comctl32: Disable owner of modal property sheets before creating the dialog.
[wine/wine-kai.git] / programs / winhlp32 / macro.lex.l
blobb8d6ac21fdfe28cd524ebfabd0eefa0c14a756bb
1 %{ /* -*-C-*- */
2 /*
3  * Help Viewer
4  *
5  * Copyright 1996 Ulrich Schmid
6  * Copyright 2002 Eric Pouech
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
23 %option noinput nounput interactive 8bit
24 %x quote
26 #include "config.h"
27 #include <assert.h>
29 #ifndef HAVE_UNISTD_H
30 #define YY_NO_UNISTD_H
31 #endif
33 #include "macro.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(winhelp);
39 static LPCSTR  macroptr;
40 static LPSTR   strptr;
41 static int     quote_stack[32];
42 static unsigned int quote_stk_idx = 0;
43 struct lexret  yylval;
45 #define YY_INPUT(buf,result,max_size)\
46   if ((result = *macroptr ? 1 : 0)) buf[0] = *macroptr++;
51 [-+]?[0-9]+             yylval.integer = strtol(yytext, NULL, 10);      return INTEGER;
52 [-+]?0[xX][0-9a-f]+     yylval.integer = strtol(yytext, NULL, 16);      return INTEGER;
54 [a-zA-Z][_0-9a-zA-Z]*   return MACRO_Lookup(yytext, &yylval);
56 \`          |
57 \"          |
58 \'          |
59 <quote>\`   |
60 <quote>\"   |
61 <quote>\'   {
62     if (quote_stk_idx == 0 ||
63         (yytext[0] == '\"' && quote_stack[quote_stk_idx - 1] != '\"') ||
64         (yytext[0] == '`'))
65     {
66         /* opening a new one */
67         if (quote_stk_idx == 0)
68         {
69             strptr = HeapAlloc(GetProcessHeap(), 0, strlen(macroptr) + 1);
70             yylval.string = strptr;
71             BEGIN(quote);
72         }
73         else *strptr++ = yytext[0];
74         quote_stack[quote_stk_idx++] = yytext[0];
75         assert(quote_stk_idx < sizeof(quote_stack) / sizeof(quote_stack[0]));
76     }
77     else
78     {
79         if (yytext[0] == '`') assert(0);
80         /* close the current quote */
81         if (--quote_stk_idx == 0)
82         {
83             BEGIN INITIAL;
84             *strptr++ = '\0';
85             return STRING;
86         }
87         else *strptr++ = yytext[0];
88     }
91 <quote>.                *strptr++ = yytext[0];
92 <quote>\\.              *strptr++ = yytext[1];
93 <quote><<EOF>>          return 0;
95 " "
96 .                       return yytext[0];
99 #if 0
100 /* all code for testing macros */
101 #include "winhelp.h"
102 static CHAR szTestMacro[256];
104 static LRESULT CALLBACK MACRO_TestDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
106     if (msg == WM_COMMAND && wParam == IDOK)
107     {
108         GetDlgItemText(hDlg, 99, szTestMacro, sizeof(szTestMacro));
109         EndDialog(hDlg, IDOK);
110         return TRUE;
111     }
112     return FALSE;
115 void macro_test(void)
117     WNDPROC lpfnDlg = MakeProcInstance(MACRO_TestDialogProc, Globals.hInstance);
118     DialogBox(Globals.hInstance, STRING_DIALOG_TEST, Globals.active_win->hMainWnd, (DLGPROC)lpfnDlg);
119     FreeProcInstance(lpfnDlg);
120     macro = szTestMacro;
122 #endif
124 /* small helper function for debug messages */
125 static const char* ts(int t)
127     static char c[2] = {0,0};
129     switch (t)
130     {
131     case EMPTY: return "EMPTY";
132     case VOID_FUNCTION: return "VOID_FUNCTION";
133     case BOOL_FUNCTION: return "BOOL_FUNCTION";
134     case INTEGER: return "INTEGER";
135     case STRING: return "STRING";
136     case IDENTIFIER: return "IDENTIFIER";
137     default: c[0] = (char)t; return c;
138     }
141 static int MACRO_CallBoolFunc(FARPROC fn, const char* args, void** ret);
143 /******************************************************************
144  *              MACRO_CheckArgs
146  * checks number of arguments against prototype, and stores arguments on
147  * stack pa for later call
148  * returns -1 on error, otherwise the number of pushed parameters
149  */
150 static int MACRO_CheckArgs(void* pa[], unsigned max, const char* args)
152     int t;
153     unsigned int len = 0, idx = 0;
155     WINE_TRACE("Checking %s\n", args);
157     if (yylex() != '(') {WINE_WARN("missing (\n");return -1;}
159     if (*args)
160     {
161         len = strlen(args);
162         for (;;)
163         {
164             t = yylex();
165             WINE_TRACE("Got %s <=> %c\n", ts(t), *args);
167             switch (*args)
168             {
169             case 'S': 
170                 if (t != STRING)
171                 {WINE_WARN("missing S\n");return -1;}
172                 pa[idx] = (void*)yylval.string;  
173                 break;
174             case 'U':
175             case 'I':
176                 if (t != INTEGER)
177                 {WINE_WARN("missing U\n");return -1;}   
178                 pa[idx] = LongToPtr(yylval.integer);
179                 break;
180             case 'B':
181                 if (t != BOOL_FUNCTION) 
182                 {WINE_WARN("missing B\n");return -1;}   
183                 if (MACRO_CallBoolFunc(yylval.function, yylval.proto, &pa[idx]) == 0)
184                     return -1;
185                 break;
186             default: 
187                 WINE_WARN("unexpected %s while args is %c\n", ts(t), *args);
188                 return -1;
189             }
190             idx++;
191             if (*++args == '\0') break;
192             t = yylex();
193             if (t == ')') goto CheckArgs_end;
194             if (t != ',') {WINE_WARN("missing ,\n");return -1;}
195             if (idx >= max) {WINE_FIXME("stack overflow (%d)\n", max);return -1;}
196         }
197     }
198     if (yylex() != ')') {WINE_WARN("missing )\n");return -1;}
200 CheckArgs_end:
201     while (len > idx) pa[--len] = NULL;
202     return idx;
205 /******************************************************************
206  *              MACRO_CallBoolFunc
208  * Invokes boolean function fn, which arguments are defined by args
209  * stores bool result into ret
210  */
211 static int MACRO_CallBoolFunc(FARPROC fn, const char* args, void** ret)
213     void*       pa[2];
214     int         idx = MACRO_CheckArgs(pa, sizeof(pa)/sizeof(pa[0]), args);
216     if (idx < 0) return 0;
217     if (!fn)     return 1;
219     WINE_TRACE("calling with %u pmts\n", idx);
221     switch (strlen(args))
222     {
223     case 0: *ret = (void*)(fn)();          break;
224     case 1: *ret = (void*)(fn)(pa[0]);     break;
225     default: WINE_FIXME("NIY\n");
226     }
228     return 1;
231 /******************************************************************
232  *              MACRO_CallVoidFunc
235  */
236 static int MACRO_CallVoidFunc(FARPROC fn, const char* args)
238     void*       pa[6];
239     int         idx = MACRO_CheckArgs(pa, sizeof(pa)/sizeof(pa[0]), args);
241     if (idx < 0) return 0;
242     if (!fn)     return 1;
244     WINE_TRACE("calling %p with %u pmts\n", fn, idx);
246     switch (strlen(args))
247     {
248     case 0: (fn)();                                     break;
249     case 1: (fn)(pa[0]);                                break;
250     case 2: (fn)(pa[0],pa[1]);                          break;
251     case 3: (fn)(pa[0],pa[1],pa[2]);                    break;
252     case 4: (fn)(pa[0],pa[1],pa[2],pa[3]);              break;
253     case 5: (fn)(pa[0],pa[1],pa[2],pa[3],pa[4]);        break;
254     case 6: (fn)(pa[0],pa[1],pa[2],pa[3],pa[4],pa[5]);  break;
255     default: WINE_FIXME("NIY\n");
256     }
258     return 1;
261 BOOL MACRO_ExecuteMacro(LPCSTR macro)
263     int t;
265     WINE_TRACE("%s\n", wine_dbgstr_a(macro));
267     macroptr = macro;
269     while ((t = yylex()) != EMPTY)
270     {
271         switch (t)
272         {
273         case VOID_FUNCTION:
274             WINE_TRACE("got type void func(%s)\n", yylval.proto);
275             MACRO_CallVoidFunc(yylval.function, yylval.proto);
276             break;
277         case BOOL_FUNCTION:
278             WINE_WARN("got type bool func(%s)\n", yylval.proto);
279             break;
280         default:
281             WINE_WARN("got unexpected type %s\n", ts(t));
282             return 0;
283         }
284         switch (t = yylex())
285         {
286         case EMPTY:     return 1;
287         case ';':       break;
288         default:        return 0;
289         }
290     }
292     HeapFree(GetProcessHeap(), 0, strptr);
293     strptr = NULL;
294     quote_stk_idx = 0;
296     return 1;
299 #ifndef yywrap
300 int yywrap(void) { return 1; }
301 #endif