From d0a04935ceda0d9e35f8e7f7a47e76d65b0e47ab Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Fri, 23 Nov 2001 23:10:08 +0000 Subject: [PATCH] Revisited console support (got rid of old hacks and private editline since we now have a brand new console), removed private debug heap. --- debugger/Makefile.in | 1 - debugger/debug.l | 73 +-- debugger/debugger.h | 13 +- debugger/editline.c | 1249 ------------------------------------------ debugger/hash.c | 15 +- debugger/source.c | 2 +- debugger/winedbg.c | 58 +- 7 files changed, 93 insertions(+), 1318 deletions(-) delete mode 100644 debugger/editline.c diff --git a/debugger/Makefile.in b/debugger/Makefile.in index 43fabb8656a..f0c5b920451 100644 --- a/debugger/Makefile.in +++ b/debugger/Makefile.in @@ -9,7 +9,6 @@ C_SRCS = \ break.c \ db_disasm.c \ display.c \ - editline.c \ expr.c \ ext_debugger.c \ hash.c \ diff --git a/debugger/debug.l b/debugger/debug.l index 910d721a72c..6064c32464c 100644 --- a/debugger/debug.l +++ b/debugger/debug.l @@ -8,17 +8,17 @@ %{ #include #include +#include "winbase.h" +#include "wincon.h" #include "debugger.h" #include "y.tab.h" #ifndef DONT_USE_READLINE #undef YY_INPUT #define YY_INPUT(buf,result,max_size) \ - if ( (result = dbg_read((char *) buf, max_size )) < 0 ) \ + if ( (result = DEBUG_ReadLine("Wine-dbg>", (char *) buf, max_size, TRUE )) < 0 ) \ YY_FATAL_ERROR( "read() in flex scanner failed" ); -static int dbg_read(char * buf, int size); - #endif /* DONT_USE_READLINE */ #define YY_NO_UNPUT @@ -195,52 +195,61 @@ static void stripwhite (char *string) string[++i] = '\0'; } -static int dbg_read(char * buf, int size) +int DEBUG_ReadLine(const char* pfx, char * buf, int size, int remind) { - static char last_line[256] = ""; - char * line; - int len; - + char buf_line[256]; + char* ptr; + int len; + DWORD nread; + for (;;) { DEBUG_FlushSymbols(); - line = readline ("Wine-dbg>"); - if (!line) - { - DEBUG_Printf( DBG_CHN_MESG, "\n" ); - DEBUG_Exit(0); - } + WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), pfx, strlen(pfx), NULL, NULL); + + if (!ReadConsole(GetStdHandle(STD_INPUT_HANDLE), buf_line, sizeof(buf_line), &nread, NULL)) + break; + /* FIXME: should be rewritten not to remove and then add the trailing '\n' */ + if (nread > 0 && buf_line[nread - 1] == '\n') nread--; + buf_line[nread] = 0; /* Remove leading and trailing whitespace from the line */ + stripwhite (buf_line); - stripwhite (line); + if (remind) + { + static char last_line[256] = ""; + /* If there is anything left, add it to the history list + and execute it. Otherwise, re-execute last command. */ + + if (*buf_line) + { + strncpy( last_line, buf_line, sizeof(last_line) - 1 ); + last_line[sizeof(last_line) - 1] = '\0'; + } + ptr = last_line; + } + else + { + /* I could also tweak with the undoc functions to remove this line from the console + * history... */ + ptr = buf_line; + } - /* If there is anything left, add it to the history list - and execute it. Otherwise, re-execute last command. */ - - if (*line) + if ((len = strlen(ptr)) > 0) { - add_history( line ); - strncpy( last_line, line, 255 ); - last_line[255] = '\0'; - } - - free( line ); - line = last_line; - - if ((len = strlen(line)) > 0) - { - if (size < len + 1) + if (size < len + 1) { - DEBUG_Printf(DBG_CHN_MESG,"Fatal readline goof.\n"); + DEBUG_Printf(DBG_CHN_MESG, "Fatal readline goof.\n"); DEBUG_Exit(0); } - strcpy(buf, line); + strcpy(buf, ptr); buf[len] = '\n'; buf[len+1] = 0; return len + 1; } } + return 0; } static char *local_symbols[30]; diff --git a/debugger/debugger.h b/debugger/debugger.h index 567b9497b7e..3080d171a26 100644 --- a/debugger/debugger.h +++ b/debugger/debugger.h @@ -287,6 +287,7 @@ extern void DEBUG_Exit( DWORD ); /* debugger/debug.l */ extern void DEBUG_FlushSymbols(void); extern char*DEBUG_MakeSymbol(const char*); +extern int DEBUG_ReadLine(const char* pfx, char* buffer, int size, int remind); /* debugger/display.c */ extern int DEBUG_DoDisplay(void); @@ -512,13 +513,11 @@ extern char* DEBUG_XStrDup(const char *str); #define DBG_strdup(x) DEBUG_XStrDup(x) #else /* this one is slow (takes 5 minutes to load the debugger on my machine), - but is pretty crash-proof (can step through malloc() without problems, - malloc() arena (and other heaps) can be totally wasted and it'll still - work, etc... if someone could make optimized routines so it wouldn't + if someone could make optimized routines so it wouldn't take so long to load, it could be made default) */ -#define DBG_alloc(x) HeapAlloc(dbg_heap,0,x) -#define DBG_realloc(x,y) HeapRealloc(dbg_heap,0,x,y) -#define DBG_free(x) HeapFree(dbg_heap,0,x) +#define DBG_alloc(x) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,x) +#define DBG_realloc(x,y) HeapReAlloc(GetProcessHeap(),0,x,y) +#define DBG_free(x) HeapFree(GetProcessHeap(),0,x) inline static LPSTR DBG_strdup( LPCSTR str ) { INT len = strlen(str) + 1; @@ -526,8 +525,6 @@ inline static LPSTR DBG_strdup( LPCSTR str ) if (p) memcpy( p, str, len ); return p; } -#define DBG_need_heap -extern HANDLE dbg_heap; #endif #define DEBUG_STATUS_OFFSET 0x80003000 diff --git a/debugger/editline.c b/debugger/editline.c deleted file mode 100644 index 50ae04d7580..00000000000 --- a/debugger/editline.c +++ /dev/null @@ -1,1249 +0,0 @@ -/* - * Line-editing routines - * - * Copyright 1992 Simmule Turner and Rich Salz. All rights reserved. - * - * - * This software is not subject to any license of the American Telephone - * and Telegraph Company or of the Regents of the University of California. - * - * Permission is granted to anyone to use this software for any purpose on - * any computer system, and to alter it and redistribute it freely, subject - * to the following restrictions: - * 1. The authors are not responsible for the consequences of use of this - * software, no matter how awful, even if they arise from flaws in it. - * 2. The origin of this software must not be misrepresented, either by - * explicit claim or by omission. Since few users ever read sources, - * credits must appear in the documentation. - * 3. Altered versions must be plainly marked as such, and must not be - * misrepresented as being the original software. Since few users - * ever read sources, credits must appear in the documentation. - * 4. This notice may not be removed or altered. - * - * The code was heavily simplified for inclusion in Wine. -- AJ - */ - -#include "config.h" -#include -#include -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "wincon.h" -#include "debugger.h" - -/* -** Manifest constants. -*/ -#define SCREEN_WIDTH 80 -#define SCREEN_ROWS 24 -#define NO_ARG (-1) -#define DEL 127 -#define CTL(x) ((x) & 0x1F) -#define ISCTL(x) ((x) && (x) < ' ') -#define UNCTL(x) ((x) + 64) -#define META(x) ((x) | 0x80) -#define ISMETA(x) ((x) & 0x80) -#define UNMETA(x) ((x) & 0x7F) -#if !defined(HIST_SIZE) -#define HIST_SIZE 20 -#endif /* !defined(HIST_SIZE) */ -#define CRLF "\r\n" -#define MEM_INC 64 -#define SCREEN_INC 256 - -#define DISPOSE(p) DBG_free((char *)(p)) -#define NEW(T, c) \ - ((T *)DBG_alloc((unsigned int)(sizeof (T) * (c)))) -#define RENEW(p, T, c) \ - (p = (T *)DBG_realloc((char *)(p), (unsigned int)(sizeof (T) * (c)))) -#define COPYFROMTO(new, p, len) \ - (void)memcpy((char *)(new), (char *)(p), (int)(len)) - -/* -** Command status codes. -*/ -typedef enum _STATUS { - CSdone, CSeof, CSmove, CSdispatch, CSstay -} STATUS; - -/* -** The type of case-changing to perform. -*/ -typedef enum _CASE { - TOupper, TOlower -} CASE; - -/* -** Key to command mapping. -*/ -typedef struct _KEYMAP { - CHAR Key; - STATUS (*Function)(); -} KEYMAP; - -/* -** Command history structure. -*/ -typedef struct _HISTORY { - int Size; - int Pos; - CHAR *Lines[HIST_SIZE]; -} HISTORY; - -/* -** Globals. -*/ -static int rl_eof; -static int rl_erase; -static int rl_intr; -static int rl_kill; - -static CHAR NIL[] = ""; -static const CHAR *Input = NIL; -static CHAR *Line; -static const char *Prompt; -static CHAR *Yanked; -static char *Screen; -static char NEWLINE[]= CRLF; -static HISTORY H; -static int rl_quit; -static int Repeat; -static int End; -static int Mark; -static int OldPoint; -static int Point; -static int PushBack; -static int Pushed; -static KEYMAP Map[33]; -static KEYMAP MetaMap[16]; -static size_t Length; -static size_t ScreenCount; -static size_t ScreenSize; -static char *backspace; -static int TTYwidth; -static int TTYrows; - -/* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */ -int rl_meta_chars = 1; - -/* -** Declarations. -*/ -static CHAR *editinput(); - -/* -** TTY input/output functions. -*/ - -static void -rl_ttyset(int Reset) -{ - static DWORD old_mode; - - if (Reset == 0) { - GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &old_mode); - SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0 /*ENABLE_PROCESSED_INPUT|ENABLE_WINDOW_INPUT|ENABLE_MOUSE_INPUT*/); - } else { - SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), old_mode); - } -} - -static void -TTYflush(void) -{ - if (ScreenCount) { - DEBUG_Output(DBG_CHN_MESG, Screen, ScreenCount); - ScreenCount = 0; - } -} - -static void -TTYput(CHAR c) -{ - Screen[ScreenCount] = c; - if (++ScreenCount >= ScreenSize - 1) { - ScreenSize += SCREEN_INC; - RENEW(Screen, char, ScreenSize); - } -} - -static void -TTYputs(CHAR *p) -{ - while (*p) - TTYput(*p++); -} - -static void -TTYshow(CHAR c) -{ - if (c == DEL) { - TTYput('^'); - TTYput('?'); - } - else if (ISCTL(c)) { - TTYput('^'); - TTYput(UNCTL(c)); - } - else if (rl_meta_chars && ISMETA(c)) { - TTYput('M'); - TTYput('-'); - TTYput(UNMETA(c)); - } - else - TTYput(c); -} - -static void -TTYstring(CHAR *p) -{ - while (*p) - TTYshow(*p++); -} - -static unsigned int -TTYget(void) -{ - CHAR c; - DWORD retv; - - TTYflush(); - if (Pushed) { - Pushed = 0; - return PushBack; - } - if (*Input) - return *Input++; - - for (;;) { - /* data available ? */ - if (ReadConsole(GetStdHandle(STD_INPUT_HANDLE), &c, 1, &retv, NULL) && - retv == 1) - return c; - switch (WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), INFINITE)) { - case WAIT_OBJECT_0: - break; - default: - DEBUG_Printf(DBG_CHN_FIXME, "shouldn't happen\n"); - /* fall through */ - case WAIT_ABANDONED: - case WAIT_TIMEOUT: - return EOF; - } - } -} - -#define TTYback() (backspace ? TTYputs((CHAR *)backspace) : TTYput('\b')) - -static void -TTYbackn(int n) -{ - while (--n >= 0) - TTYback(); -} - -static void -TTYinfo(void) -{ - COORD c = GetLargestConsoleWindowSize(GetStdHandle(STD_INPUT_HANDLE)); - TTYwidth = c.X; - TTYrows = c.Y; -} - - - -static void -reposition(void) -{ - int i; - CHAR *p; - - TTYput('\r'); - TTYputs((CHAR *)Prompt); - for (i = Point, p = Line; --i >= 0; p++) - TTYshow(*p); -} - -static void -left(STATUS Change) -{ - TTYback(); - if (Point) { - if (ISCTL(Line[Point - 1])) - TTYback(); - else if (rl_meta_chars && ISMETA(Line[Point - 1])) { - TTYback(); - TTYback(); - } - } - if (Change == CSmove) - Point--; -} - -static void -right(STATUS Change) -{ - TTYshow(Line[Point]); - if (Change == CSmove) - Point++; -} - -static STATUS -ring_bell(void) -{ - TTYput('\07'); - TTYflush(); - return CSstay; -} - -static STATUS -do_macro(unsigned int c) -{ - CHAR name[4]; - - name[0] = '_'; - name[1] = c; - name[2] = '_'; - name[3] = '\0'; - - if ((Input = (CHAR *)getenv((char *)name)) == NULL) { - Input = NIL; - return ring_bell(); - } - return CSstay; -} - -static STATUS -do_forward(STATUS move) -{ - int i; - CHAR *p; - - i = 0; - do { - p = &Line[Point]; - for ( ; Point < End && (*p == ' ' || !isalnum(*p)); Point++, p++) - if (move == CSmove) - right(CSstay); - - for (; Point < End && isalnum(*p); Point++, p++) - if (move == CSmove) - right(CSstay); - - if (Point == End) - break; - } while (++i < Repeat); - - return CSstay; -} - -static STATUS -do_case(CASE type) -{ - int i; - int end; - int count; - CHAR *p; - - (void)do_forward(CSstay); - if (OldPoint != Point) { - if ((count = Point - OldPoint) < 0) - count = -count; - Point = OldPoint; - if ((end = Point + count) > End) - end = End; - for (i = Point, p = &Line[i]; i < end; i++, p++) { - if (type == TOupper) { - if (islower(*p)) - *p = toupper(*p); - } - else if (isupper(*p)) - *p = tolower(*p); - right(CSmove); - } - } - return CSstay; -} - -static STATUS -case_down_word(void) -{ - return do_case(TOlower); -} - -static STATUS -case_up_word(void) -{ - return do_case(TOupper); -} - -static void -ceol(void) -{ - int extras; - int i; - CHAR *p; - - for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) { - TTYput(' '); - if (ISCTL(*p)) { - TTYput(' '); - extras++; - } - else if (rl_meta_chars && ISMETA(*p)) { - TTYput(' '); - TTYput(' '); - extras += 2; - } - } - - for (i += extras; i > Point; i--) - TTYback(); -} - -static void -clear_line(void) -{ - Point = -strlen(Prompt); - TTYput('\r'); - ceol(); - Point = 0; - End = 0; - Line[0] = '\0'; -} - -static STATUS -insert_string(CHAR *p) -{ - size_t len; - int i; - CHAR *new; - CHAR *q; - - len = strlen((char *)p); - if (End + len >= Length) { - if ((new = NEW(CHAR, Length + len + MEM_INC)) == NULL) - return CSstay; - if (Length) { - COPYFROMTO(new, Line, Length); - DISPOSE(Line); - } - Line = new; - Length += len + MEM_INC; - } - - for (q = &Line[Point], i = End - Point; --i >= 0; ) - q[len + i] = q[i]; - COPYFROMTO(&Line[Point], p, len); - End += len; - Line[End] = '\0'; - TTYstring(&Line[Point]); - Point += len; - - return Point == End ? CSstay : CSmove; -} - - -static CHAR * -next_hist(void) -{ - return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos]; -} - -static CHAR * -prev_hist() -{ - return H.Pos == 0 ? NULL : H.Lines[--H.Pos]; -} - -static STATUS -do_insert_hist(CHAR *p) -{ - if (p == NULL) - return ring_bell(); - Point = 0; - reposition(); - ceol(); - End = 0; - return insert_string(p); -} - -static STATUS -do_hist(CHAR *(*move)(void)) -{ - CHAR *p; - int i; - - i = 0; - do { - if ((p = (*move)()) == NULL) - return ring_bell(); - } while (++i < Repeat); - return do_insert_hist(p); -} - -static STATUS -h_next(void) -{ - return do_hist(next_hist); -} - -static STATUS -h_prev(void) -{ - return do_hist(prev_hist); -} - -static STATUS -h_first(void) -{ - return do_insert_hist(H.Lines[H.Pos = 0]); -} - -static STATUS -h_last(void) -{ - return do_insert_hist(H.Lines[H.Pos = H.Size - 1]); -} - -/* -** Return zero if pat appears as a substring in text. -*/ -static int -substrcmp(char *text, char *pat, int len) -{ - CHAR c; - - if ((c = *pat) == '\0') - return *text == '\0'; - for ( ; *text; text++) - if ((CHAR)*text == c && strncmp(text, pat, len) == 0) - return 0; - return 1; -} - -static CHAR * -search_hist(CHAR *search, CHAR *(*move)(void)) -{ - static CHAR *old_search; - int len; - int pos; - int (*match)(); - char *pat; - - /* Save or get remembered search pattern. */ - if (search && *search) { - if (old_search) - DISPOSE(old_search); - old_search = (CHAR *)DBG_strdup((char *)search); - } - else { - if (old_search == NULL || *old_search == '\0') - return NULL; - search = old_search; - } - - /* Set up pattern-finder. */ - if (*search == '^') { - match = strncmp; - pat = (char *)(search + 1); - } - else { - match = substrcmp; - pat = (char *)search; - } - len = strlen(pat); - - for (pos = H.Pos; (*move)() != NULL; ) - if ((*match)((char *)H.Lines[H.Pos], pat, len) == 0) - return H.Lines[H.Pos]; - H.Pos = pos; - return NULL; -} - -static STATUS -h_search(void) -{ - static int Searching; - const char *old_prompt; - CHAR *(*move)(); - CHAR *p; - - if (Searching) - return ring_bell(); - Searching = 1; - - clear_line(); - old_prompt = Prompt; - Prompt = "Search: "; - TTYputs((CHAR *)Prompt); - move = Repeat == NO_ARG ? prev_hist : next_hist; - p = search_hist(editinput(), move); - clear_line(); - Prompt = old_prompt; - TTYputs((CHAR *)Prompt); - - Searching = 0; - return do_insert_hist(p); -} - -static STATUS -fd_char(void) -{ - int i; - - i = 0; - do { - if (Point >= End) - break; - right(CSmove); - } while (++i < Repeat); - return CSstay; -} - -static void -save_yank(int begin, int i) -{ - if (Yanked) { - DISPOSE(Yanked); - Yanked = NULL; - } - - if (i < 1) - return; - - if ((Yanked = NEW(CHAR, (size_t)i + 1)) != NULL) { - COPYFROMTO(Yanked, &Line[begin], i); - Yanked[i] = '\0'; - } -} - -static STATUS -delete_string(int count) -{ - int i; - CHAR *p; - - if (count <= 0 || End == Point) - return ring_bell(); - - if (count == 1 && Point == End - 1) { - /* Optimize common case of delete at end of line. */ - End--; - p = &Line[Point]; - i = 1; - TTYput(' '); - if (ISCTL(*p)) { - i = 2; - TTYput(' '); - } - else if (rl_meta_chars && ISMETA(*p)) { - i = 3; - TTYput(' '); - TTYput(' '); - } - TTYbackn(i); - *p = '\0'; - return CSmove; - } - if (Point + count > End && (count = End - Point) <= 0) - return CSstay; - - if (count > 1) - save_yank(Point, count); - - for (p = &Line[Point], i = End - (Point + count) + 1; --i >= 0; p++) - p[0] = p[count]; - ceol(); - End -= count; - TTYstring(&Line[Point]); - return CSmove; -} - -static STATUS -bk_char(void) -{ - int i; - - i = 0; - do { - if (Point == 0) - break; - left(CSmove); - } while (++i < Repeat); - - return CSstay; -} - -static STATUS -bk_del_char(void) -{ - int i; - - i = 0; - do { - if (Point == 0) - break; - left(CSmove); - } while (++i < Repeat); - - return delete_string(i); -} - -static STATUS -redisplay(void) -{ - TTYputs((CHAR *)NEWLINE); - TTYputs((CHAR *)Prompt); - TTYstring(Line); - return CSmove; -} - -static STATUS -kill_line(void) -{ - int i; - - if (Repeat != NO_ARG) { - if (Repeat < Point) { - i = Point; - Point = Repeat; - reposition(); - (void)delete_string(i - Point); - } - else if (Repeat > Point) { - right(CSmove); - (void)delete_string(Repeat - Point - 1); - } - return CSmove; - } - - save_yank(Point, End - Point); - Line[Point] = '\0'; - ceol(); - End = Point; - return CSstay; -} - -static STATUS -insert_char(int c) -{ - STATUS s; - CHAR buff[2]; - CHAR *p; - CHAR *q; - int i; - - if (Repeat == NO_ARG || Repeat < 2) { - buff[0] = c; - buff[1] = '\0'; - return insert_string(buff); - } - - if ((p = NEW(CHAR, Repeat + 1)) == NULL) - return CSstay; - for (i = Repeat, q = p; --i >= 0; ) - *q++ = c; - *q = '\0'; - Repeat = 0; - s = insert_string(p); - DISPOSE(p); - return s; -} - -static STATUS -meta(void) -{ - unsigned int c; - KEYMAP *kp; - - if ((c = TTYget()) == EOF) - return CSeof; - /* Also include VT-100 arrows. */ - if (c == '[' || c == 'O') - switch (c = TTYget()) { - default: return ring_bell(); - case EOF: return CSeof; - case 'A': return h_prev(); - case 'B': return h_next(); - case 'C': return fd_char(); - case 'D': return bk_char(); - } - - if (isdigit(c)) { - for (Repeat = c - '0'; (c = TTYget()) != EOF && isdigit(c); ) - Repeat = Repeat * 10 + c - '0'; - Pushed = 1; - PushBack = c; - return CSstay; - } - - if (isupper(c)) - return do_macro(c); - for (OldPoint = Point, kp = MetaMap; kp->Function; kp++) - if (kp->Key == c) - return (*kp->Function)(); - - return ring_bell(); -} - -static STATUS -emacs(unsigned int c) -{ - STATUS s; - KEYMAP *kp; - - if (ISMETA(c)) { - Pushed = 1; - PushBack = UNMETA(c); - return meta(); - } - for (kp = Map; kp->Function; kp++) - if (kp->Key == c) - break; - s = kp->Function ? (*kp->Function)() : insert_char((int)c); - if (!Pushed) - /* No pushback means no repeat count; hacky, but true. */ - Repeat = NO_ARG; - return s; -} - -static STATUS -TTYspecial(unsigned int c) -{ - if (ISMETA(c)) - return CSdispatch; - - if (c == rl_erase || c == DEL) - return bk_del_char(); - if (c == rl_kill) { - if (Point != 0) { - Point = 0; - reposition(); - } - Repeat = NO_ARG; - return kill_line(); - } - if (c == rl_intr || c == rl_quit) { - Point = End = 0; - Line[0] = '\0'; - return redisplay(); - } - if (c == rl_eof && Point == 0 && End == 0) - return CSeof; - - return CSdispatch; -} - -static CHAR * -editinput(void) -{ - unsigned int c; - - Repeat = NO_ARG; - OldPoint = Point = Mark = End = 0; - Line[0] = '\0'; - - while ((c = TTYget()) != EOF) - switch (TTYspecial(c)) { - case CSdone: - return Line; - case CSeof: - return NULL; - case CSmove: - reposition(); - break; - case CSdispatch: - switch (emacs(c)) { - case CSdone: - return Line; - case CSeof: - return NULL; - case CSmove: - reposition(); - break; - case CSdispatch: - case CSstay: - break; - } - break; - case CSstay: - break; - } - return NULL; -} - -static void -hist_add(CHAR *p) -{ - int i; - - if ((p = (CHAR *)DBG_strdup((char *)p)) == NULL) - return; - if (H.Size < HIST_SIZE) - H.Lines[H.Size++] = p; - else { - DISPOSE(H.Lines[0]); - for (i = 0; i < HIST_SIZE - 1; i++) - H.Lines[i] = H.Lines[i + 1]; - H.Lines[i] = p; - } - H.Pos = H.Size - 1; -} - -char * -readline(const char *prompt) -{ - CHAR *line; - - if (Line == NULL) { - Length = MEM_INC; - if ((Line = NEW(CHAR, Length)) == NULL) - return NULL; - } - - TTYinfo(); - rl_ttyset(0); - hist_add(NIL); - ScreenSize = SCREEN_INC; - Screen = NEW(char, ScreenSize); - Prompt = prompt ? prompt : (char *)NIL; - TTYputs((CHAR *)Prompt); - if ((line = editinput()) != NULL) { - line = (CHAR *)DBG_strdup((char *)line); - TTYputs((CHAR *)NEWLINE); - TTYflush(); - } - rl_ttyset(1); - DISPOSE(Screen); - DISPOSE(H.Lines[--H.Size]); - return (char *)line; -} - -void -add_history(char *p) -{ - if (p == NULL || *p == '\0') - return; - -#if defined(UNIQUE_HISTORY) - if (H.Pos && strcmp(p, H.Lines[H.Pos - 1]) == 0) - return; -#endif /* defined(UNIQUE_HISTORY) */ - hist_add((CHAR *)p); -} - - -static STATUS -beg_line(void) -{ - if (Point) { - Point = 0; - return CSmove; - } - return CSstay; -} - -static STATUS -del_char(void) -{ - return delete_string(Repeat == NO_ARG ? 1 : Repeat); -} - -static STATUS -end_line(void) -{ - if (Point != End) { - Point = End; - return CSmove; - } - return CSstay; -} - -static STATUS -accept_line(void) -{ - Line[End] = '\0'; - return CSdone; -} - -static STATUS -transpose(void) -{ - CHAR c; - - if (Point) { - if (Point == End) - left(CSmove); - c = Line[Point - 1]; - left(CSstay); - Line[Point - 1] = Line[Point]; - TTYshow(Line[Point - 1]); - Line[Point++] = c; - TTYshow(c); - } - return CSstay; -} - -static STATUS -quote(void) -{ - unsigned int c; - - return (c = TTYget()) == EOF ? CSeof : insert_char((int)c); -} - -static STATUS -wipe(void) -{ - int i; - - if (Mark > End) - return ring_bell(); - - if (Point > Mark) { - i = Point; - Point = Mark; - Mark = i; - reposition(); - } - - return delete_string(Mark - Point); -} - -static STATUS -mk_set(void) -{ - Mark = Point; - return CSstay; -} - -static STATUS -exchange(void) -{ - unsigned int c; - - if ((c = TTYget()) != CTL('X')) - return c == EOF ? CSeof : ring_bell(); - - if ((c = Mark) <= End) { - Mark = Point; - Point = c; - return CSmove; - } - return CSstay; -} - -static STATUS -yank(void) -{ - if (Yanked && *Yanked) - return insert_string(Yanked); - return CSstay; -} - -static STATUS -copy_region(void) -{ - if (Mark > End) - return ring_bell(); - - if (Point > Mark) - save_yank(Mark, Point - Mark); - else - save_yank(Point, Mark - Point); - - return CSstay; -} - -static STATUS -move_to_char(void) -{ - unsigned int c; - int i; - CHAR *p; - - if ((c = TTYget()) == EOF) - return CSeof; - for (i = Point + 1, p = &Line[i]; i < End; i++, p++) - if (*p == c) { - Point = i; - return CSmove; - } - return CSstay; -} - -static STATUS -fd_word(void) -{ - return do_forward(CSmove); -} - -static STATUS -fd_kill_word(void) -{ - int i; - - (void)do_forward(CSstay); - if (OldPoint != Point) { - i = Point - OldPoint; - Point = OldPoint; - return delete_string(i); - } - return CSstay; -} - -static STATUS -bk_word(void) -{ - int i; - CHAR *p; - - i = 0; - do { - for (p = &Line[Point]; p > Line && !isalnum(p[-1]); p--) - left(CSmove); - - for (; p > Line && p[-1] != ' ' && isalnum(p[-1]); p--) - left(CSmove); - - if (Point == 0) - break; - } while (++i < Repeat); - - return CSstay; -} - -static STATUS -bk_kill_word(void) -{ - (void)bk_word(); - if (OldPoint != Point) - return delete_string(OldPoint - Point); - return CSstay; -} - -static int -argify(CHAR *line, CHAR ***avp) -{ - CHAR *c; - CHAR **p; - CHAR **new; - int ac; - int i; - - i = MEM_INC; - if ((*avp = p = NEW(CHAR*, i))== NULL) - return 0; - - for (c = line; isspace(*c); c++) - continue; - if (*c == '\n' || *c == '\0') - return 0; - - for (ac = 0, p[ac++] = c; *c && *c != '\n'; ) { - if (isspace(*c)) { - *c++ = '\0'; - if (*c && *c != '\n') { - if (ac + 1 == i) { - new = NEW(CHAR*, i + MEM_INC); - if (new == NULL) { - p[ac] = NULL; - return ac; - } - COPYFROMTO(new, p, i * sizeof (char **)); - i += MEM_INC; - DISPOSE(p); - *avp = p = new; - } - p[ac++] = c; - } - } - else - c++; - } - *c = '\0'; - p[ac] = NULL; - return ac; -} - -static STATUS -last_argument(void) -{ - CHAR **av; - CHAR *p; - STATUS s; - int ac; - - if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL) - return ring_bell(); - - if ((p = (CHAR *)DBG_strdup((char *)p)) == NULL) - return CSstay; - ac = argify(p, &av); - - if (Repeat != NO_ARG) - s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell(); - else - s = ac ? insert_string(av[ac - 1]) : CSstay; - - if (ac) - DISPOSE(av); - DISPOSE(p); - return s; -} - -static KEYMAP Map[33] = { - { CTL('@'), ring_bell }, - { CTL('A'), beg_line }, - { CTL('B'), bk_char }, - { CTL('D'), del_char }, - { CTL('E'), end_line }, - { CTL('F'), fd_char }, - { CTL('G'), ring_bell }, - { CTL('H'), bk_del_char }, - { CTL('I'), ring_bell }, - { CTL('J'), accept_line }, - { CTL('K'), kill_line }, - { CTL('L'), redisplay }, - { CTL('M'), accept_line }, - { CTL('N'), h_next }, - { CTL('O'), ring_bell }, - { CTL('P'), h_prev }, - { CTL('Q'), ring_bell }, - { CTL('R'), h_search }, - { CTL('S'), ring_bell }, - { CTL('T'), transpose }, - { CTL('U'), ring_bell }, - { CTL('V'), quote }, - { CTL('W'), wipe }, - { CTL('X'), exchange }, - { CTL('Y'), yank }, - { CTL('Z'), ring_bell }, - { CTL('['), meta }, - { CTL(']'), move_to_char }, - { CTL('^'), ring_bell }, - { CTL('_'), ring_bell }, - { 0, NULL } -}; - -static KEYMAP MetaMap[16]= { - { CTL('H'), bk_kill_word }, - { DEL, bk_kill_word }, - { ' ', mk_set }, - { '.', last_argument }, - { '<', h_first }, - { '>', h_last }, - { '?', ring_bell }, - { 'b', bk_word }, - { 'd', fd_kill_word }, - { 'f', fd_word }, - { 'l', case_down_word }, - { 'u', case_up_word }, - { 'y', yank }, - { 'w', copy_region }, - { 0, NULL } -}; diff --git a/debugger/hash.c b/debugger/hash.c index d19355ba2ea..6ea1c4799dd 100644 --- a/debugger/hash.c +++ b/debugger/hash.c @@ -387,7 +387,8 @@ BOOL DEBUG_GetSymbolValue( const char * name, const int lineno, } else if (!DEBUG_interactiveP || num == 1) { i = 0; } else { - char* ptr; + char buffer[256]; + if (num == NUMDBGV+1) { DEBUG_Printf(DBG_CHN_MESG, "Too many addresses for symbol '%s', limiting the first %d\n", name, NUMDBGV); num = NUMDBGV; @@ -399,11 +400,13 @@ BOOL DEBUG_GetSymbolValue( const char * name, const int lineno, DEBUG_Printf(DBG_CHN_MESG, "\n"); } do { - ptr = readline("=> "); - if (!*ptr) return FALSE; - i = atoi(ptr); - if (i < 1 || i > num) - DEBUG_Printf(DBG_CHN_MESG, "Invalid choice %d\n", i); + i = 0; + if (DEBUG_ReadLine("=> ", buffer, sizeof(buffer), FALSE)) + { + i = atoi(buffer); + if (i < 1 || i > num) + DEBUG_Printf(DBG_CHN_MESG, "Invalid choice %d\n", i); + } } while (i < 1 || i > num); /* The array is 0-based, but the choices are 1..n, so we have to subtract one before returning. */ diff --git a/debugger/source.c b/debugger/source.c index 7ec9020706a..ec5b1d0913b 100644 --- a/debugger/source.c +++ b/debugger/source.c @@ -188,7 +188,7 @@ DEBUG_DisplaySource(char * sourcefile, int start, int end) * Still couldn't find it. Ask user for path to add. */ sprintf(zbuf, "Enter path to file '%s': ", sourcefile); - lstrcpynA(tmppath, readline(zbuf), sizeof(tmppath)); + DEBUG_ReadLine(zbuf, tmppath, sizeof(tmppath), FALSE); if( tmppath[strlen(tmppath)-1] == '\n' ) { diff --git a/debugger/winedbg.c b/debugger/winedbg.c index 74104fb130b..b8c2b5d2109 100644 --- a/debugger/winedbg.c +++ b/debugger/winedbg.c @@ -19,10 +19,6 @@ #include "winreg.h" -#ifdef DBG_need_heap -HANDLE dbg_heap = 0; -#endif - DBG_PROCESS* DEBUG_CurrProcess = NULL; DBG_THREAD* DEBUG_CurrThread = NULL; DWORD DEBUG_CurrTid; @@ -464,6 +460,9 @@ static BOOL DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL case EXCEPTION_DATATYPE_MISALIGNMENT: DEBUG_Printf(DBG_CHN_MESG, "Alignment"); break; + case DBG_CONTROL_C: + DEBUG_Printf(DBG_CHN_MESG, "^C"); + break; case CONTROL_C_EXIT: DEBUG_Printf(DBG_CHN_MESG, "^C"); break; @@ -863,7 +862,7 @@ static BOOL DEBUG_Start(LPSTR cmdLine) startup.wShowWindow = SW_SHOWNORMAL; if (!CreateProcess(NULL, cmdLine, NULL, NULL, - FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) { + FALSE, DEBUG_PROCESS|DETACHED_PROCESS, NULL, NULL, &startup, &info)) { DEBUG_Printf(DBG_CHN_MESG, "Couldn't start process '%s'\n", cmdLine); return FALSE; } @@ -889,15 +888,41 @@ void DEBUG_Run(const char* args) } } +static void DEBUG_InitConsole(void) +{ + COORD c; + SMALL_RECT sr; + DWORD mode; + + /* keep it as a cuiexe for now, so that Wine won't touch the Unix stdin, + * stdout and stderr streams + */ + if (DBG_IVAR(UseXTerm)) + { + FreeConsole(); + AllocConsole(); + } + /* this would be nicer for output */ + c.X = 132; + c.Y = 500; + SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), c); + + /* sets the console's window width accordingly */ + sr.Left = 0; + sr.Top = 0; + sr.Right = c.X - 1; + sr.Bottom = 50; + SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &sr); + + /* put the line editing mode with the nice emacs features (FIXME: could be triggered by a IVAR) */ + if (GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode)) + SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode | WINE_ENABLE_LINE_INPUT_EMACS); +} + int DEBUG_main(int argc, char** argv) { DWORD retv = 0; -#ifdef DBG_need_heap - /* Initialize the debugger heap. */ - dbg_heap = HeapCreate(HEAP_NO_SERIALIZE, 0x1000, 0x8000000); /* 128MB */ -#endif - /* Initialize the type handling stuff. */ DEBUG_InitTypes(); DEBUG_InitCVDataTypes(); @@ -917,17 +942,8 @@ int DEBUG_main(int argc, char** argv) DBG_IVAR(StdChannelMask) = DBG_CHN_MESG; } - /* keep it as a guiexe for now, so that Wine won't touch the Unix stdin, - * stdout and stderr streams - */ - if (DBG_IVAR(UseXTerm)) { - COORD pos; - - /* This is a hack: it forces creation of an xterm, not done by default */ - pos.X = 0; pos.Y = 1; - SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); - } - + DEBUG_InitConsole(); + DEBUG_Printf(DBG_CHN_MESG, "WineDbg starting... "); if (argc == 3) {