debug.l 10.9 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
%{
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
#define YY_NO_UNISTD_H
Alexandre Julliard's avatar
Alexandre Julliard committed
31
#include "debugger.h"
32
#include "dbg.tab.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
33 34

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

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

70 71 72
    /* try first to fetch the remaining of an existing line */
    if (last_line_idx == 0)
    {
73
        char* tmp = NULL;
74 75
        /* no remaining chars to be read from last line, grab a brand new line up to '\n' */
        lexeme_flush();
76
        len = input_fetch_entire_line(pfx, &tmp);
77
        if (len < 0) return 0;  /* eof */
78 79 80 81 82 83 84 85 86

        /* remove carriage return in newline */
        if (len >= 2 && tmp[len - 2] == '\r')
        {
            tmp[len - 2] = '\n';
            tmp[len - 1] = '\0';
            len--;
        }

87 88 89
        /* FIXME: should have a pair of buffers, and switch between the two, instead of
         * reallocating a new one for each line
         */
90
        if (last_line && (len == 0 || (len == 1 && tmp[0] == '\n')))
91 92 93 94 95 96 97 98
        {
            HeapFree(GetProcessHeap(), 0, tmp);
        }
        else
        {
            HeapFree(GetProcessHeap(), 0, last_line);
            last_line = tmp;
        }
99 100 101 102 103 104 105 106 107
    }

    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;
}
108

Alexandre Julliard's avatar
Alexandre Julliard committed
109
#define YY_INPUT(buf,result,max_size) \
110
        (result = read_input("Wine-dbg>", buf, max_size))
Alexandre Julliard's avatar
Alexandre Julliard committed
111 112 113 114

static int syntax_error;
%}

115
OCTDIGIT   [0-7]
Alexandre Julliard's avatar
Alexandre Julliard committed
116 117
DIGIT	   [0-9]
HEXDIGIT   [0-9a-fA-F]
118
FORMAT     [ubcdgiswxa]
119
IDENTIFIER [_a-zA-Z~?][_a-zA-Z0-9~?@]*
120
PATHNAME   [\\/_a-zA-Z0-9\.~@][\\/\-_a-zA-Z0-9\.~@]*
Alexandre Julliard's avatar
Alexandre Julliard committed
121 122 123 124 125
STRING     \"[^\n"]+\"

%s FORMAT_EXPECTED
%s INFO_CMD
%s HELP_CMD
126 127
%s BD_CMD
%s LOCAL_CMD
Alexandre Julliard's avatar
Alexandre Julliard committed
128
%s SHOW_CMD
129
%s MODE_CMD
130
%s MAINT_CMD
131
%s NOCMD
132
%s PATH_ACCEPTED
Alexandre Julliard's avatar
Alexandre Julliard committed
133

134
%x PATH_EXPECTED
135 136
%x ASTRING_EXPECTED
%x NOPROCESS
Alexandre Julliard's avatar
Alexandre Julliard committed
137
%%
138
                                        /* set to special state when no process is loaded. */
139
                                        if (!dbg_num_processes() && YYSTATE == INITIAL) {BEGIN(NOPROCESS);}
140

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

158 159
"0x"{HEXDIGIT}+      			{ sscanf(yytext, "%lx", &dbg_lval.integer); return tNUM; }
{DIGIT}+             			{ sscanf(yytext, "%ld", &dbg_lval.integer); return tNUM; }
160 161 162 163 164
"'\\''"                                 { dbg_lval.integer = '\''; return tNUM;}
"'\\0"{OCTDIGIT}*"'"                    { sscanf(yytext + 3, "%lo", &dbg_lval.integer); return tNUM;}
"'\\x"{HEXDIGIT}+"'"                    { sscanf(yytext + 3, "%lx", &dbg_lval.integer); return tNUM;}
"'\\"[a-z]"'"                           { dbg_lval.integer = yytext[2] - 'a'; return tNUM;}
"'"."'"                                 { dbg_lval.integer = yytext[1]; return tNUM;}
165 166

