debug.l 10.3 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 interactive 8bit prefix="dbg_"
23

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

30 31 32 33
#ifndef HAVE_UNISTD_H
#define YY_NO_UNISTD_H
#endif

Alexandre Julliard's avatar
Alexandre Julliard committed
34
#include "debugger.h"
35
#include "dbg.tab.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
36 37

#undef YY_INPUT
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 63 64 65 66
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;
}

67 68
static int read_input(const char* pfx, char* buf, int size)
{
69 70 71
    int len;
    static char*  last_line = NULL;
    static size_t last_line_idx = 0;
Eric Pouech's avatar
Eric Pouech committed
72

73 74 75
    /* try first to fetch the remaining of an existing line */
    if (last_line_idx == 0)
    {
76
        char* tmp = NULL;
77 78
        /* no remaining chars to be read from last line, grab a brand new line up to '\n' */
        lexeme_flush();
79
        len = input_fetch_entire_line(pfx, &tmp);
80
        if (len < 0) return 0;  /* eof */
81 82 83
        /* FIXME: should have a pair of buffers, and switch between the two, instead of
         * reallocating a new one for each line
         */
84
        if (last_line && (len == 0 || (len == 1 && tmp[0] == '\n') || (len == 2 && tmp[0] == '\r' && tmp[1] == '\n')))
85 86 87 88 89 90 91 92
        {
            HeapFree(GetProcessHeap(), 0, tmp);
        }
        else
        {
            HeapFree(GetProcessHeap(), 0, last_line);
            last_line = tmp;
        }
93 94 95 96 97 98 99 100 101
    }

    len = min(strlen(last_line + last_line_idx), size - 1);
    memcpy(buf, last_line + last_line_idx, len);
    buf[len] = '\0';
    if ((last_line_idx += len) >= strlen(last_line))
        last_line_idx = 0;
    return len;
}
102

Alexandre Julliard's avatar
Alexandre Julliard committed
103
#define YY_INPUT(buf,result,max_size) \
104 105
	if ((result = read_input("Wine-dbg>", buf, max_size)) < 0) \
	    YY_FATAL_ERROR("read_input in flex scanner failed");
Alexandre Julliard's avatar
Alexandre Julliard committed
106 107 108 109

static int syntax_error;
%}

Alexandre Julliard's avatar
Alexandre Julliard committed
110 111
DIGIT	   [0-9]
HEXDIGIT   [0-9a-fA-F]
112
FORMAT     [ubcdgiswxa]
113
IDENTIFIER [_a-zA-Z~?][_a-zA-Z0-9~?@]*
114
PATHNAME   [\\/_a-zA-Z0-9\.~@][\\/\-_a-zA-Z0-9\.~@]*
Alexandre Julliard's avatar
Alexandre Julliard committed
115 116 117 118 119
STRING     \"[^\n"]+\"

%s FORMAT_EXPECTED
%s INFO_CMD
%s HELP_CMD
120 121
%s BD_CMD
%s LOCAL_CMD
Alexandre Julliard's avatar
Alexandre Julliard committed
122
%s SHOW_CMD
123
%s MODE_CMD
124
%s MAINT_CMD
125
%s NOCMD
126
%s PATH_ACCEPTED
Alexandre Julliard's avatar
Alexandre Julliard committed
127

128
%x PATH_EXPECTED
129 130
%x ASTRING_EXPECTED
%x NOPROCESS
Alexandre Julliard's avatar
Alexandre Julliard committed
131
%%
132
                                        /* set to special state when no process is loaded. */
133
                                        if (!dbg_num_processes() && YYSTATE == INITIAL) {BEGIN(NOPROCESS);}
134

