Make parser and scanner reentrant
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@gmail.com> [daniels: Updated to current sources.]master
parent
034ffce664
commit
bb6ca7682c
|
@ -56,8 +56,6 @@ ProcessIncludeFile(struct xkb_context *context,
|
|||
{
|
||||
FILE *file;
|
||||
XkbFile *rtrn, *mapToUse, *next;
|
||||
char oldFile[1024] = {0};
|
||||
int oldLine = lineNum;
|
||||
|
||||
file = XkbFindFileInPath(context, stmt->file, file_type, &stmt->path);
|
||||
if (file == NULL)
|
||||
|
@ -66,16 +64,9 @@ ProcessIncludeFile(struct xkb_context *context,
|
|||
XkbDirectoryForInclude(file_type));
|
||||
return False;
|
||||
}
|
||||
if (scanFile)
|
||||
strcpy(oldFile, scanFile);
|
||||
else
|
||||
memset(oldFile, 0, sizeof(oldFile));
|
||||
oldLine = lineNum;
|
||||
setScanState(stmt->file, 1);
|
||||
/* 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;
|
||||
|
@ -114,7 +105,6 @@ ProcessIncludeFile(struct xkb_context *context,
|
|||
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",
|
||||
|
|
|
@ -552,7 +552,7 @@ PrintStmtAddrs(ParseCommon * stmt)
|
|||
#endif
|
||||
|
||||
void
|
||||
CheckDefaultMap(XkbFile * maps)
|
||||
CheckDefaultMap(XkbFile * maps, const char *fileName)
|
||||
{
|
||||
XkbFile *dflt, *tmp;
|
||||
|
||||
|
@ -569,7 +569,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)"));
|
||||
|
@ -603,11 +603,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;
|
||||
|
|
|
@ -28,13 +28,19 @@
|
|||
#define XKBPARSE_H 1
|
||||
|
||||
#include "xkbcomp.h"
|
||||
#include "xkbparse.h"
|
||||
|
||||
extern char scanBuf[1024];
|
||||
extern int scanInt;
|
||||
extern unsigned long scanULong;
|
||||
extern int lineNum;
|
||||
struct parser_param {
|
||||
void *scanner;
|
||||
XkbFile *rtrn;
|
||||
};
|
||||
|
||||
extern XkbFile *rtrnValue;
|
||||
struct scanner_extra {
|
||||
char *scanFile;
|
||||
/* FIXME: This can overflow! */
|
||||
char scanBuf[8192];
|
||||
char *s;
|
||||
};
|
||||
|
||||
extern ParseCommon *AppendStmt(ParseCommon * /* to */ ,
|
||||
ParseCommon * /* append */
|
||||
|
@ -123,7 +129,9 @@ extern IncludeStmt *IncludeCreate(char * /* str */ ,
|
|||
);
|
||||
|
||||
extern unsigned StmtSetMerge(ParseCommon * /* stmt */ ,
|
||||
unsigned /* merge */
|
||||
unsigned /* merge */,
|
||||
YYLTYPE * /* loc */,
|
||||
void * /* scanner */
|
||||
);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -132,12 +140,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 */ ,
|
||||
|
@ -147,14 +157,9 @@ extern XkbFile *CreateXKBFile(int /* type */ ,
|
|||
|
||||
extern void FreeXKBFile(XkbFile *file);
|
||||
|
||||
extern void yyerror(const char * /* msg */
|
||||
);
|
||||
|
||||
extern void setScanState(const char * /* file */ ,
|
||||
int /* line */
|
||||
);
|
||||
|
||||
extern void FreeStmt(ParseCommon * /* stmt */
|
||||
);
|
||||
|
||||
extern void yyerror(struct YYLTYPE *loc, void *scanner, const char *msg);
|
||||
|
||||
#endif /* XKBPARSE_H */
|
||||
|
|
|
@ -212,7 +212,6 @@ compile_keymap(struct xkb_context *context, XkbFile *file)
|
|||
|
||||
err:
|
||||
FreeXKBFile(file);
|
||||
free(scanFile);
|
||||
XkbcFreeAllAtoms();
|
||||
return xkb;
|
||||
}
|
||||
|
@ -273,8 +272,7 @@ xkb_map_new_from_string(struct xkb_context *context,
|
|||
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;
|
||||
}
|
||||
|
@ -306,8 +304,7 @@ xkb_map_new_from_fd(struct xkb_context *context,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
setScanState("input", 1);
|
||||
if (!XKBParseFile(fptr, &file) || !file) {
|
||||
if (!XKBParseFile(fptr, "(unknown file)", &file) || !file) {
|
||||
ERROR("failed to parse input xkb file\n");
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include "XKBcommonint.h"
|
||||
#include "xkbmisc.h"
|
||||
|
||||
extern char *scanFile;
|
||||
|
||||
#define TypeUnknown 0
|
||||
#define TypeBoolean 1
|
||||
#define TypeInt 2
|
||||
|
|
|
@ -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,19 +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>
|
||||
|
||||
extern int yylex(void);
|
||||
extern FILE *yyin;
|
||||
%}
|
||||
%right EQUALS
|
||||
%left PLUS MINUS
|
||||
%left TIMES DIVIDE
|
||||
|
@ -110,6 +118,7 @@ extern FILE *yyin;
|
|||
%union {
|
||||
int ival;
|
||||
unsigned uval;
|
||||
int64_t num;
|
||||
char *str;
|
||||
Atom sval;
|
||||
ParseCommon *any;
|
||||
|
@ -128,6 +137,8 @@ extern FILE *yyin;
|
|||
void *geom;
|
||||
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
|
||||
|
@ -154,11 +165,11 @@ extern FILE *yyin;
|
|||
%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
|
||||
|
@ -254,57 +265,57 @@ 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
|
||||
|
@ -319,11 +330,12 @@ Decl : OptMergeMode VarDecl
|
|||
| 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;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
@ -713,7 +725,7 @@ KeySymList : KeySymList COMMA KeySym
|
|||
{ $$= CreateKeysymList($1); }
|
||||
;
|
||||
|
||||
KeySym : IDENT { $$= strdup(scanBuf); }
|
||||
KeySym : IDENT { $$= $1; }
|
||||
| SECTION { $$= strdup("section"); }
|
||||
| Integer
|
||||
{
|
||||
|
@ -733,32 +745,36 @@ SignedNumber : MINUS Number { $$= -$2; }
|
|||
| Number { $$= $1; }
|
||||
;
|
||||
|
||||
Number : FLOAT { $$= scanInt; }
|
||||
| INTEGER { $$= scanInt*XkbGeomPtsPerMM; }
|
||||
Number : FLOAT { $$= $1; }
|
||||
| INTEGER { $$= $1*XkbGeomPtsPerMM; }
|
||||
;
|
||||
|
||||
Float : FLOAT { $$= 0; }
|
||||
;
|
||||
|
||||
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
|
||||
|
|
|
@ -31,25 +31,26 @@
|
|||
|
||||
#include "utils.h"
|
||||
#include "parseutils.h"
|
||||
#include "xkbparse.h"
|
||||
|
||||
char *scanFile = NULL;
|
||||
int lineNum = 0;
|
||||
|
||||
int scanInt;
|
||||
unsigned long scanULong;
|
||||
extern int yyparse(struct parser_param *param);
|
||||
|
||||
static char *s;
|
||||
char scanBuf[1024];
|
||||
|
||||
extern int yyparse(void);
|
||||
#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 never-interactive
|
||||
%option nowarn
|
||||
%option noinput
|
||||
%option nounput
|
||||
|
||||
|
@ -60,11 +61,21 @@ extern int yyparse(void);
|
|||
"//"[^\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 */
|
||||
|
@ -77,7 +88,7 @@ extern int yyparse(void);
|
|||
return ERROR_TOK;
|
||||
}
|
||||
|
||||
*s++ = result;
|
||||
*yyextra->s++ = result;
|
||||
}
|
||||
|
||||
<S_STR,S_KEY>\\[0-9]+ {
|
||||
|
@ -85,15 +96,15 @@ extern int yyparse(void);
|
|||
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;
|
||||
|
@ -141,19 +152,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;
|
||||
}
|
||||
|
@ -184,62 +194,75 @@ alternate_group return ALTERNATE_GROUP;
|
|||
%%
|
||||
|
||||
void
|
||||
yyerror(const char *msg)
|
||||
yyerror(YYLTYPE *loc, void *scanner, const char *msg)
|
||||
{
|
||||
if (warningLevel>0) {
|
||||
fprintf(stderr,"%s: line %d of %s\n",msg,yylineno,
|
||||
(scanFile?scanFile:"(unknown)"));
|
||||
if (warningLevel>3)
|
||||
fprintf(stderr,"last scanned symbol is: %s\n",scanBuf);
|
||||
struct scanner_extra *extra = yyget_extra(scanner);
|
||||
|
||||
if (warningLevel > 0) {
|
||||
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(const char *file, int lineno)
|
||||
{
|
||||
yylineno = 1;
|
||||
free(scanFile);
|
||||
scanFile = strdup(file);
|
||||
}
|
||||
|
||||
int
|
||||
XKBParseString(const char *string, XkbFile ** pRtrn)
|
||||
XKBParseString(const char *string, const char *fileName, XkbFile **pRtrn)
|
||||
{
|
||||
YY_BUFFER_STATE state;
|
||||
struct parser_param param;
|
||||
struct scanner_extra extra;
|
||||
int ret;
|
||||
|
||||
*pRtrn = NULL;
|
||||
if (string == NULL)
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
state = yy_scan_string(string);
|
||||
rtrnValue = NULL;
|
||||
if (yyparse() != 0)
|
||||
return 0;
|
||||
memset(&extra, 0, sizeof(extra));
|
||||
ret = yylex_init_extra(&extra, ¶m.scanner);
|
||||
if (ret != 0)
|
||||
return 0;
|
||||
extra.scanFile = strdup(fileName);
|
||||
|
||||
yy_delete_buffer(state);
|
||||
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
|
||||
*pRtrn = rtrnValue;
|
||||
CheckDefaultMap(rtrnValue);
|
||||
rtrnValue = NULL;
|
||||
state = yy_scan_string(string, param.scanner);
|
||||
ret = yyparse(¶m);
|
||||
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)
|
||||
{
|
||||
int ret;
|
||||
struct parser_param param;
|
||||
struct scanner_extra extra;
|
||||
|
||||
*pRtrn = NULL;
|
||||
if (!file)
|
||||
return 1;
|
||||
|
||||
yyin = file;
|
||||
rtrnValue = NULL;
|
||||
if (yyparse() != 0)
|
||||
memset(&extra, 0, sizeof(extra));
|
||||
if (yylex_init_extra(&extra, ¶m.scanner) != 0)
|
||||
return 0;
|
||||
extra.scanFile = strdup(fileName);
|
||||
|
||||
yyset_in(file, param.scanner);
|
||||
ret = yyparse(¶m);
|
||||
yylex_destroy(param.scanner);
|
||||
free(extra.scanFile);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
yylex_destroy();
|
||||
*pRtrn = rtrnValue;
|
||||
CheckDefaultMap(rtrnValue);
|
||||
rtrnValue = NULL;
|
||||
CheckDefaultMap(param.rtrn, fileName);
|
||||
*pRtrn = param.rtrn;
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue