- Enhanced internal variables framework (including read/save to
  registry and typing)
- Finalized use of Windows' Console I/O interface (instead of Unix std
  streams)
- Now handling registers as internal variables (they are no longer
  seen as a specific type)

diff --git a/debugger/winedbg.c b/debugger/winedbg.c
index 0bdc6d5..16cce68 100644
--- a/debugger/winedbg.c
+++ b/debugger/winedbg.c
@@ -26,47 +26,80 @@
 CONTEXT		DEBUG_context;
 
 static DBG_PROCESS* proc = NULL;
+DBG_INTVAR DEBUG_IntVars[DBG_IV_LAST];
 
-/* build internal vars table */
-#define  INTERNAL_VAR(_var,_val) int DBG_IVAR(_var) = _val;
-#include "intvar.h"
-#undef   INTERNAL_VAR
+void	DEBUG_Output(int chn, const char* buffer, int len)
+{
+    if (DBG_IVAR(ConChannelMask) & chn)
+	WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL);
+    if (DBG_IVAR(StdChannelMask) & chn)
+	fwrite(buffer, len, 1, stderr);
+}
 
 int	DEBUG_Printf(int chn, const char* format, ...)
 {
     char	buf[1024];
     va_list 	valist;
+    int		len;
 
     va_start(valist, format);
-    vsprintf(buf, format, valist);
+    len = vsprintf(buf, format, valist);
     va_end(valist);
-#if 0
-    if (DBG_IVAR(ChannelMask) & chn)
-	WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, strlen(buf), NULL, NULL);
-    if (chn == DBG_CHN_MESG) fwrite(buf, strlen(buf), 1, stderr);
-#else
-    if (DBG_IVAR(ChannelMask) & chn) fwrite(buf, strlen(buf), 1, stderr); 
-#endif
-    return strlen(buf);
+    DEBUG_Output(chn, buf, len);
+    return len;
 }
 