<FORMAT_EXPECTED>"/"{DIGIT}+{FORMAT}	{ char* last;
167 168
                                          dbg_lval.integer = strtol(yytext+1, &last, 0) << 8;
                                          dbg_lval.integer |= *last;
169 170
                                          return tFORMAT; }

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

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

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

195 196
<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
197

198 199 200 201 202 203 204 205
<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
206

207
<INITIAL>abort|abor|abo         	{ BEGIN(NOCMD); return tABORT; }
Alexandre Julliard's avatar
Alexandre Julliard committed
208 209 210
<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
211
<INITIAL,NOPROCESS>source|sourc|sour|src { BEGIN(PATH_EXPECTED); return tSOURCE; }
212
<INITIAL>symbolfile|symbols|symbol|sf   { BEGIN(PATH_EXPECTED); return tSYMBOLFILE; }
Alexandre Julliard's avatar
Alexandre Julliard committed
213

214 215
<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; }
216
<INITIAL>watch|watc|wat			{ BEGIN(NOCMD); return tWATCH; }
217
<INITIAL>rwatch|rwatc|rwat		{ BEGIN(NOCMD); return tRWATCH; }
218
<INITIAL>whatis|whati|what		{ BEGIN(NOCMD); return tWHATIS; }
219
<INITIAL,NOPROCESS>run|ru|r     	{ BEGIN(ASTRING_EXPECTED); return tRUN;}
220
<INITIAL>detach|detac|deta|det   	{ BEGIN(NOCMD); return tDETACH; }
221
<INITIAL>kill|kil|ki|k                  { BEGIN(NOCMD); return tKILL; }
222
<INITIAL,NOPROCESS>maintenance|maint    { BEGIN(MAINT_CMD); return tMAINTENANCE; }
223
<INITIAL>minidump|mdmp                  { BEGIN(PATH_EXPECTED); return tMINIDUMP; }
224
<INITIAL>echo				{ BEGIN(ASTRING_EXPECTED); return tECHO; }
225
<NOPROCESS>attach|attac|atta|att 	{ BEGIN(NOCMD); return tATTACH; }
226 227
<INFO_CMD>share|shar|sha                { return tSHARE; }
<MAINT_CMD>module|modul|mod             { BEGIN(ASTRING_EXPECTED); return tMODULE; }
Alexandre Julliard's avatar
Alexandre Julliard committed
228
<INFO_CMD>locals|local|loca|loc		{ return tLOCAL; }
229 230 231 232
<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
233
<INFO_CMD>registers|regs|reg|re		{ return tREGS; }
234 235
<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
236
<INFO_CMD>segments|segment|segm|seg|se	{ return tSEGMENTS; }
237
<INFO_CMD>stack|stac|sta|st     	{ return tSTACK; }
238
<INFO_CMD>symbol|symbo|symb|sym         { BEGIN(ASTRING_EXPECTED); return tSYMBOL; }
239 240
<INFO_CMD>maps|map			{ return tMAPS; }
<INFO_CMD>window|windo|wind|win|wnd	{ return tWND; }
Alexandre Julliard's avatar
Alexandre Julliard committed
241
<HELP_CMD>info|inf|in                   { return tINFO; }
242
<MAINT_CMD>type                         { return tTYPE; }
Alexandre Julliard's avatar
Alexandre Julliard committed
243

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

Alexandre Julliard's avatar
Alexandre Julliard committed
247 248 249 250 251 252 253 254 255 256 257
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; }
258
all                                     { return tALL; }
Alexandre Julliard's avatar
Alexandre Julliard committed
259

260 261
{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
262

263 264 265 266
<PATH_EXPECTED,PATH_ACCEPTED>{PATHNAME}	{ dbg_lval.string = lexeme_alloc(yytext); return tPATH; }

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

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

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

273 274
#ifndef dbg_wrap
int dbg_wrap(void) { return 1; }
Alexandre Julliard's avatar
Alexandre Julliard committed
275
#endif