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