debug.l 10.8 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1
/* -*-C-*-
Alexandre Julliard's avatar
Alexandre Julliard committed
2
 * Lexical scanner for command line parsing
Alexandre Julliard's avatar
Alexandre Julliard committed
3
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
4
 * Copyright 1993 Eric Youngdale
5
 *           2000 Eric Pouech
6 7 8 9 10 11 12 13 14 15 16 17 18
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard's avatar
Alexandre Julliard committed
20 21
 */

22
%option noinput nounput always-interactive 8bit prefix="dbg_"
23

Alexandre Julliard's avatar
Alexandre Julliard committed
24
%{
Alexandre Julliard's avatar
Alexandre Julliard committed
25
#include <stdlib.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
26
#include <string.h>
27 28
#include <stdarg.h>

29
#define YY_NO_UNISTD_H
Alexandre Julliard's avatar
Alexandre Julliard committed
30
#include "debugger.h"
31
#include "dbg.tab.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
32 33

#undef YY_INPUT
34

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
static char** local_lexemes /* = NULL */;
static int next_lexeme /* = 0 */;
static int alloc_lexeme /* = 0 */;

char* lexeme_alloc_size(int size)
{
    assert(0 <= next_lexeme && next_lexeme < alloc_lexeme + 1);
    if (next_lexeme >= alloc_lexeme)
    {
        alloc_lexeme += 32;
        local_lexemes = dbg_heap_realloc(local_lexemes, alloc_lexeme * sizeof(local_lexemes[0]));
        assert(local_lexemes);
    }
    return local_lexemes[next_lexeme++] = HeapAlloc(GetProcessHeap(), 0, size + 1);
}

static char* lexeme_alloc(const char* lexeme)
{
    char*       ptr = lexeme_alloc_size(strlen(lexeme) + 1);
    return strcpy(ptr, lexeme);
}

void lexeme_flush(void)
{
    while (--next_lexeme >= 0) HeapFree(GetProcessHeap(), 0, local_lexemes[next_lexeme]);
    next_lexeme = 0;
}

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
/* called with quoted string, unescape all elements inside the quotes */
static char* unescape_string(const char* str)
{
    size_t len = strlen(str) - 2;
    char* ret = lexeme_alloc_size(len + 1);
    char* dst = ret;
    const char* ptr;
    for (ptr = str + 1; ptr < str + 1 + len; ptr++)
    {
        if (*ptr == '\\')
        {
            switch (*++ptr)
            {
            case 't':  *dst++ = '\t'; break;
            case 'r':  *dst++ = '\r'; break;
            case 'n':  *dst++ = '\n'; break;
            case '\\': *dst++ = '\\'; break;
            case '"':  *dst++ = '"';  break;
            default: *dst++ = '\\'; *dst++ = *ptr; /* not handled, don't change */
            }
        }
        else
            *dst++ = *ptr;
    }
    *dst = '\0';
    return ret;
}

Alexandre Julliard's avatar
Alexandre Julliard committed
91
#define YY_INPUT(buf,result,max_size) \
92
        (result = input_lex_read_buffer(buf, max_size))
Alexandre Julliard's avatar
Alexandre Julliard committed
93 94 95 96

static int syntax_error;
%}

97
OCTDIGIT   [0-7]
Alexandre Julliard's avatar
Alexandre Julliard committed
98 99
DIGIT	   [0-9]
HEXDIGIT   [0-9a-fA-F]
100
FORMAT     [ubcdgiswxa]
101
IDENTIFIER [_a-zA-Z~?][_a-zA-Z0-9~?@]*
102
SCOPED_IDENTIFIER [_a-zA-Z~?][_a-zA-Z0-9~?@]*"::"
103
MODULE_IDENTIFIER [_a-zA-Z~?\*][_a-zA-Z0-9~?\*@]*"!"
104
PATHNAME   [\\/_a-zA-Z0-9\.~@][\\/\-_a-zA-Z0-9\.~@]*
105
STRING     \"(\\[^\n]|[^\\"\n])*\"
Alexandre Julliard's avatar
Alexandre Julliard committed
106 107 108 109

%s FORMAT_EXPECTED
%s INFO_CMD
%s HELP_CMD
110 111
%s BD_CMD
%s LOCAL_CMD
Alexandre Julliard's avatar
Alexandre Julliard committed
112
%s SHOW_CMD
113
%s MODE_CMD
114
%s MAINT_CMD
115
%s NOCMD
116
%s PATH_ACCEPTED
Alexandre Julliard's avatar
Alexandre Julliard committed
117