Eric Pouech's avatar
Eric Pouech committed
135
<<EOF>>                                 { return tEOF; }
136
<*>\n		                        { BEGIN(INITIAL); syntax_error = 0; return tEOL; }
137 138 139 140 141 142 143 144 145 146 147
                                        /* 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; }
148
"::"					{ return OP_SCOPE; }
149 150 151
"["					{ return *yytext; }
"]"					{ return *yytext; }

152 153
"0x"{HEXDIGIT}+      			{ sscanf(yytext, "%lx", &dbg_lval.integer); return tNUM; }
{DIGIT}+             			{ sscanf(yytext, "%ld", &dbg_lval.integer); return tNUM; }
154 155

<FORMAT_EXPECTED>"/"{DIGIT}+{FORMAT}	{ char* last;
156 157
                                          dbg_lval.integer = strtol(yytext+1, &last, 0) << 8;
                                          dbg_lval.integer |= *last;
158 159
                                          return tFORMAT; }

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

162
{STRING} 				{ dbg_lval.string = lexeme_alloc(yytext + 1); dbg_lval.string[strlen(dbg_lval.string) - 1] = '\0'; return tSTRING; }
163
<ASTRING_EXPECTED>[^\n]+                { char* p = yytext; while (*p == ' ' || *p == '\t') p++;
164
                                          dbg_lval.string = lexeme_alloc(p); return tSTRING; }
Alexandre Julliard's avatar
Alexandre Julliard committed
165

166
<INITIAL,NOPROCESS>info|inf|in		{ BEGIN(INFO_CMD); return tINFO; }
167 168 169
<INITIAL>up				{ BEGIN(NOCMD); return tUP; }
<INITIAL>down|dow|do			{ BEGIN(NOCMD); return tDOWN; }
<INITIAL>frame|fram|fra|fr		{ BEGIN(NOCMD); return tFRAME; }
170
<INITIAL>list|lis|li|l			{ BEGIN(PATH_ACCEPTED); return tLIST; }
171 172
<INITIAL>enable|enabl|enab|ena		{ BEGIN(BD_CMD); return tENABLE;}
<INITIAL>disable|disabl|disab|disa|dis  { BEGIN(BD_CMD); return tDISABLE; }
173
<INITIAL>disassemble|disassembl|disassemb|disassem|disasse|disass|disas { BEGIN(NOCMD); return tDISASSEMBLE; }
174 175
<INITIAL>locally|local			{ BEGIN(LOCAL_CMD); return tLOCAL; }
<INITIAL,LOCAL_CMD>display|displa|displ|disp	{ BEGIN(FORMAT_EXPECTED); return tDISPLAY; }
176 177
<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; }
178
<INITIAL>delete|delet|dele|del		{ BEGIN(BD_CMD); return tDELETE; }
179 180
<INITIAL,NOPROCESS>quit|qui|qu|q	{ BEGIN(NOCMD); return tQUIT; }
<INITIAL>set|se				{ BEGIN(NOCMD); return tSET; }
Alexandre Julliard's avatar
Alexandre Julliard committed
181
<INITIAL>x				{ BEGIN(FORMAT_EXPECTED); return tEXAM; }
182
<INITIAL,NOPROCESS>help|hel|he|"?"	{ BEGIN(HELP_CMD); return tHELP; }
Alexandre Julliard's avatar
Alexandre Julliard committed
183

184 185
<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
186

187 188 189 190 191 192 193 194
<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
195

196
<INITIAL>abort|abor|abo         	{ BEGIN(NOCMD); return tABORT; }
Alexandre Julliard's avatar
Alexandre Julliard committed
197 198 199
<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
200
<INITIAL,NOPROCESS>source|sourc|sour|src { BEGIN(PATH_EXPECTED); return tSOURCE; }
201
<INITIAL>symbolfile|symbols|symbol|sf   { BEGIN(PATH_EXPECTED); return tSYMBOLFILE; }
Alexandre Julliard's avatar
Alexandre Julliard committed
202

203 204 205 206
<INITIAL,INFO_CMD,BD_CMD>break|brea|bre|br|b	{ BEGIN(NOCMD); return tBREAK; }
<INITIAL,INFO_CMD,BD_CMD>hbreak|hbrea|hbre|hbr|hb { BEGIN(NOCMD); return tHBREAK; }
<INITIAL>watch|watc|wat			{ BEGIN(NOCMD); return tWATCH; }
<INITIAL>whatis|whati|what		{ BEGIN(NOCMD); return tWHATIS; }
207
<INITIAL,NOPROCESS>run|ru|r     	{ BEGIN(ASTRING_EXPECTED); return tRUN;}
208
<INITIAL>detach|detac|deta|det   	{ BEGIN(NOCMD); return tDETACH; }
209
<INITIAL>kill|kil|ki|k                  { BEGIN(NOCMD); return tKILL; }
210
<INITIAL,NOPROCESS>maintenance|maint    { BEGIN(MAINT_CMD); return tMAINTENANCE; }
211
<INITIAL>minidump|mdmp                  { BEGIN(PATH_EXPECTED); return tMINIDUMP; }
212
<INITIAL>echo				{ BEGIN(ASTRING_EXPECTED); return tECHO; }
213
<NOPROCESS>attach|attac|atta|att 	{ BEGIN(NOCMD); return tATTACH; }
214 215
<INFO_CMD>share|shar|sha                { return tSHARE; }
<MAINT_CMD>module|modul|mod             { BEGIN(ASTRING_EXPECTED); return tMODULE; }
Alexandre Julliard's avatar
Alexandre Julliard committed
216
<INFO_CMD>locals|local|loca|loc		{ return tLOCAL; }
217 218 219 220
<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
221
<INFO_CMD>registers|regs|reg|re		{ return tREGS; }
222 223
<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
224
<INFO_CMD>segments|segment|segm|seg|se	{ return tSEGMENTS; }
225
<INFO_CMD>stack|stac|sta|st     	{ return tSTACK; }
226
<INFO_CMD>symbol|symbo|symb|sym         { BEGIN(ASTRING_EXPECTED); return tSYMBOL; }
227 228
<INFO_CMD>maps|map			{ return tMAPS; }
<INFO_CMD>window|windo|wind|win|wnd	{ return tWND; }
Alexandre Julliard's avatar
Alexandre Julliard committed
229
<HELP_CMD>info|inf|in                   { return tINFO; }
230
<MAINT_CMD>type                         { return tTYPE; }
Alexandre Julliard's avatar
Alexandre Julliard committed
231

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

Alexandre Julliard's avatar
Alexandre Julliard committed
235 236 237 238 239 240 241 242 243 244 245
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; }
246
all                                     { return tALL; }
Alexandre Julliard's avatar
Alexandre Julliard committed
247

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

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

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

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

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

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