winhelp: Allow MACRO_Execute to be called recursively.

This commit is contained in:
Eric Pouech 2008-07-12 10:37:19 +02:00 committed by Alexandre Julliard
parent 7d0b6bd4a6
commit 81168297e2
1 changed files with 36 additions and 29 deletions

View File

@ -3,7 +3,7 @@
* Help Viewer * Help Viewer
* *
* Copyright 1996 Ulrich Schmid * Copyright 1996 Ulrich Schmid
* Copyright 2002 Eric Pouech * Copyright 2002,2008 Eric Pouech
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -36,16 +36,20 @@
WINE_DEFAULT_DEBUG_CHANNEL(winhelp); WINE_DEFAULT_DEBUG_CHANNEL(winhelp);
static LPCSTR macroptr; struct lex_data {
static LPSTR strptr; LPCSTR macroptr;
static int quote_stack[32]; LPSTR strptr;
static unsigned int quote_stk_idx = 0; int quote_stack[32];
static LPSTR cache_string[32]; unsigned quote_stk_idx;
static int cache_used; LPSTR cache_string[32];
int cache_used;
};
static struct lex_data* lex_data = NULL;
struct lexret yylval; struct lexret yylval;
#define YY_INPUT(buf,result,max_size)\ #define YY_INPUT(buf,result,max_size)\
if ((result = *macroptr ? 1 : 0)) buf[0] = *macroptr++; if ((result = *lex_data->macroptr ? 1 : 0)) buf[0] = *lex_data->macroptr++;
%} %}
%% %%
@ -61,39 +65,39 @@ struct lexret yylval;
<quote>\` | <quote>\` |
<quote>\" | <quote>\" |
<quote>\' { <quote>\' {
if (quote_stk_idx == 0 || if (lex_data->quote_stk_idx == 0 ||
(yytext[0] == '\"' && quote_stack[quote_stk_idx - 1] != '\"') || (yytext[0] == '\"' && lex_data->quote_stack[lex_data->quote_stk_idx - 1] != '\"') ||
(yytext[0] == '`')) (yytext[0] == '`'))
{ {
/* opening a new one */ /* opening a new one */
if (quote_stk_idx == 0) if (lex_data->quote_stk_idx == 0)
{ {
assert(cache_used < sizeof(cache_string) / sizeof(cache_string[0])); assert(lex_data->cache_used < sizeof(lex_data->cache_string) / sizeof(lex_data->cache_string[0]));
strptr = cache_string[cache_used] = HeapAlloc(GetProcessHeap(), 0, strlen(macroptr) + 1); lex_data->strptr = lex_data->cache_string[lex_data->cache_used] = HeapAlloc(GetProcessHeap(), 0, strlen(lex_data->macroptr) + 1);
yylval.string = strptr; yylval.string = lex_data->strptr;
cache_used++; lex_data->cache_used++;
BEGIN(quote); BEGIN(quote);
} }
else *strptr++ = yytext[0]; else *lex_data->strptr++ = yytext[0];
quote_stack[quote_stk_idx++] = yytext[0]; lex_data->quote_stack[lex_data->quote_stk_idx++] = yytext[0];
assert(quote_stk_idx < sizeof(quote_stack) / sizeof(quote_stack[0])); assert(lex_data->quote_stk_idx < sizeof(lex_data->quote_stack) / sizeof(lex_data->quote_stack[0]));
} }
else else
{ {
if (yytext[0] == '`') assert(0); if (yytext[0] == '`') assert(0);
/* close the current quote */ /* close the current quote */
if (--quote_stk_idx == 0) if (--lex_data->quote_stk_idx == 0)
{ {
BEGIN INITIAL; BEGIN INITIAL;
*strptr++ = '\0'; *lex_data->strptr++ = '\0';
return STRING; return STRING;
} }
else *strptr++ = yytext[0]; else *lex_data->strptr++ = yytext[0];
} }
} }
<quote>. *strptr++ = yytext[0]; <quote>. *lex_data->strptr++ = yytext[0];
<quote>\\. *strptr++ = yytext[1]; <quote>\\. *lex_data->strptr++ = yytext[1];
<quote><<EOF>> return 0; <quote><<EOF>> return 0;
" " " "
@ -264,12 +268,17 @@ static int MACRO_CallVoidFunc(FARPROC fn, const char* args)
BOOL MACRO_ExecuteMacro(LPCSTR macro) BOOL MACRO_ExecuteMacro(LPCSTR macro)
{ {
struct lex_data curr_lex_data, *prev_lex_data;
BOOL ret = TRUE; BOOL ret = TRUE;
int t; int t;
WINE_TRACE("%s\n", wine_dbgstr_a(macro)); WINE_TRACE("%s\n", wine_dbgstr_a(macro));
macroptr = macro; prev_lex_data = lex_data;
lex_data = &curr_lex_data;
memset(lex_data, 0, sizeof(*lex_data));
lex_data->macroptr = macro;
while ((t = yylex()) != EMPTY) while ((t = yylex()) != EMPTY)
{ {
@ -295,11 +304,9 @@ BOOL MACRO_ExecuteMacro(LPCSTR macro)
} }
done: done:
strptr = NULL; for (t = 0; t < lex_data->cache_used; t++)
quote_stk_idx = 0; HeapFree(GetProcessHeap(), 0, lex_data->cache_string[t]);
for (t = 0; t < cache_used; t++) lex_data = prev_lex_data;
HeapFree(GetProcessHeap(), 0, cache_string[t]);
cache_used = 0;
return ret; return ret;
} }