118
%x PATH_EXPECTED
119
%x ASTRING_EXPECTED
120
%x AWORD_EXPECTED
121
%x NOPROCESS
Alexandre Julliard's avatar
Alexandre Julliard committed
122
%%
123
                                        /* set to special state when no process is loaded. */
124
                                        if (!dbg_num_processes() && YYSTATE == INITIAL) {BEGIN(NOPROCESS);}
125

Eric Pouech's avatar
Eric Pouech committed
126
<<EOF>>                                 { return tEOF; }
127
<*>"#"[^\n]*                            /* Skip comments */
128
<*>\n		                        { BEGIN(INITIAL); syntax_error = 0; return tEOL; }
129 130 131 132 133 134 135 136 137 138 139 140 141 142
                                        /* Indicates end of command. Reset state. */

"||"					{ return OP_LOR; }
"&&"					{ return OP_LAND; }
"=="					{ return OP_EQ; }
"!="					{ return OP_NE; }
"<="					{ return OP_LE; }
">="					{ return OP_GE; }
"<<"					{ return OP_SHL; }
">>"					{ return OP_SHR; }
"->"					{ return OP_DRF; }
"["					{ return *yytext; }
"]"					{ return *yytext; }

143 144
"0x"{HEXDIGIT}+      			{ sscanf(yytext, "%I64x", &dbg_lval.integer); return tNUM; }
{DIGIT}+             			{ sscanf(yytext, "%I64d", &dbg_lval.integer); return tNUM; }
145
"'\\''"                                 { dbg_lval.integer = '\''; return tNUM;}
146 147
"'\\0"{OCTDIGIT}*"'"                    { sscanf(yytext + 3, "%I64o", &dbg_lval.integer); return tNUM;}
"'\\x"{HEXDIGIT}+"'"                    { sscanf(yytext + 3, "%I64x", &dbg_lval.integer); return tNUM;}
148 149
"'\\"[a-z]"'"                           { dbg_lval.integer = yytext[2] - 'a'; return tNUM;}
"'"."'"                                 { dbg_lval.integer = yytext[1]; return tNUM;}
150 151

<FORMAT_EXPECTED>"/"{DIGIT}+{FORMAT}	{ char* last;
152 153
                                          dbg_lval.integer = strtol(yytext+1, &last, 0) << 8;
                                          dbg_lval.integer |= *last;
154 155
                                          return tFORMAT; }

156
<FORMAT_EXPECTED>"/"{FORMAT}          	{ dbg_lval.integer = (1 << 8) | yytext[1]; return tFORMAT; }
157

158
<*>{STRING}	                        { dbg_lval.string = unescape_string(yytext); return tSTRING;}
159
<ASTRING_EXPECTED>[^\n]+                { char* p = yytext; while (*p == ' ' || *p == '\t') p++;
160
                                          dbg_lval.string = lexeme_alloc(p); return tSTRING; }
161 162
<AWORD_EXPECTED>[^ \t\n]+               { char* p = yytext; while (*p == ' ' || *p == '\t') p++;
                                          dbg_lval.string = lexeme_alloc(p); return tSTRING; }
163
<INITIAL,NOPROCESS>info|inf|in		{ BEGIN(INFO_CMD); return tINFO; }
164 165
<INITIAL>up				{ BEGIN(NOCMD); return tUP; }
<INITIAL>down|dow|do			{ BEGIN(NOCMD); return tDOWN; }
166
<INITIAL,INFO_CMD>frame|fram|fra|fr	{ BEGIN(NOCMD); return tFRAME; }
167
<INITIAL>list|lis|li|l			{ BEGIN(PATH_ACCEPTED); return tLIST; }
168 169
<INITIAL>enable|enabl|enab|ena		{ BEGIN(BD_CMD); return tENABLE;}
<INITIAL>disable|disabl|disab|disa|dis  { BEGIN(BD_CMD); return tDISABLE; }
170
<INITIAL>disassemble|disassembl|disassemb|disassem|disasse|disass|disas { BEGIN(NOCMD); return tDISASSEMBLE; }
171 172
<INITIAL>locally|local			{ BEGIN(LOCAL_CMD); return tLOCAL; }
<INITIAL,LOCAL_CMD>display|displa|displ|disp	{ BEGIN(FORMAT_EXPECTED); return tDISPLAY; }
173 174
<INFO_CMD,BD_CMD>display|displa|displ|disp|dis|di|d	{ BEGIN(NOCMD); return tDISPLAY; }
<INITIAL>undisplay|undispla|undispl|undisp|undis|undi|und	{ BEGIN(NOCMD); return tUNDISPLAY; }
175
<INITIAL>delete|delet|dele|del		{ BEGIN(BD_CMD); return tDELETE; }
176
<INITIAL>thread|threa|thre|thr|th	{ BEGIN(NOCMD); return tTHREAD; }
177 178
<INITIAL,NOPROCESS>quit|qui|qu|q	{ BEGIN(NOCMD); return tQUIT; }
<INITIAL>set|se				{ BEGIN(NOCMD); return tSET; }
Alexandre Julliard's avatar
Alexandre Julliard committed
179
<INITIAL>x				{ BEGIN(FORMAT_EXPECTED); return tEXAM; }
180
<INITIAL,NOPROCESS>help|hel|he|"?"	{ BEGIN(HELP_CMD); return tHELP; }
Alexandre Julliard's avatar
Alexandre Julliard committed
181

