[PATCH libxkbcommon 2/2] Make parser and scanner reentrant

Ran Benita ran234 at gmail.com
Thu Feb 23 16:58:34 PST 2012


All global state is removed from the parser and scanner.
This makes use of the standard facilities in Bison and Flex for
reentrant/pure scanner/lexer and location tracking.

Signed-off-by: Ran Benita <ran234 at gmail.com>
---
 src/xkbcomp/compat.c     |    3 +-
 src/xkbcomp/keytypes.c   |    3 +-
 src/xkbcomp/listing.c    |    3 +-
 src/xkbcomp/misc.c       |   12 +---
 src/xkbcomp/parseutils.c |    8 +--
 src/xkbcomp/parseutils.h |   38 ++++++------
 src/xkbcomp/xkbcomp.c    |    6 +-
 src/xkbcomp/xkbcomp.h    |    2 -
 src/xkbcomp/xkbparse.y   |   97 +++++++++++++++++------------
 src/xkbcomp/xkbscan.l    |  155 +++++++++++++++++++++++++---------------------
 10 files changed, 171 insertions(+), 156 deletions(-)

diff --git a/src/xkbcomp/compat.c b/src/xkbcomp/compat.c
index 9b268e6..620e8ff 100644
--- a/src/xkbcomp/compat.c
+++ b/src/xkbcomp/compat.c
@@ -820,8 +820,7 @@ CompileCompatMap(XkbFile *file, struct xkb_desc * xkb, unsigned merge,
 	    else
             {
                 WSGO("Couldn't allocate space for compat name\n");
-                ACTION("Name \"%s\" (from %s) NOT assigned\n",
-                        scanFile, info.name);
+                ACTION("Name \"%s\" NOT assigned\n", info.name);
             }
         }
         size = info.nInterps * sizeof(struct xkb_sym_interpret);
diff --git a/src/xkbcomp/keytypes.c b/src/xkbcomp/keytypes.c
index 71f6075..3e2e91e 100644
--- a/src/xkbcomp/keytypes.c
+++ b/src/xkbcomp/keytypes.c
@@ -1189,8 +1189,7 @@ CompileKeyTypes(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
             else
             {
                 WSGO("Couldn't allocate space for types name\n");
-                ACTION("Name \"%s\" (from %s) NOT assigned\n",
-                        scanFile, info.name);
+                ACTION("Name \"%s\" NOT assigned\n", info.name);
             }
         }
         i = info.nTypes;
diff --git a/src/xkbcomp/listing.c b/src/xkbcomp/listing.c
index dbedca6..a3ff89e 100644
--- a/src/xkbcomp/listing.c
+++ b/src/xkbcomp/listing.c
@@ -235,8 +235,7 @@ ParseComponents(CompPair *cp, char *path, char *map, int *max, unsigned strip)
         return 0;
     }
 