-static	BOOL DEBUG_Init(void)
+static	BOOL DEBUG_IntVarsRW(int read)
 {
     HKEY	hkey;
-    DWORD 	type;
+    DWORD 	type = REG_DWORD;
     DWORD	val;
     DWORD 	count = sizeof(val);
+    int		i;
+    DBG_INTVAR* div = DEBUG_IntVars;
 
-    if (!RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) {
-#define  INTERNAL_VAR(_var,_val) \
- 	if (!RegQueryValueEx(hkey, #_var, 0, &type, (LPSTR)&val, &count)) \
-	    DBG_IVAR(_var) = val;
+    if (read) {
+/* initializes internal vars table */
+#define  INTERNAL_VAR(_var,_val,_ref,_typ) 			\
+        div->val = _val; div->name = #_var; div->pval = _ref;	\
+        div->type = _typ; div++;
 #include "intvar.h"
 #undef   INTERNAL_VAR
+    }
+
+    if (!RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) {
+	for (i = 0; i < DBG_IV_LAST; i++) {
+	    if (read) {
+		if (!DEBUG_IntVars[i].pval) {
+		    if (!RegQueryValueEx(hkey, DEBUG_IntVars[i].name, 0, 
+					 &type, (LPSTR)&val, &count))
+			DEBUG_IntVars[i].val = val;
+		    DEBUG_IntVars[i].pval = &DEBUG_IntVars[i].val;
+		} else {
+		    *DEBUG_IntVars[i].pval = 0;
+		}
+	    } else {
+		/* FIXME: type should be infered from basic type -if any- of intvar */
+		if (DEBUG_IntVars[i].pval == &DEBUG_IntVars[i].val)
+		    RegSetValueEx(hkey, DEBUG_IntVars[i].name, 0, 
+				  type, (LPCVOID)DEBUG_IntVars[i].pval, count);
+	    }
+	}
 	RegCloseKey(hkey);
     }
     return TRUE;
 }
+
+DBG_INTVAR*	DEBUG_GetIntVar(const char* name)
+{
+    int		i;
+
+    for (i = 0; i < DBG_IV_LAST; i++) {
+	if (!strcmp(DEBUG_IntVars[i].name, name))
+	    return &DEBUG_IntVars[i];
+    }
+    return NULL;
+}
 		       
 static WINE_EXCEPTION_FILTER(wine_dbg)
 {
@@ -119,18 +152,6 @@
 
 static	void			DEBUG_InitCurrProcess(void)
 {
-#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();    
 }
 
 static BOOL DEBUG_ProcessGetString(char* buffer, int size, HANDLE hp, LPSTR addr)
@@ -277,6 +298,8 @@
         case EXCEPTION_CRITICAL_SECTION_WAIT:
             DEBUG_Printf( DBG_CHN_MESG, "critical section %08lx wait failed", 
 			  rec->ExceptionInformation[0] );
+	    if (!DBG_IVAR(BreakOnCritSectTimeOut))
+		return DBG_CONTINUE;
             break;
         default:
             DEBUG_Printf( DBG_CHN_MESG, "%08lx", rec->ExceptionCode );
@@ -284,6 +307,8 @@
         }
     }
 
+    DEBUG_Printf(DBG_CHN_MESG, "\n");
+
     DEBUG_Printf(DBG_CHN_TRACE, 
 		 "Entering debugger 	PC=%lx EFL=%08lx mode=%d count=%d\n",
 		 DEBUG_context.Eip, DEBUG_context.EFlags, 
@@ -503,7 +528,7 @@
     return ret;
 }
 
-static	DWORD	CALLBACK	DEBUG_MainLoop(DWORD pid)
+static	DWORD	DEBUG_MainLoop(DWORD pid)
 {
     DEBUG_EVENT		de;
     DWORD		cont;
@@ -511,87 +536,85 @@
 
     DEBUG_Printf(DBG_CHN_MESG, " on pid %ld\n", pid);
     
-    DEBUG_Init();
-
     while (ret && WaitForDebugEvent(&de, INFINITE)) {
 	ret = DEBUG_HandleDebugEvent(&de, &cont);
 	ContinueDebugEvent(de.dwProcessId, de.dwThreadId, cont);
     }
     
     DEBUG_Printf(DBG_CHN_MESG, "WineDbg terminated on pid %ld\n", pid);
-    
-    ExitProcess(0);
+
+    return 0;
 }
 
-int PASCAL WinMain(HINSTANCE hInst, HINSTANCE prev, LPSTR _cmdline, int show)
+int DEBUG_main(int argc, char** argv)
 {
-    char*		argv[5];
-    char*		cmdline = strdup(_cmdline);
-    char*		ptr = cmdline;
-    int			instr = FALSE;
-    int			argc = 0;
+    DWORD	pid = 0, retv = 0;
+    int		i;
 
-    while ((*ptr == ' ' || *ptr == '\t') && *ptr != 0) ptr++;
-    argv[argc++] = ptr;
-    for (; *ptr; ptr++) {
-	if ((*ptr == ' ' || *ptr == '\t') && !instr) {
-	    *ptr++ = 0;
-	    while (*ptr == ' ' || *ptr == '\t') ptr++;
-	    if (*ptr) argv[argc++] = ptr;
-	    if (argc >= sizeof(argv) / sizeof(argv[0])) return 0;
-	} else if (*ptr == '"') {
-	    instr = !instr;
-	}
-    }
+    for  (i = 0; i < argc; i++) fprintf(stderr, "argv[%d]=%s\n", i, argv[i]);
+#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();    
 
-#if 0
-    /* would require to change .spec with a cuiexe type */
+    /* Initialize internal vars */
+    DEBUG_IntVarsRW(TRUE);
+
     /* keep it as a guiexe for now, so that Wine won't touch the Unix stdin, 
      * stdout and stderr streams
      */
-    if (1 /*DBG_IVAR(UseXterm)*/) {
+    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);
     }
-#endif
 
     DEBUG_Printf(DBG_CHN_MESG, "Starting WineDbg... ");
-    if (argc == 2) {
-	DWORD	pid = atoi(argv[0]);
-	HANDLE	hEvent = atoi(argv[1]);
+    if (argc == 3) {
+	HANDLE	hEvent;
 
-	if (pid != 0 && hEvent != 0) {
-	    free(cmdline);
-
+	if ((pid = atoi(argv[1])) != 0 && (hEvent = atoi(argv[2])) != 0) {
 	    if (!DebugActiveProcess(pid)) {
 		DEBUG_Printf(DBG_CHN_ERR, "Can't attach process %ld: %ld\n", 
 			     pid, GetLastError());
-		return 0;
+		SetEvent(hEvent);
+		goto leave;
 	    }
 	    SetEvent(hEvent);
-	    return DEBUG_MainLoop(pid);
+	} else {
+	    pid = 0;
 	}
     }
-    do {
+
+    if (pid == 0) {
 	PROCESS_INFORMATION	info;
 	STARTUPINFOA		startup;
 
-	free(cmdline);
-
 	memset(&startup, 0, sizeof(startup));
 	startup.cb = sizeof(startup);
 	startup.dwFlags = STARTF_USESHOWWINDOW;
 	startup.wShowWindow = SW_SHOWNORMAL;
 
-	if (CreateProcess(NULL, _cmdline, NULL, NULL, 
-			  FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
-	    return DEBUG_MainLoop(info.dwProcessId);
+	if (!CreateProcess(NULL, argv[1], NULL, NULL, 
+			   FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
+	    DEBUG_Printf(DBG_CHN_MESG, "Couldn't start process '%s'\n", argv[1]);
+	    goto leave;
 	}
-	DEBUG_Printf(DBG_CHN_MESG, "Couldn't start process '%s'\n", _cmdline);
-    } while (0);
-    return 0;
+	pid = info.dwProcessId;
+    }
+
+    if (pid) retv = DEBUG_MainLoop(pid);
+ leave:
+    /* saves modified variables */
+    DEBUG_IntVarsRW(FALSE);
+
+    return retv;
 }
 
+