182 183
<INITIAL,NOPROCESS>backtrace|backtrac|backtra|backt|back|bac|ba|bt { BEGIN(NOCMD); return tBACKTRACE; }
<INITIAL,NOPROCESS>where|wher|whe       { BEGIN(NOCMD); return tBACKTRACE; }
Alexandre Julliard's avatar
Alexandre Julliard committed
184

185 186 187 188 189 190 191 192
<INITIAL>cont|con|co|c   		{ BEGIN(NOCMD); return tCONT; }
<INITIAL>pass|pas|pa   			{ BEGIN(NOCMD); return tPASS; }
<INITIAL>condition|conditio|conditi|condit|condi|cond	{ BEGIN(NOCMD); return tCOND; }
<INITIAL>step|ste|st|s   		{ BEGIN(NOCMD); return tSTEP; }
<INITIAL>next|nex|ne|n   		{ BEGIN(NOCMD); return tNEXT; }
<INITIAL>stepi|si	   		{ BEGIN(NOCMD); return tSTEPI; }
<INITIAL>nexti|ni	   		{ BEGIN(NOCMD); return tNEXTI; }
<INITIAL>finish|finis|fini|fin|fi	{ BEGIN(NOCMD); return tFINISH; }
Alexandre Julliard's avatar
Alexandre Julliard committed
193

194
<INITIAL>abort|abor|abo         	{ BEGIN(NOCMD); return tABORT; }
Alexandre Julliard's avatar
Alexandre Julliard committed
195 196 197
<INITIAL>print|prin|pri|pr|p		{ BEGIN(FORMAT_EXPECTED); return tPRINT; }

<INITIAL>show|sho|sh			{ BEGIN(SHOW_CMD); return tSHOW; }
Eric Pouech's avatar
Eric Pouech committed
198
<INITIAL,NOPROCESS>source|sourc|sour|src { BEGIN(PATH_EXPECTED); return tSOURCE; }
199
<INITIAL>symbolfile|symbols|symbol|sf   { BEGIN(PATH_EXPECTED); return tSYMBOLFILE; }
Alexandre Julliard's avatar
Alexandre Julliard committed
200

