WineDbg and long input lines
Eric Pouech
eric.pouech at wanadoo.fr
Sun Jul 21 03:34:12 CDT 2002
after fixing the console routines for enabling edition on several lines,
winedbg input line code had to be fixed a bit
this patch takes care of it
A+
-------------- next part --------------
Name: dbg_readline
ChangeLog:
fixed very long line reading (and some buffering bugs)
removed the static limit in array for symbols parsing
License: X11
GenDate: 2002/07/21 08:28:30 UTC
ModifiedFiles: debugger/debug.l debugger/debugger.h debugger/hash.c debugger/source.c
AddedFiles:
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/debug.l,v
retrieving revision 1.28
diff -u -u -r1.28 debug.l
--- debugger/debug.l 10 Jul 2002 03:04:30 -0000 1.28
+++ debugger/debug.l 21 Jul 2002 08:28:28 -0000
@@ -28,8 +28,11 @@
#include "y.tab.h"
#undef YY_INPUT
+
+static int DEBUG_FetchFromLine(const char* pfx, char* buf, int size);
+
#define YY_INPUT(buf,result,max_size) \
- if ( (result = DEBUG_ReadLine("Wine-dbg>", buf, max_size, TRUE, TRUE)) <= 0 ) \
+ if ( (result = DEBUG_FetchFromLine("Wine-dbg>", buf, max_size)) <= 0 ) \
YY_FATAL_ERROR( "ReadLine() in flex scanner failed" );
@@ -188,95 +191,120 @@
/* Strip whitespace from the start and end of STRING. */
-static void stripwhite (char *string)
+static void stripwhite(char *string)
{
- register int i = 0;
-
- while (whitespace (string[i]))
- i++;
+ int i, last;
- if (i)
- strcpy (string, string + i);
+ for (i = 0; whitespace(string[i]); i++);
+ if (i) strcpy(string, string + i);
- i = strlen (string) - 1;
+ last = i = strlen(string) - 1;
+ if (string[last] == '\n') i--;
- while (i > 0 && whitespace (string[i]))
- i--;
-
- string[++i] = '\0';
+ while (i > 0 && whitespace(string[i])) i--;
+ if (string[last] == '\n')
+ string[++i] = '\n';
+ string[++i] = '\0';
}
-int DEBUG_ReadLine(const char* pfx, char * buf, int size, int flush_sym, int keep_hist)
+static int DEBUG_FetchEntireLine(const char* pfx, char** line, size_t* alloc, BOOL check_nl)
{
char buf_line[256];
- char* ptr;
- int len;
DWORD nread;
+ size_t len;
- for (;;)
- {
- if (flush_sym) DEBUG_FlushSymbols();
- /* as of today, console handles can be file handles... so better use file APIs rather than
- * consoles
- */
- WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pfx, strlen(pfx), &nread, NULL);
+ /* as of today, console handles can be file handles... so better use file APIs rather than
+ * consoles
+ */
+ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pfx, strlen(pfx), NULL, NULL);
- if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf_line, sizeof(buf_line), &nread, NULL))
+ len = 0;
+ do
+ {
+ if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf_line, sizeof(buf_line) - 1, &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);
-
- if (keep_hist)
- {
- 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 should also tweak with the undoc functions to remove this line from the console
- * history... */
- ptr = buf_line;
- }
+ buf_line[nread] = '\0';
- if ((len = strlen(ptr)) > 0)
+ if (check_nl && len == 0 && nread == 1 && buf_line[0] == '\n')
+ return 0;
+
+ /* store stuff at the end of last_line */
+ if (len + nread + 1 > *alloc)
{
- if (size < len + 1)
- {
- DEBUG_Printf(DBG_CHN_MESG, "Fatal readline goof.\n");
- DEBUG_Exit(0);
- }
- strcpy(buf, ptr);
- buf[len] = '\n';
- buf[len+1] = 0;
- return len + 1;
+ *line = HeapReAlloc(GetProcessHeap(), 0, *line, *alloc += nread + 1);
}
+ strcpy(*line + len, buf_line);
+ len += nread;
+ } while (nread == 0 || buf_line[nread - 1] != '\n');
+
+ /* Remove leading and trailing whitespace from the line */
+ stripwhite(*line);
+ return 1;
+}
+
+static int DEBUG_FetchFromLine(const char* pfx, char* buf, int size)
+{
+ size_t len;
+static char* last_line = NULL;
+static size_t last_line_size = 0;
+static size_t last_line_idx = 0;
+
+ /* first alloc of our current buffer */
+ if (!last_line)
+ {
+ last_line = HeapAlloc(GetProcessHeap(), 0, last_line_size = 2);
+ assert(last_line);
+ last_line[0] = '\n';
+ last_line[1] = '\0';
}
- return 0;
+
+ /* try first to fetch the remaining of an existing line */
+ if (last_line_idx == 0)
+ {
+ /* no remaining chars to be read from last line, grab a brand new line up to '\n' */
+ DEBUG_FlushSymbols();
+
+ DEBUG_FetchEntireLine(pfx, &last_line, &last_line_size, TRUE);
+ }
+
+ 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;
+}
+
+int DEBUG_ReadLine(const char* pfx, char* buf, int size)
+{
+ char* line = NULL;
+ size_t len = 0;
+
+ DEBUG_FetchEntireLine(pfx, &line, &len, FALSE);
+ len = min(size, len);
+ memcpy(buf, line, len - 1);
+ buf[len] = '\0';
+ return len - 1;
}
-static char *local_symbols[30];
-static int next_symbol;
+static char** local_symbols /* = NULL */;
+static int next_symbol /* = 0 */;
+static int alloc_symbol /* = 0 */;
-char * DEBUG_MakeSymbol(const char * symbol)
+char* DEBUG_MakeSymbol(const char* symbol)
{
- assert(0 <= next_symbol && next_symbol < (sizeof(local_symbols) / sizeof(local_symbols[0])));
- return local_symbols[next_symbol++] = DBG_strdup(symbol);
+ assert(0 <= next_symbol && next_symbol < alloc_symbol + 1);
+ if (next_symbol >= alloc_symbol)
+ {
+ local_symbols = HeapReAlloc(GetProcessHeap(), 0, local_symbols,
+ (alloc_symbol += 32) * sizeof(local_symbols[0]));
+ assert(local_symbols);
+ }
+ return local_symbols[next_symbol++] = DBG_strdup(symbol);
}
void DEBUG_FlushSymbols(void)
{
- while(--next_symbol >= 0) DBG_free(local_symbols[next_symbol]);
- next_symbol = 0;
+ while(--next_symbol >= 0) DBG_free(local_symbols[next_symbol]);
+ next_symbol = 0;
}
Index: debugger/debugger.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/debugger.h,v
retrieving revision 1.36
diff -u -u -r1.36 debugger.h
--- debugger/debugger.h 20 Jul 2002 20:18:17 -0000 1.36
+++ debugger/debugger.h 21 Jul 2002 06:09:53 -0000
@@ -312,7 +312,7 @@
/* 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 flush_sym, int keep_hist);
+extern int DEBUG_ReadLine(const char* pfx, char* buffer, int size);
/* debugger/display.c */
extern int DEBUG_DoDisplay(void);
Index: debugger/hash.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/hash.c,v
retrieving revision 1.31
diff -u -u -r1.31 hash.c
--- debugger/hash.c 20 Jul 2002 20:18:17 -0000 1.31
+++ debugger/hash.c 21 Jul 2002 06:09:53 -0000
@@ -427,7 +427,7 @@
}
do {
i = 0;
- if (DEBUG_ReadLine("=> ", buffer, sizeof(buffer), FALSE, FALSE))
+ if (DEBUG_ReadLine("=> ", buffer, sizeof(buffer)))
{
i = atoi(buffer);
if (i < 1 || i > num)
Index: debugger/source.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/debugger/source.c,v
retrieving revision 1.23
diff -u -u -r1.23 source.c
--- debugger/source.c 20 Jul 2002 20:18:17 -0000 1.23
+++ debugger/source.c 21 Jul 2002 06:09:53 -0000
@@ -203,7 +203,7 @@
* Still couldn't find it. Ask user for path to add.
*/
sprintf(zbuf, "Enter path to file '%s': ", sourcefile);
- DEBUG_ReadLine(zbuf, tmppath, sizeof(tmppath), FALSE, FALSE);
+ DEBUG_ReadLine(zbuf, tmppath, sizeof(tmppath));
if( tmppath[strlen(tmppath)-1] == '\n' )
{
More information about the wine-patches
mailing list