this patch makes the type handling a bit more robust it also allows to use the /u format modifier to display Unicode strings I didn't test it with complicated strings (ie, that convert easily to ANSI strings), but it should work in the wineconsole (if you have a proper font selected) A+
Name: wdbg_uni_typ ChangeLog: hacked unicode printing feature (x /u) made the type casts a bit more robust License: X11 GenDate: 2002/05/25 18:38:33 UTC ModifiedFiles: debugger/dbg.y debugger/expr.c debugger/info.c debugger/memory.c debugger/types.c debugger/winedbg.c debugger/debugger.h AddedFiles: =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/debugger/dbg.y,v retrieving revision 1.54 diff -u -u -r1.54 dbg.y --- debugger/dbg.y 27 Apr 2002 21:16:28 -0000 1.54 +++ debugger/dbg.y 27 Apr 2002 21:37:05 -0000 @@ -86,7 +86,7 @@ %nonassoc ':' %type <expression> expr lval lvalue -%type <type> type_cast type_expr +%type <type> type_expr %type <value> expr_addr lval_addr %type <integer> expr_value %type <string> pathname identifier @@ -266,11 +266,8 @@ | tNOPROCESS tSTRING tEOL { DEBUG_Printf(DBG_CHN_MESG, "No process loaded, cannot execute '%s'\n", $2); } ; -type_cast: '(' type_expr ')' { $$ = $2; } - ; - type_expr: - type_expr '*' { $$ = DEBUG_FindOrMakePointerType($1); } + type_expr '*' { $$ = $1 ? DEBUG_FindOrMakePointerType($1) : NULL; } | tINT { $$ = DEBUG_GetBasicType(DT_BASIC_INT); } | tCHAR { $$ = DEBUG_GetBasicType(DT_BASIC_CHAR); } | tLONG tINT { $$ = DEBUG_GetBasicType(DT_BASIC_LONGINT); } @@ -344,7 +341,7 @@ | '(' expr ')' { $$ = $2; } | '*' expr %prec OP_DEREF { $$ = DEBUG_UnopExpr(EXP_OP_DEREF, $2); } | '&' expr %prec OP_DEREF { $$ = DEBUG_UnopExpr(EXP_OP_ADDR, $2); } - | type_cast expr %prec OP_DEREF { $$ = DEBUG_TypeCastExpr($1, $2); } + | '(' type_expr ')' expr %prec OP_DEREF { $$ = DEBUG_TypeCastExpr($2, $4); } ; /* Index: debugger/expr.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/debugger/expr.c,v retrieving revision 1.25 diff -u -u -r1.25 expr.c --- debugger/expr.c 9 Mar 2002 23:50:37 -0000 1.25 +++ debugger/expr.c 21 Apr 2002 13:56:51 -0000 @@ -323,6 +323,11 @@ case EXPR_TYPE_CAST: rtn = DEBUG_EvalExpr(exp->un.cast.expr); rtn.type = exp->un.cast.cast; + if (!rtn.type) + { + DEBUG_Printf(DBG_CHN_MESG, "Can't cast to unknown type\n"); + RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); + } if (DEBUG_GetType(rtn.type) == DT_POINTER) rtn.cookie = DV_TARGET; break; Index: debugger/info.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/debugger/info.c,v retrieving revision 1.23 diff -u -u -r1.23 info.c --- debugger/info.c 9 Mar 2002 23:50:37 -0000 1.23 +++ debugger/info.c 11 May 2002 08:43:30 -0000 @@ -36,97 +36,107 @@ */ void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format ) { - char * default_format; - long long int res; - - assert(value->cookie == DV_TARGET || value->cookie == DV_HOST); - if( value->type == NULL ) + char * default_format; + long long int res; + + assert(value->cookie == DV_TARGET || value->cookie == DV_HOST); + if (value->type == NULL) { - DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression\n"); - return; + DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression\n"); + return; } - - default_format = NULL; - res = DEBUG_GetExprValue(value, &default_format); - - switch(format) + + default_format = NULL; + res = DEBUG_GetExprValue(value, &default_format); + + switch (format) { case 'x': - if (value->addr.seg) + if (value->addr.seg) { - DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "0x%04lx", (long unsigned int) res ); + DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "0x%04lx", (long unsigned int)res); } - else + else { - DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "0x%08lx", (long unsigned int) res ); + DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "0x%08lx", (long unsigned int)res); } - break; - + break; + case 'd': - DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "%ld\n", (long int) res ); - break; - + DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%ld\n", (long int)res); + break; + case 'c': - DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "%d = '%c'", - (char)(res & 0xff), (char)(res & 0xff) ); - break; - + DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%d = '%c'", + (char)(res & 0xff), (char)(res & 0xff)); + break; + + case 'u': + { + WCHAR wch = (WCHAR)(res & 0xFFFF); + DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%d = '", (unsigned)(res & 0xffff)); + DEBUG_OutputW(DBG_CHN_MESG, &wch, 1); + DEBUG_Printf(DBG_CHN_MESG, "'"); + } + break; + case 'i': case 's': case 'w': case 'b': - DEBUG_Printf( DBG_CHN_MESG, "Format specifier '%c' is meaningless in 'print' command\n", format ); + DEBUG_Printf(DBG_CHN_MESG, "Format specifier '%c' is meaningless in 'print' command\n", format); case 0: - if( default_format != NULL ) + if (default_format != NULL) { - if (strstr(default_format, "%S") != NULL) + if (strstr(default_format, "%S") != NULL) { - char* ptr; - int state = 0; - - /* FIXME: simplistic implementation for default_format being - * foo%Sbar => will print foo, then string then bar - */ - for (ptr = default_format; *ptr; ptr++) - { - if (*ptr == '%') state++; - else if (state == 1) + char* ptr; + int state = 0; + + /* FIXME: simplistic implementation for default_format being + * foo%Sbar => will print foo, then string then bar + */ + for (ptr = default_format; *ptr; ptr++) + { + if (*ptr == '%') + { + state++; + } + else if (state == 1) { - if (*ptr == 'S') - { - char ch; - char* str = (char*)(long)res; - - for (; DEBUG_READ_MEM(str, &ch, 1) && ch; str++) { - DEBUG_Output(DBG_CHN_MESG, &ch, 1); - DEBUG_nchar++; - } - } - else - { + if (*ptr == 'S') + { + DBG_ADDR addr; + + addr.seg = 0; + addr.off = (long)res; + DEBUG_nchar += DEBUG_PrintStringA(DBG_CHN_MESG, &addr, -1); + } + else + { /* shouldn't happen */ DEBUG_Printf(DBG_CHN_MESG, "%%%c", *ptr); DEBUG_nchar += 2; - } - state = 0; + } + state = 0; } - else + else { - DEBUG_Output(DBG_CHN_MESG, ptr, 1); - DEBUG_nchar++; + DEBUG_OutputA(DBG_CHN_MESG, ptr, 1); + DEBUG_nchar++; } - } + } } - else if (strcmp(default_format, "%B") == 0) + else if (strcmp(default_format, "%B") == 0) { - DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "%s", res ? "true" : "false"); + DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%s", res ? "true" : "false"); } - else + else { - DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, default_format, res ); + DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, default_format, res); } } - break; + break; } } Index: debugger/memory.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/debugger/memory.c,v retrieving revision 1.27 diff -u -u -r1.27 memory.c --- debugger/memory.c 26 Apr 2002 19:05:16 -0000 1.27 +++ debugger/memory.c 27 Apr 2002 21:35:39 -0000 @@ -276,33 +276,15 @@ switch(format) { - case 'u': { - WCHAR wch; - if (count == 1) count = 256; - while (count--) - { - if (!DEBUG_READ_MEM_VERBOSE(pnt, &wch, sizeof(wch)) || !wch) - break; - pnt += sizeof(wch); - DEBUG_Printf(DBG_CHN_MESG, "%c", (char)wch); - } - DEBUG_Printf(DBG_CHN_MESG,"\n"); + case 'u': + if (count == 1) count = 256; + DEBUG_nchar += DEBUG_PrintStringW(DBG_CHN_MESG, &value.addr, count); + DEBUG_Printf(DBG_CHN_MESG, "\n"); return; - } - case 's': { - char ch; - - if (count == 1) count = 256; - while (count--) - { - if (!DEBUG_READ_MEM_VERBOSE(pnt, &ch, sizeof(ch)) || !ch) - break; - pnt++; - DEBUG_Output(DBG_CHN_MESG, &ch, 1); - } - DEBUG_Printf(DBG_CHN_MESG,"\n"); + case 's': + DEBUG_nchar += DEBUG_PrintStringA(DBG_CHN_MESG, &value.addr, count); + DEBUG_Printf(DBG_CHN_MESG, "\n"); return; - } case 'i': while (count-- && DEBUG_DisassembleInstruction( &value.addr )); return; @@ -329,4 +311,51 @@ case 'c': DO_DUMP2(char, 32, " %c", (_v < 0x20) ? ' ' : _v); case 'b': DO_DUMP2(char, 16, " %02x", (_v) & 0xff); } +} + +/****************************************************************** + * DEBUG_PrintStringA + * + * Prints on channel chnl, the string starting at address in target + * address space. The string stops when either len chars (if <> -1) + * have been printed, or the '\0' char is printed + */ +int DEBUG_PrintStringA(int chnl, const DBG_ADDR* address, int len) +{ + char* lin = (void*)DEBUG_ToLinear(address); + char ach[16+1]; + int i, l; + + if (len == -1) len = 32767; /* should be big enough */ + + /* so that the ach is always terminated */ + ach[sizeof(ach) - 1] = '\0'; + for (i = len; i >= 0; i -= sizeof(ach) - 1) + { + l = min(sizeof(ach) - 1, i); + DEBUG_READ_MEM_VERBOSE(lin, ach, l); + l = strlen(ach); + DEBUG_OutputA(chnl, ach, l); + lin += l; + if (l < sizeof(ach) - 1) break; + } + return len - i; /* number of actually written chars */ +} + +int DEBUG_PrintStringW(int chnl, const DBG_ADDR* address, int len) +{ + char* lin = (void*)DEBUG_ToLinear(address); + WCHAR wch; + int ret = 0; + + if (len == -1) len = 32767; /* should be big enough */ + while (len--) + { + if (!DEBUG_READ_MEM_VERBOSE(lin, &wch, sizeof(wch)) || !wch) + break; + lin += sizeof(wch); + DEBUG_OutputW(chnl, &wch, 1); + ret++; + } + return ret; } Index: debugger/types.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/debugger/types.c,v retrieving revision 1.28 diff -u -u -r1.28 types.c --- debugger/types.c 9 Mar 2002 23:50:37 -0000 1.28 +++ debugger/types.c 26 Apr 2002 04:29:02 -0000 @@ -875,7 +875,6 @@ size = DEBUG_GetObjectSize(value->type->un.array.basictype); if( size == 1 ) { - char ach[16]; int len, clen; /* @@ -883,21 +882,17 @@ */ pnt = (char *) value->addr.off; len = value->type->un.array.end - value->type->un.array.start + 1; - clen = (DEBUG_nchar + len < DEBUG_maxchar) + clen = (DEBUG_nchar + len < DEBUG_maxchar) ? len : (DEBUG_maxchar - DEBUG_nchar); DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "\""); switch (value->cookie) { case DV_TARGET: - for (i = clen; i > 0; i -= sizeof(ach)) - { - DEBUG_READ_MEM(pnt, ach, min(sizeof(ach), i)); - DEBUG_Output(DBG_CHN_MESG, ach, min(sizeof(ach), i)); - } + clen = DEBUG_PrintStringA(DBG_CHN_MESG, &value->addr, clen); break; case DV_HOST: - DEBUG_Output(DBG_CHN_MESG, pnt, clen); + DEBUG_OutputA(DBG_CHN_MESG, pnt, clen); break; default: assert(0); } Index: debugger/winedbg.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/debugger/winedbg.c,v retrieving revision 1.51 diff -u -u -r1.51 winedbg.c --- debugger/winedbg.c 11 May 2002 23:06:32 -0000 1.51 +++ debugger/winedbg.c 25 May 2002 13:51:51 -0000 @@ -48,7 +48,7 @@ static int automatic_mode; DBG_INTVAR DEBUG_IntVars[DBG_IV_LAST]; -void DEBUG_Output(int chn, const char* buffer, int len) +void DEBUG_OutputA(int chn, const char* buffer, int len) { if (DBG_IVAR(ConChannelMask) & chn) WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL); @@ -56,6 +56,16 @@ fwrite(buffer, len, 1, stderr); } +void DEBUG_OutputW(int chn, const WCHAR* buffer, int len) +{ + /* FIXME: this won't work is std output isn't attached to a console */ + if (DBG_IVAR(ConChannelMask) & chn) + WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL); + /* simplistic Unicode to ANSI conversion */ + if (DBG_IVAR(StdChannelMask) & chn) + while (len--) fputc((char)*buffer++, stderr); +} + int DEBUG_Printf(int chn, const char* format, ...) { static char buf[4*1024]; @@ -71,7 +81,7 @@ buf[len] = 0; buf[len - 1] = buf[len - 2] = buf[len - 3] = '.'; } - DEBUG_Output(chn, buf, len); + DEBUG_OutputA(chn, buf, len); return len; } Index: debugger/debugger.h =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/debugger/debugger.h,v retrieving revision 1.31 diff -u -u -r1.31 debugger.h --- debugger/debugger.h 1 Apr 2002 21:03:13 -0000 1.31 +++ debugger/debugger.h 21 Apr 2002 19:09:32 -0000 @@ -419,6 +419,8 @@ extern void DEBUG_FixAddress( DBG_ADDR *address, DWORD def ); extern int DEBUG_IsSelectorSystem( WORD sel ); #endif +extern int DEBUG_PrintStringA( int chnl, const DBG_ADDR* address, int len ); +extern int DEBUG_PrintStringW( int chnl, const DBG_ADDR* address, int len ); /* debugger/module.c */ extern int DEBUG_LoadEntryPoints( const char * prefix ); @@ -513,7 +515,8 @@ #define DBG_CHN_WARN 4 #define DBG_CHN_FIXME 8 #define DBG_CHN_TRACE 16 -extern void DEBUG_Output(int chn, const char* buffer, int len); +extern void DEBUG_OutputA(int chn, const char* buffer, int len); +extern void DEBUG_OutputW(int chn, const WCHAR* buffer, int len); #ifdef __GNUC__ extern int DEBUG_Printf(int chn, const char* format, ...) __attribute__((format (printf,2,3))); #else