201 202
<INITIAL,INFO_CMD,BD_CMD>break|brea|bre|br|b	{ BEGIN(PATH_ACCEPTED); return tBREAK; }
<INITIAL,INFO_CMD,BD_CMD>hbreak|hbrea|hbre|hbr|hb { BEGIN(PATH_ACCEPTED); return tHBREAK; }
203
<INITIAL>watch|watc|wat			{ BEGIN(NOCMD); return tWATCH; }
204
<INITIAL>rwatch|rwatc|rwat		{ BEGIN(NOCMD); return tRWATCH; }
205
<INITIAL>whatis|whati|what		{ BEGIN(NOCMD); return tWHATIS; }
206
<INITIAL,NOPROCESS>run|ru|r     	{ BEGIN(AWORD_EXPECTED); return tRUN;}
207
<INITIAL>detach|detac|deta|det   	{ BEGIN(NOCMD); return tDETACH; }
208
<INITIAL>kill|kil|ki|k                  { BEGIN(NOCMD); return tKILL; }
209
<INITIAL,NOPROCESS>maintenance|maint    { BEGIN(MAINT_CMD); return tMAINTENANCE; }
210
<INITIAL>minidump|mdmp                  { BEGIN(PATH_EXPECTED); return tMINIDUMP; }
211
<INITIAL>echo				{ BEGIN(ASTRING_EXPECTED); return tECHO; }
212
<NOPROCESS>attach|attac|atta|att 	{ BEGIN(NOCMD); return tATTACH; }
213 214
<INFO_CMD>share|shar|sha                { return tSHARE; }
<MAINT_CMD>module|modul|mod             { BEGIN(ASTRING_EXPECTED); return tMODULE; }
Alexandre Julliard's avatar
Alexandre Julliard committed
215
<INFO_CMD>locals|local|loca|loc		{ return tLOCAL; }
216 217 218 219
<INFO_CMD>class|clas|cla                { return tCLASS; }
<INFO_CMD>process|proces|proce|proc   	{ return tPROCESS; }
<INFO_CMD>threads|thread|threa|thre|thr|th { return tTHREAD; }
<INFO_CMD>exception|except|exc|ex	{ return tEXCEPTION; }
Alexandre Julliard's avatar
Alexandre Julliard committed
220
<INFO_CMD>registers|regs|reg|re		{ return tREGS; }
221 222
<INFO_CMD>allregs|allreg|allre          { return tALLREGS; }
<INFO_CMD>"all-registers"|"all-regs"|"all-reg"|"all-re" { return tALLREGS; }
Alexandre Julliard's avatar
Alexandre Julliard committed
223
<INFO_CMD>segments|segment|segm|seg|se	{ return tSEGMENTS; }
224
<INFO_CMD>stack|stac|sta|st     	{ return tSTACK; }
225
<INFO_CMD>symbol|symbo|symb|sym         { BEGIN(ASTRING_EXPECTED); return tSYMBOL; }
226 227
<INFO_CMD>maps|map			{ return tMAPS; }
<INFO_CMD>window|windo|wind|win|wnd	{ return tWND; }
Alexandre Julliard's avatar
Alexandre Julliard committed
228
<HELP_CMD>info|inf|in                   { return tINFO; }
229
<MAINT_CMD>type                         { return tTYPE; }
Alexandre Julliard's avatar
Alexandre Julliard committed
230

231
<INITIAL,SHOW_CMD>directories|directorie|directori|director|directo|direct|direc|direc|dir {
232
			                  BEGIN(PATH_EXPECTED); return tDIR; }
Alexandre Julliard's avatar
Alexandre Julliard committed
233

Alexandre Julliard's avatar
Alexandre Julliard committed
234 235 236 237 238 239 240 241 242 243 244
char					{ return tCHAR; }
short					{ return tSHORT; }
int					{ return tINT; }
long					{ return tLONG; }
float					{ return tFLOAT; }
double					{ return tDOUBLE; }
unsigned				{ return tUNSIGNED; }
signed					{ return tSIGNED; }
struct					{ return tSTRUCT; }
union					{ return tUNION; }
enum					{ return tENUM; }
245
all                                     { return tALL; }
Alexandre Julliard's avatar
Alexandre Julliard committed
246

247
{MODULE_IDENTIFIER}?{SCOPED_IDENTIFIER}*{IDENTIFIER}	{ dbg_lval.string = lexeme_alloc(yytext); return tIDENTIFIER; }
248
"$"{IDENTIFIER}				{ dbg_lval.string = lexeme_alloc(yytext+1); return tINTVAR; }
Alexandre Julliard's avatar
Alexandre Julliard committed
249

250 251 252 253
<PATH_EXPECTED,PATH_ACCEPTED>{PATHNAME}	{ dbg_lval.string = lexeme_alloc(yytext); return tPATH; }

[-+<=>|&^()*/%:!~,\.]			{ return *yytext; }

254
<*>[ \t\r]+                             /* Eat up whitespace and DOS LF */
Alexandre Julliard's avatar
Alexandre Julliard committed
255

256
<NOPROCESS>.                            { BEGIN(ASTRING_EXPECTED); yyless(0); return tNOPROCESS;}
257
<*>.                                    { if (syntax_error == 0) { syntax_error++; dbg_printf("Syntax Error (%s)\n", yytext); } }
Alexandre Julliard's avatar
Alexandre Julliard committed
258 259
%%

260 261
#ifndef dbg_wrap
int dbg_wrap(void) { return 1; }
Alexandre Julliard's avatar
Alexandre Julliard committed
262
#endif