-    setScanState(path, 1);
-    if (!XKBParseFile(inputFile, &rtrn) || !rtrn) {
+    if (!XKBParseFile(inputFile, path, &rtrn) || !rtrn) {
         if (oldWarningLevel > 5)
             WARN("Couldn't parse file \"%s\"\n", path);
         fclose(inputFile);
diff --git a/src/xkbcomp/misc.c b/src/xkbcomp/misc.c
index 35f947c..ed98b9f 100644
--- a/src/xkbcomp/misc.c
+++ b/src/xkbcomp/misc.c
@@ -54,8 +54,6 @@ ProcessIncludeFile(IncludeStmt * stmt,
 {
     FILE *file;
     XkbFile *rtrn, *mapToUse;
-    char oldFile[1024] = {0};
-    int oldLine = lineNum;
 
     rtrn = XkbFindFileInCache(stmt->file, file_type, &stmt->path);
     if (rtrn == NULL)
@@ -69,18 +67,11 @@ ProcessIncludeFile(IncludeStmt * stmt,
                    XkbDirectoryForInclude(file_type));
             return False;
         }
-        if (scanFile)
-            strcpy(oldFile, scanFile);
-        else
-            memset(oldFile, 0, sizeof(oldFile));
-        oldLine = lineNum;
-        setScanState(stmt->file, 1);
         if (debugFlags & 2)
             INFO("About to parse include file %s\n", stmt->file);
         /* parse the file */
-        if ((XKBParseFile(file, &rtrn) == 0) || (rtrn == NULL))
+        if ((XKBParseFile(file, stmt->file, &rtrn) == 0) || (rtrn == NULL))
         {
-            setScanState(oldFile, oldLine);
             ERROR("Error interpreting include file \"%s\"\n", stmt->file);
             fclose(file);
             return False;
@@ -109,7 +100,6 @@ ProcessIncludeFile(IncludeStmt * stmt,
               stmt->file);
         ACTION("Using first defined map, \"%s\"\n", rtrn->name);
     }
-    setScanState(oldFile, oldLine);
     if (mapToUse->type != file_type)
     {
         ERROR("Include file wrong type (expected %s, got %s)\n",
diff --git a/src/xkbcomp/parseutils.c b/src/xkbcomp/parseutils.c
index 65de324..099863b 100644
--- a/src/xkbcomp/parseutils.c
+++ b/src/xkbcomp/parseutils.c
@@ -739,7 +739,7 @@ PrintStmtAddrs(ParseCommon * stmt)
 #endif
 
 void
-CheckDefaultMap(XkbFile * maps)
+CheckDefaultMap(XkbFile * maps, const char *fileName)
 {
     XkbFile *dflt, *tmp;
 
@@ -756,7 +756,7 @@ CheckDefaultMap(XkbFile * maps)
                 if (warningLevel > 2)
                 {
                     WARN("Multiple default components in %s\n",
-                          (scanFile ? scanFile : "(unknown)"));
+                          (fileName ? fileName : "(unknown)"));
                     ACTION("Using %s, ignoring %s\n",
                             (dflt->name ? dflt->name : "(first)"),
                             (tmp->name ? tmp->name : "(subsequent)"));
@@ -791,11 +791,11 @@ CreateXKBFile(int type, char *name, ParseCommon * defs, unsigned flags)
 }
 
 unsigned
-StmtSetMerge(ParseCommon * stmt, unsigned merge)
+StmtSetMerge(ParseCommon * stmt, unsigned merge, YYLTYPE *loc, void *scanner)
 {
     if ((merge == MergeAltForm) && (stmt->stmtType != StmtKeycodeDef))
     {
-        yyerror("illegal use of 'alternate' merge mode");
+        yyerror(loc, scanner, "illegal use of 'alternate' merge mode");
         merge = MergeDefault;
     }
     return merge;
diff --git a/src/xkbcomp/parseutils.h b/src/xkbcomp/parseutils.h
index 64d01e0..d2a92a5 100644
--- a/src/xkbcomp/parseutils.h
+++ b/src/xkbcomp/parseutils.h
@@ -28,13 +28,7 @@
 #define	XKBPARSE_H 1
 
 #include "xkbcomp.h"
-
-extern char scanBuf[1024];
-extern int scanInt;
-extern unsigned long scanULong;
-extern int lineNum;
-
-extern XkbFile *rtrnValue;
+#include "xkbparse.h"
 
 #ifdef DEBUG
 #define	d(str)		fprintf(stderr,"%s\n",str);
@@ -166,7 +160,9 @@ extern IncludeStmt *IncludeCreate(char * /* str */ ,
     );
 
 extern unsigned StmtSetMerge(ParseCommon * /* stmt */ ,
-                             unsigned   /* merge */
+                             unsigned   /* merge */,
+                             YYLTYPE *  /* loc */,
+                             void *     /* scanner */
     );
 
 #ifdef DEBUG
@@ -175,12 +171,14 @@ extern void PrintStmtAddrs(ParseCommon *        /* stmt */
 #endif
 
 extern int XKBParseFile(FILE * /* file */ ,
+                        const char *    /* fileName */,
                         XkbFile **      /* pRtrn */
     );
 
-extern int XKBParseString(const char *string, XkbFile ** pRtrn);
+extern int XKBParseString(const char *string, const char *fileName,
+                          XkbFile ** pRtrn);
 
-extern void CheckDefaultMap(XkbFile * maps);
+extern void CheckDefaultMap(XkbFile * maps, const char *fileName);
 
 extern XkbFile *CreateXKBFile(int /* type */ ,
                               char * /* name */ ,
@@ -188,16 +186,18 @@ extern XkbFile *CreateXKBFile(int /* type */ ,
                               unsigned  /* flags */
     );
 
-extern void yyerror(const char *        /* s */
-    );
+struct parser_param {
+        void *scanner;
+        XkbFile *rtrn;
+};
 
-extern int yylex(void);
-extern int yyparse(void);
-
-extern void setScanState(char * /* file */ ,
-                         int     /* line */
-    );
+struct scanner_extra {
+        char *scanFile;
+        /* FIXME: This can overflow. */
+        char scanBuf[1024];
+        char *s;
+};
 
-extern const char *yystring;
+extern void yyerror(struct YYLTYPE *loc, void *scanner, const char *msg);
 
 #endif /* XKBPARSE_H */
diff --git a/src/xkbcomp/xkbcomp.c b/src/xkbcomp/xkbcomp.c
index cc3b52d..8f74c3b 100644
--- a/src/xkbcomp/xkbcomp.c
+++ b/src/xkbcomp/xkbcomp.c
@@ -297,8 +297,7 @@ xkb_compile_keymap_from_string(const char *string, const char *mapName)
         return NULL;
     }
 
-    setScanState("input", 1);
-    if (!XKBParseString(string, &file) || !file) {
+    if (!XKBParseString(string, "input", &file) || !file) {
         ERROR("failed to parse input xkb file\n");
         return NULL;
     }
@@ -316,8 +315,7 @@ xkb_compile_keymap_from_file(FILE *inputFile, const char *mapName)
 	return NULL;
     }
 
-    setScanState("input", 1);
-    if (!XKBParseFile(inputFile, &file) || !file) {
+    if (!XKBParseFile(inputFile, "input", &file) || !file) {
         ERROR("failed to parse input xkb file\n");
 	return NULL;
     }
diff --git a/src/xkbcomp/xkbcomp.h b/src/xkbcomp/xkbcomp.h
index 502b0ba..d2d69c6 100644
--- a/src/xkbcomp/xkbcomp.h
+++ b/src/xkbcomp/xkbcomp.h
@@ -39,8 +39,6 @@
 #include "xkbcommon/xkbcommon.h"
 #include "XKBcommonint.h"
 
-extern char *scanFile;
-
 #define	TypeUnknown	0
 #define	TypeBoolean	1
 #define	TypeInt		2
diff --git a/src/xkbcomp/xkbparse.y b/src/xkbcomp/xkbparse.y
index 60c445b..a369039 100644
--- a/src/xkbcomp/xkbparse.y
+++ b/src/xkbcomp/xkbparse.y
@@ -24,6 +24,26 @@
 
  ********************************************************/
 
+%{
+#define DEBUG 1
+#ifdef DEBUG
+#define	YYDEBUG 1
+#endif
+#include "parseutils.h"
+#include "xkbmisc.h"
+#include <X11/keysym.h>
+#include <stdlib.h>
+
+extern int yylex(union YYSTYPE *val, struct YYLTYPE *loc, void *scanner);
+
+#define scanner param->scanner
+%}
+
+%define		api.pure
+%locations
+%lex-param	{ void *scanner }
+%parse-param	{ struct parser_param *param }
+
 %token
 	END_OF_FILE	0
 	ERROR_TOK	255
@@ -88,17 +108,7 @@
 	KEYPAD_KEYS		75
 	FUNCTION_KEYS		76
 	ALTERNATE_GROUP		77
-%{
-#define DEBUG 1
-#ifdef DEBUG
-#define	YYDEBUG 1
-#endif
-#include "parseutils.h"
-#include "xkbmisc.h"
-#include <X11/keysym.h>
-#include <stdlib.h>
 
-%}
 %right	EQUALS
 %left	PLUS MINUS
 %left	TIMES DIVIDE
@@ -108,6 +118,7 @@
 %union	{
 	int		 ival;
 	unsigned	 uval;
+	int64_t		 num;
 	char		*str;
 	Atom	 	sval;
 	ParseCommon	*any;
@@ -133,6 +144,8 @@
 	DoodadDef	*doodad;
 	XkbFile		*file;
 }
+%type <num>	INTEGER FLOAT
+%type <str>	IDENT KEYNAME STRING
 %type <ival>	Number Integer Float SignedNumber
 %type <uval>	XkbCompositeType FileType MergeMode OptMergeMode
 %type <uval>	DoodadType Flag Flags OptFlags KeyCode
@@ -164,11 +177,11 @@
 %type <file>	XkbCompositeMap XkbCompMapList
 %%
 XkbFile		:	XkbCompMapList
-			{ $$= rtrnValue= $1; }
+			{ $$= param->rtrn= $1; }
 		|	XkbMapConfigList
-			{ $$= rtrnValue= $1;  }
+			{ $$= param->rtrn= $1;  }
 		|	XkbConfig
-			{ $$= rtrnValue= $1; }
+			{ $$= param->rtrn= $1; }
 		;
 
 XkbCompMapList	:	XkbCompMapList XkbCompositeMap
@@ -237,82 +250,82 @@ DeclList	:	DeclList Decl
 
 Decl		:	OptMergeMode VarDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode VModDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode InterpretDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode KeyNameDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode KeyAliasDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode KeyTypeDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode SymbolsDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode ModMapDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode GroupCompatDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode IndicatorMapDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode IndicatorNameDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode ShapeDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode SectionDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	OptMergeMode DoodadDecl
 			{
-			    $2->merge= StmtSetMerge(&$2->common,$1);
+			    $2->merge= StmtSetMerge(&$2->common,$1,&@1,scanner);
 			    $$= &$2->common;
 			}
 		|	MergeMode STRING
 			{
 			    if ($1==MergeAltForm) {
-				yyerror("cannot use 'alternate' to include other maps");
-				$$= &IncludeCreate(scanBuf,MergeDefault)->common;
+				yyerror(&@1, scanner, "cannot use 'alternate' to include other maps");
+				$$= &IncludeCreate($2,MergeDefault)->common;
 			    }
 			    else {
-				$$= &IncludeCreate(scanBuf,$1)->common;
+				$$= &IncludeCreate($2,$1)->common;
 			    }
                         }
 		;
@@ -719,7 +732,7 @@ KeySymList	:	KeySymList COMMA KeySym
 			{ $$= CreateKeysymList($1); }
 		;
 
-KeySym		:	IDENT	{ $$= strdup(scanBuf); }
+KeySym		:	IDENT	{ $$= $1; }
 		|	SECTION	{ $$= strdup("section"); }
 		|	Integer		
 			{
@@ -739,32 +752,36 @@ SignedNumber	:	MINUS Number    { $$= -$2; }
 		|	Number              { $$= $1; }
 		;
 
-Number		:	FLOAT		{ $$= scanInt; }
-		|	INTEGER		{ $$= scanInt*XkbGeomPtsPerMM; }
+Number		:	FLOAT		{ $$= $1; }
+		|	INTEGER		{ $$= $1*XkbGeomPtsPerMM; }
 		;
 
-Float		:	FLOAT		{ $$= scanInt; }
+Float		:	FLOAT		{ $$= $1; }
 		;
 
-Integer		:	INTEGER		{ $$= scanInt; }
+Integer		:	INTEGER		{ $$= $1; }
 		;
 
-KeyCode         :       INTEGER         { $$= scanULong; }
+KeyCode         :       INTEGER         { $$= $1; }
                 ;
 
-KeyName		:	KEYNAME		{ $$= strdup(scanBuf); }
+KeyName		:	KEYNAME		{ $$= $1; }
 		;
 
-Ident		:	IDENT	{ $$= xkb_intern_atom(scanBuf); }
+Ident		:	IDENT	{ $$= xkb_intern_atom($1); free($1); }
 		|	DEFAULT { $$= xkb_intern_atom("default"); }
 		;
 
-String		:	STRING	{ $$= xkb_intern_atom(scanBuf); }
+String		:	STRING	{ $$= xkb_intern_atom($1); free($1); }
 		;
 
 OptMapName	:	MapName	{ $$= $1; }
 		|		{ $$= NULL; }
 		;
 
-MapName		:	STRING 	{ $$= strdup(scanBuf); }
+MapName		:	STRING 	{ $$= $1; }
 		;
+
+%%
+
+#undef scanner
diff --git a/src/xkbcomp/xkbscan.l b/src/xkbcomp/xkbscan.l
index 3c98131..dfa6e50 100644
--- a/src/xkbcomp/xkbscan.l
+++ b/src/xkbcomp/xkbscan.l
@@ -31,26 +31,26 @@
 #include <X11/Xos.h>
 
 #include "parseutils.h"
-#include "xkbparse.h"
 #include "utils.h"
 
-const char *yystring;
-char *scanFile = NULL;
-int lineNum = 0;
+extern int yyparse(struct parser_param *param);
 
-int scanInt;
-unsigned long scanULong;
-
-static char *s;
-char scanBuf[1024];
-
-#define	BUFSIZE	4096
+#define YY_USER_ACTION {		\
+	yylloc->first_line = yylineno;	\
+	yylloc->last_line = yylineno;	\
+}
 
 %}
 
+%option reentrant
+%option extra-type="struct scanner_extra *"
+%option bison-bridge bison-locations
+%option never-interactive nounistd
 %option case-insensitive
 %option yylineno
 %option noyywrap
+%option warn
+%option noinput nounput
 
 %x S_STR S_KEY
 
@@ -59,11 +59,21 @@ char scanBuf[1024];
 "//"[^\n]*
 "#"[^\n]*
 
-\"			s = scanBuf; BEGIN(S_STR);
-\<			s = scanBuf; BEGIN(S_KEY);
+\"			yyextra->s = yyextra->scanBuf; BEGIN(S_STR);
+\<			yyextra->s = yyextra->scanBuf; BEGIN(S_KEY);
 
-<S_STR>\"		BEGIN(INITIAL); *s = '\0'; return STRING;
-<S_KEY>\>		BEGIN(INITIAL); *s = '\0'; return KEYNAME;
+<S_STR>\" {
+			BEGIN(INITIAL);
+			*yyextra->s = '\0';
+			yylval->str = strdup(yyextra->scanBuf);
+			return STRING;
+		    }
+<S_KEY>\> {
+			BEGIN(INITIAL);
+			*yyextra->s = '\0';
+			yylval->str = strdup(yyextra->scanBuf);
+			return KEYNAME;
+		    }
 
 <S_STR,S_KEY>\\[0-7]{1,3} {
 			/* octal escape sequence */
@@ -76,7 +86,7 @@ char scanBuf[1024];
 			    return ERROR_TOK;
 			}
 
-			*s++ = result;
+			*yyextra->s++ = result;
 		    }
 
 <S_STR,S_KEY>\\[0-9]+ {
@@ -84,15 +94,15 @@ char scanBuf[1024];
 			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>\\n	*yyextra->s++ = '\n';
+<S_STR,S_KEY>\\t	*yyextra->s++ = '\t';
+<S_STR,S_KEY>\\r	*yyextra->s++ = '\r';
+<S_STR,S_KEY>\\b	*yyextra->s++ = '\b';
+<S_STR,S_KEY>\\f	*yyextra->s++ = '\f';
+<S_STR,S_KEY>\\v	*yyextra->s++ = '\v';
+<S_STR,S_KEY>\\e	*yyextra->s++ = '\033';
 
-<S_STR,S_KEY>.		*s++ = yytext[0];
+<S_STR,S_KEY>.		*yyextra->s++ = yytext[0];
 
 xkb_keymap		return XKB_KEYMAP;
 xkb_keycodes		return XKB_KEYCODES;
@@ -140,19 +150,18 @@ 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;
+[a-zA-Z_][a-zA-Z_0-9]*	yylval->str = strdup(yytext); return IDENT;
 
 0x[a-fA-F0-9]+		|
 [0-9]+			{
 			    char *end;
-			    scanInt = strtol(yytext, &end, 0);
-                            scanULong = strtoul(yytext, &end, 0);
+			    yylval->num = strtoul(yytext, &end, 0);
 
 			    return INTEGER;
 			}
 [0-9]+\.[0-9]+ {
 			    char *end;
-			    scanInt = strtod(yytext, &end) * XkbGeomPtsPerMM;
+			    yylval->num = strtod(yytext, &end) * XkbGeomPtsPerMM;
 
 			    return FLOAT;
 			}
@@ -183,66 +192,72 @@ alternate_group		return ALTERNATE_GROUP;
 %%
 
 void
-yyerror(const char *s)
+yyerror(YYLTYPE *loc, void *scanner, const char *msg)
 {
+    struct scanner_extra *extra = yyget_extra(scanner);
+
     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);
+        fprintf(stderr,"%s: line %d of %s\n",msg,loc->first_line,
+                (extra->scanFile?extra->scanFile:"(unknown)"));
+        if ((warningLevel>3))
+            fprintf(stderr,"last scanned symbol is: %s\n",extra->scanBuf);
     }
-    return;
-}
-
-void setScanState(char *file, int lineno)
-{
-  yylineno = 1;
-  if (scanFile)
-    free(scanFile);
-  scanFile = strdup(file);
 }
 
 int
-XKBParseString(const char *string, XkbFile ** pRtrn)
+XKBParseString(const char *string, const char *fileName, XkbFile ** pRtrn)
 {
+    int ret;
+    struct parser_param param;
+    struct scanner_extra extra;
     YY_BUFFER_STATE state;
 
     *pRtrn = NULL;
     if (string == NULL)
-	return 1;
-
-    state = yy_scan_string(string);
-    rtrnValue = NULL;
-    if (yyparse() != 0)
-	return 0;
+        return 1;
 
-    yy_delete_buffer(state);
-    yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
-    *pRtrn = rtrnValue;
-    CheckDefaultMap(rtrnValue);
-    rtrnValue = NULL;
+    memset(&extra, 0, sizeof(extra));
+    if (yylex_init_extra(&extra, &param.scanner) != 0)
+        return 0;
+    extra.scanFile = strdup(fileName);
+
+    state = yy_scan_string(string, param.scanner);
+    ret = yyparse(&param);
+    yy_delete_buffer(state, param.scanner);
+    yylex_destroy(param.scanner);
+    free(extra.scanFile);
+    if (ret)
+        return 0;
 
+    CheckDefaultMap(param.rtrn, fileName);
+    *pRtrn = param.rtrn;
     return 1;
 }
 
 int
-XKBParseFile(FILE * file, XkbFile ** pRtrn)
+XKBParseFile(FILE * file, const char *fileName, 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;
-    }
+    int ret;
+    struct parser_param param;
+    struct scanner_extra extra;
+
     *pRtrn = NULL;
+    if (file == NULL)
+        return 1;
+
+    memset(&extra, 0, sizeof(extra));
+    if (yylex_init_extra(&extra, &param.scanner) != 0)
+        return 0;
+    extra.scanFile = strdup(fileName);
+
+    yyset_in(file, param.scanner);
+    ret = yyparse(&param);
+    yylex_destroy(param.scanner);
+    free(extra.scanFile);
+    if (ret)
+        return 0;
+
+    CheckDefaultMap(param.rtrn, fileName);
+    *pRtrn = param.rtrn;
     return 1;
 }
-- 
1.7.9.2



More information about the xorg-devel mailing list