Use flex for generating the scanner, add support for parsing from strings
authorKristian Høgsberg <krh@bitplanet.net>
Wed, 20 Oct 2010 01:57:59 +0000 (21:57 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Wed, 20 Oct 2010 18:03:53 +0000 (14:03 -0400)
Signed-off-by: Kristian Høgsberg <krh@bitplanet.net>
configure.ac
include/X11/extensions/XKBcommon.h
src/xkbcomp/Makefile.am
src/xkbcomp/parseutils.c
src/xkbcomp/parseutils.h
src/xkbcomp/xkbcomp.c
src/xkbcomp/xkbparse.y
src/xkbcomp/xkbscan.c [deleted file]
src/xkbcomp/xkbscan.l [new file with mode: 0644]
test/filecomp.c

index 5b1efb4..2ab311c 100644 (file)
@@ -30,6 +30,7 @@ AC_CONFIG_HEADERS([src/config.h])
 AC_PROG_LIBTOOL
 AC_PROG_CC
 AC_PROG_YACC
+AC_PROG_LEX
 
 m4_ifndef([PKG_PROG_PKG_CONFIG],
     [m4_fatal([Could not locate the pkg-config autoconf macros.
index 19adc85..6bf7d8a 100644 (file)
@@ -808,6 +808,9 @@ xkb_compile_keymap_from_components(const struct xkb_component_names * ktcsg);
 _X_EXPORT extern struct xkb_desc *
 xkb_compile_keymap_from_file(FILE *inputFile, const char *mapName);
 
+_X_EXPORT extern struct xkb_desc *
+xkb_compile_keymap_from_string(const char *string, const char *mapName);
+
 _X_EXPORT extern struct xkb_component_list *
 xkb_list_components(struct xkb_component_names * ptrns, int *maxMatch);
 
index 2923a6f..375318a 100644 (file)
@@ -38,4 +38,4 @@ libxkbcomp_la_SOURCES = \
        xkbparse.y \
        xkbpath.c \
        xkbpath.h \
-       xkbscan.c
+       xkbscan.l
index 65b66a9..c8491e7 100644 (file)
@@ -738,7 +738,7 @@ PrintStmtAddrs(ParseCommon * stmt)
 }
 #endif
 
-static void
+void
 CheckDefaultMap(XkbFile * maps)
 {
     XkbFile *dflt, *tmp;
@@ -768,27 +768,6 @@ CheckDefaultMap(XkbFile * maps)
     return;
 }
 
-int
-XKBParseFile(FILE * file, XkbFile ** pRtrn)
-{
-    if (file)
-    {
-        yyin = file;
-        rtrnValue = NULL;
-        if (yyparse() == 0)
-        {
-            *pRtrn = rtrnValue;
-            CheckDefaultMap(rtrnValue);
-            rtrnValue = NULL;
-            return 1;
-        }
-        *pRtrn = NULL;
-        return 0;
-    }
-    *pRtrn = NULL;
-    return 1;
-}
-
 XkbFile *
 CreateXKBFile(int type, char *name, ParseCommon * defs, unsigned flags)
 {
index 861ec61..6169b87 100644 (file)
@@ -177,6 +177,8 @@ extern int XKBParseFile(FILE * /* file */ ,
                         XkbFile **      /* pRtrn */
     );
 
+extern int XKBParseString(const char *string, XkbFile ** pRtrn);
+
 extern XkbFile *CreateXKBFile(int /* type */ ,
                               char * /* name */ ,
                               ParseCommon * /* defs */ ,
@@ -186,8 +188,6 @@ extern XkbFile *CreateXKBFile(int /* type */ ,
 extern void yyerror(const char *        /* s */
     );
 
-extern int yywrap(void);
-
 extern int yylex(void);
 extern int yyparse(void);
 
@@ -196,5 +196,6 @@ extern int setScanState(char * /* file */ ,
     );
 
 extern FILE *yyin;
+extern const char *yystring;
 
 #endif /* XKBPARSE_H */
index 53e6ca5..63858a0 100644 (file)
@@ -247,23 +247,12 @@ fail:
     return NULL;
 }
 
-struct xkb_desc *
-xkb_compile_keymap_from_file(FILE *inputFile, const char *mapName)
+static struct xkb_desc *
+compile_keymap(XkbFile *file, const char *mapName)
 {
-    XkbFile *file, *mapToUse;
+    XkbFile *mapToUse;
     struct xkb_desc * xkb;
 
-    if (!inputFile) {
-        ERROR("no file specified to generate XKB keymap\n");
-        goto fail;
-    }
-
-    setScanState("input", 1);
-    if (!XKBParseFile(inputFile, &file) || !file) {
-        ERROR("failed to parse input xkb file\n");
-        goto fail;
-    }
-
     /* Find map to use */
     if (!(mapToUse = XkbChooseMap(file, mapName)))
         goto unwind_file;
@@ -294,6 +283,44 @@ unwind_xkb:
     XkbcFreeKeyboard(xkb, XkbAllComponentsMask, True);
 unwind_file:
     /* XXX: here's where we would free the XkbFile */
-fail:
+
     return NULL;
 }
+
+struct xkb_desc *
+xkb_compile_keymap_from_string(const char *string, const char *mapName)
+{
+    XkbFile *file;
+
+    if (!string) {
+        ERROR("no string specified to generate XKB keymap\n");
+        return NULL;
+    }
+
+    setScanState("input", 1);
+    if (!XKBParseString(string, &file) || !file) {
+        ERROR("failed to parse input xkb file\n");
+        return NULL;
+    }
+
+    return compile_keymap(file, mapName);
+}
+
+struct xkb_desc *
+xkb_compile_keymap_from_file(FILE *inputFile, const char *mapName)
+{
+    XkbFile *file;
+
+    if (!inputFile) {
+        ERROR("no file specified to generate XKB keymap\n");
+       return NULL;
+    }
+
+    setScanState("input", 1);
+    if (!XKBParseFile(inputFile, &file) || !file) {
+        ERROR("failed to parse input xkb file\n");
+       return NULL;
+    }
+
+    return compile_keymap(file, mapName);
+}
index 713cc1d..ab21681 100644 (file)
@@ -89,6 +89,7 @@
        FUNCTION_KEYS           76
        ALTERNATE_GROUP         77
 %{
+#define DEBUG 1
 #ifdef DEBUG
 #define        YYDEBUG 1
 #endif
@@ -765,23 +766,3 @@ OptMapName :       MapName { $$= $1; }
 
 MapName                :       STRING  { $$= strdup(scanBuf); }
                ;
-%%
-void
-yyerror(const char *s)
-{
-    if (warningLevel>0) {
-       (void)fprintf(stderr,"%s: line %d of %s\n",s,lineNum,
-                                       (scanFile?scanFile:"(unknown)"));
-       if ((warningLevel>3))
-           (void)fprintf(stderr,"last scanned symbol is: %s\n",scanBuf);
-    }
-    return;
-}
-
-
-int
-yywrap(void)
-{
-   return 1;
-}
-
diff --git a/src/xkbcomp/xkbscan.c b/src/xkbcomp/xkbscan.c
deleted file mode 100644 (file)
index 4f8f9e6..0000000
+++ /dev/null
@@ -1,740 +0,0 @@
-/************************************************************
- Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
-
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
-
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
- THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- ********************************************************/
-
-#include <stdio.h>
-#include <ctype.h>
-#include <X11/Xos.h>
-
-#include "tokens.h"
-#include "utils.h"
-#include "parseutils.h"
-
-FILE *yyin = NULL;
-
-static char scanFileBuf[1024] = {0};
-char *scanFile = scanFileBuf;
-int lineNum = 0;
-
-int scanInt;
-
-char scanBuf[1024];
-static int scanStrLine = 0;
-
-#define        BUFSIZE 4096
-static char readBuf[BUFSIZE];
-static int readBufPos = 0;
-static int readBufLen = 0;
-
-#ifdef DEBUG
-extern int debugFlags;
-
-static char *
-tokText(int tok)
-{
-    static char buf[32];
-
-    switch (tok)
-    {
-    case END_OF_FILE:
-        snprintf(buf, sizeof(buf), "END_OF_FILE");
-        break;
-    case ERROR_TOK:
-        snprintf(buf, sizeof(buf), "ERROR");
-        break;
-
-    case XKB_KEYMAP:
-        snprintf(buf, sizeof(buf), "XKB_KEYMAP");
-        break;
-    case XKB_KEYCODES:
-        snprintf(buf, sizeof(buf), "XKB_KEYCODES");
-        break;
-    case XKB_TYPES:
-        snprintf(buf, sizeof(buf), "XKB_TYPES");
-        break;
-    case XKB_SYMBOLS:
-        snprintf(buf, sizeof(buf), "XKB_SYMBOLS");
-        break;
-    case XKB_COMPATMAP:
-        snprintf(buf, sizeof(buf), "XKB_COMPATMAP");
-        break;
-    case XKB_GEOMETRY:
-        snprintf(buf, sizeof(buf), "XKB_GEOMETRY");
-        break;
-    case XKB_SEMANTICS:
-        snprintf(buf, sizeof(buf), "XKB_SEMANTICS");
-        break;
-    case XKB_LAYOUT:
-        snprintf(buf, sizeof(buf), "XKB_LAYOUT");
-        break;
-
-    case INCLUDE:
-        snprintf(buf, sizeof(buf), "INCLUDE");
-        break;
-    case OVERRIDE:
-        snprintf(buf, sizeof(buf), "OVERRIDE");
-        break;
-    case AUGMENT:
-        snprintf(buf, sizeof(buf), "AUGMENT");
-        break;
-    case REPLACE:
-        snprintf(buf, sizeof(buf), "REPLACE");
-        break;
-    case ALTERNATE:
-        snprintf(buf, sizeof(buf), "ALTERNATE");
-        break;
-
-    case VIRTUAL_MODS:
-        snprintf(buf, sizeof(buf), "VIRTUAL_MODS");
-        break;
-    case TYPE:
-        snprintf(buf, sizeof(buf), "TYPE");
-        break;
-    case INTERPRET:
-        snprintf(buf, sizeof(buf), "INTERPRET");
-        break;
-    case ACTION_TOK:
-        snprintf(buf, sizeof(buf), "ACTION");
-        break;
-    case KEY:
-        snprintf(buf, sizeof(buf), "KEY");
-        break;
-    case ALIAS:
-        snprintf(buf, sizeof(buf), "ALIAS");
-        break;
-    case GROUP:
-        snprintf(buf, sizeof(buf), "GROUP");
-        break;
-    case MODIFIER_MAP:
-        snprintf(buf, sizeof(buf), "MODIFIER_MAP");
-        break;
-    case INDICATOR:
-        snprintf(buf, sizeof(buf), "INDICATOR");
-        break;
-    case SHAPE:
-        snprintf(buf, sizeof(buf), "SHAPE");
-        break;
-    case KEYS:
-        snprintf(buf, sizeof(buf), "KEYS");
-        break;
-    case ROW:
-        snprintf(buf, sizeof(buf), "ROW");
-        break;
-    case SECTION:
-        snprintf(buf, sizeof(buf), "SECTION");
-        break;
-    case OVERLAY:
-        snprintf(buf, sizeof(buf), "OVERLAY");
-        break;
-    case TEXT:
-        snprintf(buf, sizeof(buf), "TEXT");
-        break;
-    case OUTLINE:
-        snprintf(buf, sizeof(buf), "OUTLINE");
-        break;
-    case SOLID:
-        snprintf(buf, sizeof(buf), "SOLID");
-        break;
-    case LOGO:
-        snprintf(buf, sizeof(buf), "LOGO");
-        break;
-    case VIRTUAL:
-        snprintf(buf, sizeof(buf), "VIRTUAL");
-        break;
-
-    case EQUALS:
-        snprintf(buf, sizeof(buf), "EQUALS");
-        break;
-    case PLUS:
-        snprintf(buf, sizeof(buf), "PLUS");
-        break;
-    case MINUS:
-        snprintf(buf, sizeof(buf), "MINUS");
-        break;
-    case DIVIDE:
-        snprintf(buf, sizeof(buf), "DIVIDE");
-        break;
-    case TIMES:
-        snprintf(buf, sizeof(buf), "TIMES");
-        break;
-    case OBRACE:
-        snprintf(buf, sizeof(buf), "OBRACE");
-        break;
-    case CBRACE:
-        snprintf(buf, sizeof(buf), "CBRACE");
-        break;
-    case OPAREN:
-        snprintf(buf, sizeof(buf), "OPAREN");
-        break;
-    case CPAREN:
-        snprintf(buf, sizeof(buf), "CPAREN");
-        break;
-    case OBRACKET:
-        snprintf(buf, sizeof(buf), "OBRACKET");
-        break;
-    case CBRACKET:
-        snprintf(buf, sizeof(buf), "CBRACKET");
-        break;
-    case DOT:
-        snprintf(buf, sizeof(buf), "DOT");
-        break;
-    case COMMA:
-        snprintf(buf, sizeof(buf), "COMMA");
-        break;
-    case SEMI:
-        snprintf(buf, sizeof(buf), "SEMI");
-        break;
-    case EXCLAM:
-        snprintf(buf, sizeof(buf), "EXCLAM");
-        break;
-    case INVERT:
-        snprintf(buf, sizeof(buf), "INVERT");
-        break;
-
-    case STRING:
-        snprintf(buf, sizeof(buf), "STRING (%s)", scanBuf);
-        break;
-    case INTEGER:
-        snprintf(buf, sizeof(buf), "INTEGER (0x%x)", scanInt);
-        break;
-    case FLOAT:
-        snprintf(buf, sizeof(buf), "FLOAT (%d.%d)",
-                scanInt / XkbGeomPtsPerMM, scanInt % XkbGeomPtsPerMM);
-        break;
-    case IDENT:
-        snprintf(buf, sizeof(buf), "IDENT (%s)", scanBuf);
-        break;
-    case KEYNAME:
-        snprintf(buf, sizeof(buf), "KEYNAME (%s)", scanBuf);
-        break;
-
-    case PARTIAL:
-        snprintf(buf, sizeof(buf), "PARTIAL");
-        break;
-    case DEFAULT:
-        snprintf(buf, sizeof(buf), "DEFAULT");
-        break;
-    case HIDDEN:
-        snprintf(buf, sizeof(buf), "HIDDEN");
-        break;
-
-    case ALPHANUMERIC_KEYS:
-        snprintf(buf, sizeof(buf), "ALPHANUMERIC_KEYS");
-        break;
-    case MODIFIER_KEYS:
-        snprintf(buf, sizeof(buf), "MODIFIER_KEYS");
-        break;
-    case KEYPAD_KEYS:
-        snprintf(buf, sizeof(buf), "KEYPAD_KEYS");
-        break;
-    case FUNCTION_KEYS:
-        snprintf(buf, sizeof(buf), "FUNCTION_KEYS");
-        break;
-    case ALTERNATE_GROUP:
-        snprintf(buf, sizeof(buf), "ALTERNATE_GROUP");
-        break;
-
-    default:
-        snprintf(buf, sizeof(buf), "UNKNOWN");
-        break;
-    }
-    return buf;
-}
-#endif
-
-static char
-scanchar(void)
-{
-    if (readBufPos >= readBufLen) {
-        readBufLen = fread(readBuf, 1, BUFSIZE, yyin);
-        readBufPos = 0;
-        if (!readBufLen)
-            return EOF;
-        if (feof(yyin))
-            readBuf[readBufLen] = EOF;
-    }
-
-    return readBuf[readBufPos++];
-}
-
-static void
-unscanchar(char c)
-{
-    if (readBuf[--readBufPos] != c) {
-        fprintf(stderr, "UNGETCHAR FAILED! Put back %c, was expecting %c at "
-                        "position %d, buf is '%s'\n", c, readBuf[readBufPos],
-                        readBufPos, readBuf);
-        _exit(94);
-    }
-}
-
-int
-setScanState(char *file, int line)
-{
-    if (file != NULL)
-        strncpy(scanFile, file, 1024);
-    if (line >= 0)
-        lineNum = line;
-    return 1;
-}
-
-static int
-yyGetString(void)
-{
-    int ch, i;
-
-    i = 0;
-    while (((ch = scanchar()) != EOF) && (ch != '"'))
-    {
-        if (ch == '\\')
-        {
-            if ((ch = scanchar()) != EOF)
-            {
-                if (ch == 'n')
-                    ch = '\n';
-                else if (ch == 't')
-                    ch = '\t';
-                else if (ch == 'v')
-                    ch = '\v';
-                else if (ch == 'b')
-                    ch = '\b';
-                else if (ch == 'r')
-                    ch = '\r';
-                else if (ch == 'f')
-                    ch = '\f';
-                else if (ch == 'e')
-                    ch = '\033';
-                else if (ch == '0')
-                {
-                    int tmp, stop;
-                    ch = stop = 0;
-                    if (((tmp = scanchar()) != EOF) && (isdigit(tmp))
-                        && (tmp != '8') && (tmp != '9'))
-                    {
-                        ch = (ch * 8) + (tmp - '0');
-                    }
-                    else
-                    {
-                        stop = 1;
-                        unscanchar(tmp);
-                    }
-                    if (!stop)
-                    {
-                        if (((tmp = scanchar()) != EOF)
-                            && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
-                        {
-                            ch = (ch * 8) + (tmp - '0');
-                        }
-                        else
-                        {
-                            stop = 1;
-                            unscanchar(tmp);
-                        }
-                    }
-                    if (!stop)
-                    {
-                        if (((tmp = scanchar()) != EOF)
-                            && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
-                        {
-                            ch = (ch * 8) + (tmp - '0');
-                        }
-                        else
-                        {
-                            stop = 1;
-                            unscanchar(tmp);
-                        }
-                    }
-                }
-            }
-            else
-                return ERROR_TOK;
-        }
-        if (i < sizeof(scanBuf) - 1)
-            scanBuf[i++] = ch;
-    }
-    if (ch == '"')
-    {
-        scanBuf[i++] = '\0';
-        scanStrLine = lineNum;
-        return STRING;
-    }
-    return ERROR_TOK;
-}
-
-static int
-yyGetKeyName(void)
-{
-    int ch, i;
-
-    i = 0;
-    while (((ch = scanchar()) != EOF) && (ch != '>'))
-    {
-        if (ch == '\\')
-        {
-            if ((ch = scanchar()) != EOF)
-            {
-                if (ch == 'n')
-                    ch = '\n';
-                else if (ch == 't')
-                    ch = '\t';
-                else if (ch == 'v')
-                    ch = '\v';
-                else if (ch == 'b')
-                    ch = '\b';
-                else if (ch == 'r')
-                    ch = '\r';
-                else if (ch == 'f')
-                    ch = '\f';
-                else if (ch == 'e')
-                    ch = '\033';
-                else if (ch == '0')
-                {
-                    int tmp, stop;
-                    ch = stop = 0;
-                    if (((tmp = scanchar()) != EOF) && (isdigit(tmp))
-                        && (tmp != '8') && (tmp != '9'))
-                    {
-                        ch = (ch * 8) + (tmp - '0');
-                    }
-                    else
-                    {
-                        stop = 1;
-                        unscanchar(tmp);
-                    }
-                    if ((!stop) && ((tmp = scanchar()) != EOF)
-                        && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
-                    {
-                        ch = (ch * 8) + (tmp - '0');
-                    }
-                    else
-                    {
-                        stop = 1;
-                        unscanchar(tmp);
-                    }
-                    if ((!stop) && ((tmp = scanchar()) != EOF)
-                        && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
-                    {
-                        ch = (ch * 8) + (tmp - '0');
-                    }
-                    else
-                    {
-                        stop = 1;
-                        unscanchar(tmp);
-                    }
-                }
-            }
-            else
-                return ERROR_TOK;
-        }
-
-        if (i < sizeof(scanBuf) - 1)
-            scanBuf[i++] = ch;
-    }
-    if ((ch == '>') && (i < 5))
-    {
-        scanBuf[i++] = '\0';
-        scanStrLine = lineNum;
-        return KEYNAME;
-    }
-    return ERROR_TOK;
-}
-
-static struct _Keyword
-{
-    const char *keyword;
-    int token;
-} keywords[] =
-{
-    {
-    "xkb_keymap", XKB_KEYMAP},
-    {
-    "xkb_keycodes", XKB_KEYCODES},
-    {
-    "xkb_types", XKB_TYPES},
-    {
-    "xkb_symbols", XKB_SYMBOLS},
-    {
-    "xkb_compat", XKB_COMPATMAP},
-    {
-    "xkb_compat_map", XKB_COMPATMAP},
-    {
-    "xkb_compatibility", XKB_COMPATMAP},
-    {
-    "xkb_compatibility_map", XKB_COMPATMAP},
-    {
-    "xkb_geometry", XKB_GEOMETRY},
-    {
-    "xkb_semantics", XKB_SEMANTICS},
-    {
-    "xkb_layout", XKB_LAYOUT},
-    {
-    "include", INCLUDE},
-    {
-    "override", OVERRIDE},
-    {
-    "augment", AUGMENT},
-    {
-    "replace", REPLACE},
-    {
-    "alternate", ALTERNATE},
-    {
-    "partial", PARTIAL},
-    {
-    "default", DEFAULT},
-    {
-    "hidden", HIDDEN},
-    {
-    "virtual_modifiers", VIRTUAL_MODS},
-    {
-    "type", TYPE},
-    {
-    "interpret", INTERPRET},
-    {
-    "action", ACTION_TOK},
-    {
-    "key", KEY},
-    {
-    "alias", ALIAS},
-    {
-    "group", GROUP},
-    {
-    "modmap", MODIFIER_MAP},
-    {
-    "mod_map", MODIFIER_MAP},
-    {
-    "modifier_map", MODIFIER_MAP},
-    {
-    "indicator", INDICATOR},
-    {
-    "shape", SHAPE},
-    {
-    "row", ROW},
-    {
-    "keys", KEYS},
-    {
-    "section", SECTION},
-    {
-    "overlay", OVERLAY},
-    {
-    "text", TEXT},
-    {
-    "outline", OUTLINE},
-    {
-    "solid", SOLID},
-    {
-    "logo", LOGO},
-    {
-    "virtual", VIRTUAL},
-    {
-    "alphanumeric_keys", ALPHANUMERIC_KEYS},
-    {
-    "modifier_keys", MODIFIER_KEYS},
-    {
-    "keypad_keys", KEYPAD_KEYS},
-    {
-    "function_keys", FUNCTION_KEYS},
-    {
-    "alternate_group", ALTERNATE_GROUP}
-};
-static int numKeywords = sizeof(keywords) / sizeof(struct _Keyword);
-
-static int
-yyGetIdent(int first)
-{
-    int ch, i, j, found;
-    int rtrn = IDENT;
-
-    scanBuf[0] = first;
-    j = 1;
-    while (((ch = scanchar()) != EOF) && (isalnum(ch) || (ch == '_')))
-    {
-        if (j < sizeof(scanBuf) - 1)
-            scanBuf[j++] = ch;
-    }
-    scanBuf[j++] = '\0';
-    found = 0;
-
-    for (i = 0; (!found) && (i < numKeywords); i++)
-    {
-        if (uStrCaseCmp(scanBuf, keywords[i].keyword) == 0)
-        {
-            rtrn = keywords[i].token;
-            found = 1;
-        }
-    }
-    if (!found)
-    {
-        scanStrLine = lineNum;
-        rtrn = IDENT;
-    }
-
-    if ((ch != EOF) && (!isspace(ch)))
-        unscanchar(ch);
-    else if (ch == '\n')
-        lineNum++;
-
-    return rtrn;
-}
-
-static int
-yyGetNumber(int ch)
-{
-    int isFloat = 0;
-    char buf[1024];
-    int nInBuf = 0;
-
-    buf[0] = ch;
-    nInBuf = 1;
-    while (((ch = scanchar()) != EOF)
-           && (isxdigit(ch) || ((nInBuf == 1) && (ch == 'x'))))
-    {
-        buf[nInBuf++] = ch;
-    }
-    if (ch == '.')
-    {
-        isFloat = 1;
-        buf[nInBuf++] = ch;
-        while (((ch = scanchar()) != EOF) && (isxdigit(ch)))
-        {
-            buf[nInBuf++] = ch;
-        }
-    }
-    buf[nInBuf++] = '\0';
-    if ((ch != EOF) && (!isspace(ch)))
-        unscanchar(ch);
-
-    if (isFloat)
-    {
-        float tmp;
-        if (sscanf(buf, "%g", &tmp) == 1)
-        {
-            scanInt = tmp * XkbGeomPtsPerMM;
-            return FLOAT;
-        }
-    }
-    else if (sscanf(buf, "%i", &scanInt) == 1)
-        return INTEGER;
-    fprintf(stderr, "Malformed number %s\n", buf);
-    return ERROR_TOK;
-}
-
-int
-yylex(void)
-{
-    int ch;
-    int rtrn;
-
-    do
-    {
-        ch = scanchar();
-        if (ch == '\n')
-        {
-            lineNum++;
-        }
-        else if (ch == '#')
-        {                       /* handle shell style '#' comments */
-            do
-            {
-                ch = scanchar();
-            }
-            while ((ch != '\n') && (ch != EOF));
-            lineNum++;
-        }
-        else if (ch == '/')
-        {                       /* handle C++ style double-/ comments */
-            int newch = scanchar();
-            if (newch == '/')
-            {
-                do
-                {
-                    ch = scanchar();
-                }
-                while ((ch != '\n') && (ch != EOF));
-                lineNum++;
-            }
-            else if (newch != EOF)
-            {
-                unscanchar(newch);
-            }
-        }
-    }
-    while ((ch != EOF) && (isspace(ch)));
-    if (ch == '=')
-        rtrn = EQUALS;
-    else if (ch == '+')
-        rtrn = PLUS;
-    else if (ch == '-')
-        rtrn = MINUS;
-    else if (ch == '/')
-        rtrn = DIVIDE;
-    else if (ch == '*')
-        rtrn = TIMES;
-    else if (ch == '{')
-        rtrn = OBRACE;
-    else if (ch == '}')
-        rtrn = CBRACE;
-    else if (ch == '(')
-        rtrn = OPAREN;
-    else if (ch == ')')
-        rtrn = CPAREN;
-    else if (ch == '[')
-        rtrn = OBRACKET;
-    else if (ch == ']')
-        rtrn = CBRACKET;
-    else if (ch == '.')
-        rtrn = DOT;
-    else if (ch == ',')
-        rtrn = COMMA;
-    else if (ch == ';')
-        rtrn = SEMI;
-    else if (ch == '!')
-        rtrn = EXCLAM;
-    else if (ch == '~')
-        rtrn = INVERT;
-    else if (ch == '"')
-        rtrn = yyGetString();
-    else if (ch == '<')
-        rtrn = yyGetKeyName();
-    else if (isalpha(ch) || (ch == '_'))
-        rtrn = yyGetIdent(ch);
-    else if (isdigit(ch))
-        rtrn = yyGetNumber(ch);
-    else if (ch == EOF)
-        rtrn = END_OF_FILE;
-    else
-    {
-#ifdef DEBUG
-        if (debugFlags)
-            fprintf(stderr,
-                    "Unexpected character %c (%d) in input stream\n", ch, ch);
-#endif
-        rtrn = ERROR_TOK;
-    }
-#ifdef DEBUG
-    if (debugFlags & 0x2)
-        fprintf(stderr, "scan: %s\n", tokText(rtrn));
-#endif
-    return rtrn;
-}
diff --git a/src/xkbcomp/xkbscan.l b/src/xkbcomp/xkbscan.l
new file mode 100644 (file)
index 0000000..0d3cab6
--- /dev/null
@@ -0,0 +1,245 @@
+/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting
+ documentation, and that the name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+ THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ********************************************************/
+
+%{
+
+#include <stdio.h>
+#include <ctype.h>
+#include <X11/Xos.h>
+
+#include "tokens.h"
+#include "utils.h"
+#include "parseutils.h"
+
+const char *yystring;
+static char scanFileBuf[1024] = {0};
+char *scanFile = scanFileBuf;
+int lineNum = 0;
+
+int scanInt;
+
+static char *s;
+char scanBuf[1024];
+
+#define        BUFSIZE 4096
+
+%}
+
+%option case-insensitive
+%option yylineno
+%option noyywrap
+
+%x S_STR S_KEY
+
+%%
+
+"//"[^\n]*
+"#"[^\n]*
+
+\"                     s = scanBuf; BEGIN(S_STR);
+\<                     s = scanBuf; BEGIN(S_KEY);
+
+<S_STR>\"              BEGIN(INITIAL); *s = '\0'; return STRING;
+<S_KEY>\>              BEGIN(INITIAL); *s = '\0'; return KEYNAME;
+
+<S_STR,S_KEY>\\[0-7]{1,3} {
+                       /* octal escape sequence */
+                       int result;
+
+                       (void) sscanf( yytext + 1, "%o", &result );
+
+                       if (result > 0xff) {
+                           fprintf(stderr, "Illegal octal escape %s\n", yytext);
+                           return ERROR_TOK;
+                       }
+
+                       *s++ = result;
+                   }
+
+<S_STR,S_KEY>\\[0-9]+ {
+                       fprintf(stderr, "Illegal octal escape %s\n", yytext);
+                       return ERROR_TOK;
+                   }
+
+<S_STR,S_KEY>\\n       *s++ = '\n';
+<S_STR,S_KEY>\\t       *s++ = '\t';
+<S_STR,S_KEY>\\r       *s++ = '\r';
+<S_STR,S_KEY>\\b       *s++ = '\b';
+<S_STR,S_KEY>\\f       *s++ = '\f';
+<S_STR,S_KEY>\\v       *s++ = '\v';
+<S_STR,S_KEY>\\e       *s++ = '\033';
+
+<S_STR,S_KEY>.         *s++ = yytext[0];
+
+xkb_keymap             return XKB_KEYMAP;
+xkb_keycodes           return XKB_KEYCODES;
+xkb_types              return XKB_TYPES;
+xkb_symbols            return XKB_SYMBOLS;
+xkb_compat             return XKB_COMPATMAP;
+xkb_compat_map         return XKB_COMPATMAP;
+xkb_compatibility      return XKB_COMPATMAP;
+xkb_compatibility_map  return XKB_COMPATMAP;
+xkb_geometry           return XKB_GEOMETRY;
+xkb_semantics          return XKB_SEMANTICS;
+xkb_layout             return XKB_LAYOUT;
+include                        return INCLUDE;
+override               return OVERRIDE;
+augment                        return AUGMENT;
+replace                        return REPLACE;
+alternate              return ALTERNATE;
+partial                        return PARTIAL;
+default                        return DEFAULT;
+hidden                 return HIDDEN;
+virtual_modifiers      return VIRTUAL_MODS;
+type                   return TYPE;
+interpret              return INTERPRET;
+action                 return ACTION_TOK;
+key                    return KEY;
+alias                  return ALIAS;
+group                  return GROUP;
+modmap                 return MODIFIER_MAP;
+mod_map                        return MODIFIER_MAP;
+modifier_map           return MODIFIER_MAP;
+indicator              return INDICATOR;
+shape                  return SHAPE;
+row                    return ROW;
+keys                   return KEYS;
+section                        return SECTION;
+overlay                        return OVERLAY;
+text                   return TEXT;
+outline                        return OUTLINE;
+solid                  return SOLID;
+logo                   return LOGO;
+virtual                        return VIRTUAL;
+alphanumeric_keys      return ALPHANUMERIC_KEYS;
+modifier_keys          return MODIFIER_KEYS;
+keypad_keys            return KEYPAD_KEYS;
+function_keys          return FUNCTION_KEYS;
+alternate_group                return ALTERNATE_GROUP;
+
+[a-zA-Z_][a-zA-Z_0-9]* memcpy(scanBuf, yytext, yyleng + 1); return IDENT;
+
+0x[a-fA-F0-9]+         |
+[0-9]+                 {
+                           char *end;
+                           scanInt = strtol(yytext, &end, 0);
+
+                           return INTEGER;
+                       }
+[0-9]+\.[0-9]+ {
+                           char *end;
+                           scanInt = strtod(yytext, &end) * XkbGeomPtsPerMM;
+
+                           return FLOAT;
+                       }
+
+"="                    return EQUALS;
+"+"                    return PLUS;
+"-"                    return MINUS;
+"/"                    return DIVIDE;
+"*"                    return TIMES;
+"{"                    return OBRACE;
+"}"                    return CBRACE;
+"("                    return OPAREN;
+")"                    return CPAREN;
+"["                    return OBRACKET;
+"]"                    return CBRACKET;
+"."                    return DOT;
+","                    return COMMA;
+";"                    return SEMI;
+"!"                    return EXCLAM;
+"~"                    return INVERT;
+
+[ \t\r\n\v]+           
+
+<<EOF>>                        return END_OF_FILE;
+
+.                      return ERROR_TOK;
+
+%%
+
+void
+yyerror(const char *s)
+{
+    if (warningLevel>0) {
+       (void)fprintf(stderr,"%s: line %d of %s\n",s,yylineno,
+                                       (scanFile?scanFile:"(unknown)"));
+       if ((warningLevel>3))
+           (void)fprintf(stderr,"last scanned symbol is: %s\n",scanBuf);
+    }
+    return;
+}
+
+int setScanState(char *file, int lineno)
+{
+  yylineno = 1;
+  scanFile = file;
+}
+
+int
+XKBParseString(const char *string, XkbFile ** pRtrn)
+{
+    YY_BUFFER_STATE state;
+
+    *pRtrn = NULL;
+    if (string == NULL)
+       return 1;
+
+    state = yy_scan_string(string);
+    rtrnValue = NULL;
+    if (yyparse() != 0)
+       return 0;
+
+    yy_delete_buffer(state);
+    yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+    *pRtrn = rtrnValue;
+    CheckDefaultMap(rtrnValue);
+    rtrnValue = NULL;
+
+    return 1;
+}
+
+int
+XKBParseFile(FILE * file, XkbFile ** pRtrn)
+{
+    if (file)
+    {
+        yyin = file;
+       yystring = NULL;
+        rtrnValue = NULL;
+        if (yyparse() == 0)
+        {
+            *pRtrn = rtrnValue;
+            CheckDefaultMap(rtrnValue);
+            rtrnValue = NULL;
+            return 1;
+        }
+        *pRtrn = NULL;
+        return 0;
+    }
+    *pRtrn = NULL;
+    return 1;
+}
index 0ff41f9..d256d72 100644 (file)
@@ -33,22 +33,31 @@ authorization from the authors.
 #include "X11/extensions/XKBcommon.h"
 #include "xkbcomp/utils.h"
 
+static char buffer[8192];
+
 int main(int argc, char *argv[])
 {
     char *path, *name;
     FILE *file;
     struct xkb_desc * xkb;
+    int i, len, from_string = 0;
 
     /* Require xkb file */
     if (argc < 2) {
         fprintf(stderr, "Not enough arguments\n");
-        fprintf(stderr, "Usage: %s XKBFILE [NAME]\n",
+        fprintf(stderr, "Usage: %s [-s] XKBFILE [NAME]\n",
                 argv[0]);
         exit(1);
     }
 
-    path = argv[1];
-    name = (argc > 2) ? argv[2] : NULL;
+    i = 1;
+    if (strcmp(argv[1], "-s") == 0) {
+       from_string = 2;
+       i++;
+    }
+
+    path = argv[i];
+    name = (argc > i + 1) ? argv[i + 1] : NULL;
 
     file = fopen(path, "r");
     if (!file) {
@@ -57,7 +66,13 @@ int main(int argc, char *argv[])
         exit(1);
     }
 
-    xkb = xkb_compile_keymap_from_file(file, name);
+    if (from_string) {
+       len = fread(buffer, 1, sizeof buffer, file);
+       buffer[len] = '\0';
+       xkb = xkb_compile_keymap_from_string(buffer, name);
+    } else {
+       xkb = xkb_compile_keymap_from_file(file, name);
+    }
     fclose(file);
 
     if (!xkb) {