LINUX: afs_create infinite fetchStatus loop
[pkg-k5-afs_openafs.git] / src / WINNT / afsclass / c_debug.cpp
blob91412700e33397b95bafe7626f86b7c2a29e95c5
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
13 extern "C" {
14 #include <afsconfig.h>
15 #include <afs/param.h>
16 #include <roken.h>
19 #include <windows.h>
20 #include <stdlib.h>
21 #include <memory.h>
22 #include <string.h>
23 #include <stdarg.h>
24 #include <WINNT/c_debug.h>
26 #ifdef DEBUG
28 #ifndef THIS_HINST
29 #define THIS_HINST (GetModuleHandle (NULL))
30 #endif
32 #define WM_OUTSTRING (WM_USER + 0x99)
37 * VARIABLES __________________________________________________________________
41 Debugstr debug;
43 int Debugstr::fRegistered = 0;
44 int Debugstr::fInit = 0;
45 HWND Debugstr::hwnd = 0;
47 ushort Debugstr::gx;
48 ushort Debugstr::gy;
49 ushort Debugstr::gcX;
50 ushort Debugstr::gcY;
51 char Debugstr::gdata[ yMAX ][ xMAX ];
53 BOOL Debugstr::fAngles = FALSE;
55 ushort nRefr;
57 ushort cxAvgWidth (void);
61 * ROUTINES ___________________________________________________________________
65 int AssertFn (int b, char *expr, int line, char *name)
67 char szLine1[ 256 ];
68 char szLine2[ 256 ];
70 if (b)
71 return 1;
73 wsprintf (szLine1, "Assertion failed: \"%s\"", expr);
74 wsprintf (szLine2, "Line %u of module %s.", line, name);
76 #ifdef DEBUG
77 debug << szLine1 << "\n";
78 debug << szLine2 << "\n";
79 #endif
81 MessageBox (NULL, szLine1, szLine2, MB_ICONEXCLAMATION);
82 return 0;
87 * OPERATORS __________________________________________________________________
91 Debugstr & Debugstr::operator<< (char *str)
93 if (! strcmp (str, ANGLES_ON))
94 fAngles = TRUE;
95 else if (! strcmp (str, ANGLES_OFF))
96 fAngles = FALSE;
97 else if (! strcmp (str, LASTERROR))
99 LPVOID lp;
101 FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
102 NULL, GetLastError(),
103 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
104 (LPTSTR)&lp, 0, NULL);
106 (*this) << "#" << (LONG)GetLastError();
107 (*this) << " (" << (char *)lp << ")";
109 LocalFree (lp);
111 else
113 Register(); // does nothing unless first time
114 Initialize(); // does nothing unless first time
116 char *strToSend = (char *)Allocate(1+strlen(str));
117 strcpy (strToSend, str);
119 PostMessage (Debugstr::hwnd, WM_OUTSTRING, 0, (LPARAM)strToSend);
121 return (*this);
124 Debugstr & Debugstr::operator<< (void *addr)
126 char szTemp[40];
127 if (HIWORD(addr) == 0x0000)
128 wsprintf (szTemp, "0x%04X", (ushort)LOWORD(PtrToLong(addr)));
129 else
130 wsprintf (szTemp, "0x%08lX", PtrToLong(addr));
131 return (*this << szTemp);
134 Debugstr & Debugstr::operator<< (uchar ch)
136 char szTemp[2];
137 szTemp[0] = ch;
138 szTemp[1] = 0;
139 return (*this << szTemp);
142 Debugstr & Debugstr::operator<< (char ch)
144 char szTemp[2];
145 szTemp[0] = ch;
146 szTemp[1] = 0;
147 return (*this << szTemp);
150 Debugstr & Debugstr::operator<< (size_t l)
152 char szTemp[40];
153 _ltoa ((LONG)l, szTemp, 10);
154 return (*this << szTemp);
157 Debugstr & Debugstr::operator<< (long l)
159 char szTemp[40];
160 _ltoa (l, szTemp, 10);
161 return (*this << szTemp);
164 Debugstr & Debugstr::operator<< (ushort s)
166 char szTemp[40];
167 _itoa (s, szTemp, 10);
168 return (*this << szTemp);
171 Debugstr & Debugstr::operator<< (short s)
173 char szTemp[40];
174 _itoa (s, szTemp, 10);
175 return (*this << szTemp);
178 Debugstr & Debugstr::operator<< (double f)
180 char *psz; // (may cross segments)
181 char szTemp[ 64 ];
182 long l;
184 if (fAngles)
186 f *= 180.0 / 3.1415926535897;
187 while (f >= 360)
188 f -= 360;
189 while (f < 0)
190 f += 360;
193 l = (long)f;
194 *this << l;
196 f -= (double)l;
197 f *= 1000000.0; // add 6 zeroes...
198 l = (long)f;
200 wsprintf (szTemp, "%06ld", l);
202 for (psz = &szTemp[ strlen(szTemp)-1 ]; psz >= szTemp; psz--)
204 if (*psz != '0')
205 break;
207 *(1+psz) = 0;
209 if (szTemp[0] != 0)
211 *this << "." << szTemp;
214 return *this;
217 Debugstr & Debugstr::operator<< (RECT r)
219 *this << "{ x=" << (LONG)r.left << ".." << (LONG)r.right;
220 *this << ", y=" << (LONG)r.top << ".." << (LONG)r.bottom << " }";
221 return (*this);
224 Debugstr & Debugstr::operator<< (LPIDENT lpi)
226 if (!lpi)
228 *this << "{ invalid ident }";
230 else if (lpi->fIsCell())
232 TCHAR szCell[ cchNAME ];
233 lpi->GetCellName (szCell);
234 *this << "{ cell " << szCell << " }";
236 else if (lpi->fIsServer())
238 TCHAR szServer[ cchNAME ];
239 lpi->GetServerName (szServer);
240 *this << "{ server " << szServer << " }";
242 else if (lpi->fIsAggregate())
244 TCHAR szServer[ cchNAME ];
245 lpi->GetServerName (szServer);
246 TCHAR szAggregate[ cchNAME ];
247 lpi->GetAggregateName (szAggregate);
248 *this << "{ aggregate " << szServer << ":" << szAggregate << " }";
250 else if (lpi->fIsFileset())
252 TCHAR szServer[ cchNAME ];
253 lpi->GetServerName (szServer);
254 TCHAR szAggregate[ cchNAME ];
255 lpi->GetAggregateName (szAggregate);
256 TCHAR szFileset[ cchNAME ];
257 lpi->GetFilesetName (szFileset);
258 *this << "{ fileset " << szFileset << " on " << szServer << ":" << szAggregate << " }";
260 else if (lpi->fIsServer())
262 TCHAR szServer[ cchNAME ];
263 lpi->GetServerName (szServer);
264 TCHAR szService[ cchNAME ];
265 lpi->GetServiceName (szService);
266 *this << "{ service " << szServer << ":" << szService << " }";
268 return (*this);
273 * STATICS ____________________________________________________________________
277 Debugstr::Debugstr (void)
279 hfNew = NULL;
280 brBack = NULL;
283 Debugstr::~Debugstr (void)
285 if (hfNew != NULL)
287 DeleteObject (hfNew);
288 hfNew = NULL;
291 if (brBack != NULL)
293 DeleteObject (brBack);
294 brBack = NULL;
299 #define szDebugCLASS "DebugClass"
301 void Debugstr::Register (void)
303 WNDCLASS wc;
305 if (fRegistered)
306 return;
307 fRegistered = TRUE;
309 wc.style = CS_HREDRAW | CS_VREDRAW;
310 wc.lpfnWndProc = DebugWndProc;
311 wc.cbClsExtra = 0;
312 wc.cbWndExtra = 0;
313 wc.hInstance = THIS_HINST;
314 wc.hIcon = LoadIcon(NULL, IDI_EXCLAMATION);
315 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
316 wc.hbrBackground = CreateSolidBrush( GetSysColor( COLOR_BTNFACE ));
317 wc.lpszMenuName = NULL;
318 wc.lpszClassName = szDebugCLASS;
320 (void)RegisterClass(&wc);
324 void Debugstr::Initialize (void)
326 HWND hWnd;
327 int x, y, w, h;
329 if (fInit)
330 return;
331 fInit = TRUE;
333 w = cxAvgWidth() * 58;
334 // w = cxAvgWidth() * 160;
335 h = GetSystemMetrics (SM_CYSCREEN);
336 x = GetSystemMetrics (SM_CXSCREEN) - w;
337 y = 0;
339 hWnd = CreateWindow(
340 szDebugCLASS,
341 "debug++", // Title
342 WS_OVERLAPPEDWINDOW | // Window style
343 WS_THICKFRAME,
344 x, // Default horizontal position
345 y +35, // Default vertical position
346 w, // Default width
347 h -70, // Default height
348 NULL, // Overlapped windows have no parent
349 NULL, // Use the window class menu
350 THIS_HINST, // This instance owns this window
351 NULL // Pointer not needed
354 if (!hWnd)
355 return;
358 * Make the window visible and update its client area.
362 for (y = 0; y < yMAX; y++)
363 gdata[y][0] = 0;
365 gx = minX;
366 gy = minY;
367 gcX = 0;
368 gcY = 0;
369 nRefr = 0;
371 ShowWindow (hWnd, SW_SHOWNOACTIVATE);
372 UpdateWindow (hWnd);
374 Debugstr::hwnd = hWnd;
378 /*** OutString - Translates "\n" 's, and calls Output to display text
380 * ENTRY: char *str - string to display
381 * BOOL fRecord - FALSE if inside WM_PAINT message
383 * EXIT: none
387 void Debugstr::OutString (char *str, BOOL fRecord)
389 char *psz, *pch;
390 HDC hdc;
391 DWORD fg, bk;
392 RECT r;
393 RECT r2;
394 HFONT hfOld;
395 LOGFONT lf;
396 SIZE siz;
398 Register(); // does nothing unless first time
399 Initialize(); // does nothing unless first time
401 if (str == NULL)
402 str = "(null)";
404 OutputDebugString (str);
406 if (Debugstr::hwnd == NULL)
407 return;
409 if ((hdc = GetDC (Debugstr::hwnd)) == NULL)
410 return;
412 fg = SetTextColor (hdc, GetSysColor( COLOR_BTNTEXT ));
413 bk = SetBkColor (hdc, GetSysColor( COLOR_BTNFACE ));
415 if (brBack == NULL)
417 brBack = CreateSolidBrush (GetBkColor(hdc));
420 if (hfNew == NULL)
422 memset (&lf, 0, sizeof(lf));
424 lf.lfWeight = FW_NORMAL;
425 lf.lfHeight = -MulDiv (8, GetDeviceCaps(hdc, LOGPIXELSY), 72);
426 strcpy (lf.lfFaceName, "Arial");
428 hfNew = CreateFontIndirect(&lf);
431 hfOld = (HFONT)SelectObject(hdc, hfNew);
432 GetTextMetrics (hdc, &tm);
434 GetClientRect (Debugstr::hwnd, &r);
436 if (!strcmp (str, "CLS"))
438 gx = 0;
439 gy = minY;
440 gcX = 0;
441 gcY = 0;
442 gdata[gcY][0] = 0;
443 gdata[gcY+1][0] = 0;
445 FillRect (hdc, &r, brBack);
447 else for (psz = str; *psz; )
449 if ((pch = strchr(psz, '\n')) == NULL)
451 Output (hdc, psz, fRecord);
452 break;
455 *pch = 0;
456 Output (hdc, psz, fRecord);
458 gy += (ushort)tm.tmHeight;
459 gcY++;
460 gx = minX;
461 gcX = 0;
463 if (fRecord)
465 if ((gy + tm.tmHeight) > (ushort)r.bottom)
467 gy = minY;
468 gcY = 0;
470 GetTextExtentPoint (hdc, gdata[gcY], (int)strlen(gdata[gcY]), &siz);
472 r2.top = gy;
473 r2.bottom = gy + tm.tmHeight;
474 r2.left = gx -1;
475 r2.right = siz.cx;
476 r2.right += gx;
477 FillRect (hdc, &r2, brBack);
479 gdata[gcY][0] = 0;
483 nRefr = max( nRefr, gcY );
485 *pch = '\n';
486 psz = 1+pch;
488 if (fRecord)
490 GetTextExtentPoint (hdc, gdata[gcY+1], (int)strlen(gdata[gcY+1]), &siz);
492 r2.top = gy +tm.tmHeight;
493 r2.bottom = gy +tm.tmHeight +tm.tmHeight;
494 r2.left = gx;
495 r2.right = siz.cx;
496 r2.right += gx;
497 FillRect (hdc, &r2, brBack);
499 gdata[gcY+1][0] = 0;
503 SelectObject (hdc, hfOld);
504 SetTextColor (hdc, fg);
505 SetBkColor (hdc, bk);
506 ReleaseDC (Debugstr::hwnd, hdc);
510 void Debugstr::Output (HDC hdc, char *psz, BOOL fRec)
512 SIZE siz;
514 TextOut (hdc, gx, gy, psz, (int)strlen(psz));
516 if (fRec)
517 strcat (gdata[gcY], psz);
519 GetTextExtentPoint (hdc, psz, (int)strlen(psz), &siz);
521 gx += (ushort)siz.cx;
522 gcX += (int)strlen(psz);
527 /*** DebugWndProc - Main window callback
529 * ENTRY:
530 * EXIT: As WNDPROC
532 * MESSAGES: WM_COMMAND - application menu (About dialog box)
533 * WM_DESTROY - destroy window
537 LRESULT APIENTRY Debugstr::DebugWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
539 ushort x, y, cX, cY;
541 switch (message)
543 case WM_COMMAND:
544 break;
546 case WM_DESTROY:
547 if (Debugstr::hwnd != 0)
549 CloseWindow (Debugstr::hwnd);
550 Debugstr::hwnd = 0; // Turn off debugging--no window!
552 break;
554 case WM_OUTSTRING:
556 char *str = (char*)lParam;
557 debug.OutString (str, TRUE);
558 Free (str);
560 break;
562 case WM_PAINT:
564 PAINTSTRUCT ps;
565 HDC hdc;
566 hdc = BeginPaint (hWnd, &ps);
567 EndPaint (hWnd, &ps);
569 x = gx; y = gy; cX = gcX; cY = gcY;
571 gx = minX;
572 gy = minY;
573 gcX = 0;
574 gcY = 0;
576 for (gcY = 0; gcY < nRefr; )
578 TCHAR szLine[] = TEXT("\n");
579 debug.OutString (gdata[gcY], FALSE);
580 debug.OutString (szLine, FALSE);
582 debug.OutString (gdata[gcY], FALSE);
584 gx = x; gy = y; gcX = cX; gcY = cY;
585 return 0;
587 break;
589 default:
590 break;
593 return (DefWindowProc(hWnd, message, wParam, lParam));
597 /*** cxAvgWidth - Returns the average width of the chars in Arial/8point.
599 * ENTRY: none
601 * EXIT: ushort pels
603 * ERROR: returns 8
607 ushort cxAvgWidth (void)
609 HFONT hfnt, hfntOld = NULL;
610 LOGFONT lf;
611 TEXTMETRIC tm;
612 HDC hdc;
615 hdc = GetDC( GetDesktopWindow() );
617 memset (&lf, 0, sizeof(lf));
618 lf.lfHeight = -MulDiv (8, GetDeviceCaps(hdc, LOGPIXELSY), 72);
619 strcpy (lf.lfFaceName, "Arial");
621 if ((hfnt = CreateFontIndirect(&lf)) != NULL)
623 hfntOld = (HFONT)SelectObject(hdc, hfnt);
626 if (! GetTextMetrics (hdc, &tm))
627 return 8;
629 if (hfntOld != NULL)
631 SelectObject (hdc, hfntOld);
632 DeleteObject (hfnt);
635 ReleaseDC (GetDesktopWindow(), hdc);
637 return (ushort)tm.tmAveCharWidth;
642 * LOG ROUTINES
646 #define LONG_TYPE 0x0001
647 #define SHORT_TYPE 0x0002
648 #define INT_TYPE 0x0004
649 #define CHAR_TYPE 0x0008
650 #define STRING_TYPE 0x0010
651 #define FLOAT_TYPE 0x0020
652 #define COMMA_TYPE 0x0040
653 #define MSG_TYPE 0x0080
655 cdecl LogOut::LogOut (char *psz, ...)
657 char *pch;
658 ushort n;
659 BOOL fBreak;
660 va_list arg;
661 va_start (arg, psz);
663 strcpy (pszFormat, psz);
664 nArgs = 0;
666 for (pch = psz; *pch; pch++)
668 if (*pch != '%')
669 continue;
671 n = 0;
672 fBreak = FALSE;
674 while (!fBreak)
676 if (!* (++pch))
677 break;
679 switch (*pch)
681 case 'F': n |= LONG_TYPE; break;
682 case 'l': n |= LONG_TYPE; break;
683 case 'h': n |= SHORT_TYPE; break;
684 case 'X': n |= INT_TYPE; break;
685 case 'x': n |= INT_TYPE; break;
686 case 'O': n |= INT_TYPE; break;
687 case 'o': n |= INT_TYPE; break;
688 case 'd': n |= INT_TYPE; break;
689 case 'u': n |= INT_TYPE; break;
690 case 'c': n |= CHAR_TYPE; break;
691 case 's': n |= STRING_TYPE; break;
692 default: fBreak = TRUE; break;
696 if (nArgs == MAX_ARGS)
697 break;
699 aPtr[nArgs] = va_arg (arg, char *);
701 nArgs++;
703 if (! *pch)
704 break;
708 LogOut::~LogOut (void)
710 char tmpfmt[ 64 ];
711 char text[ 256 ];
712 char *pszOut;
713 char *pszTmpFmt;
714 char *pszFmt;
715 char *pch;
716 ushort i = 0;
717 ushort n;
718 BOOL fBreak;
720 pszOut = text;
722 for (pszFmt = pszFormat; *pszFmt; pszFmt++)
724 if (*pszFmt != '%')
726 *pszOut++ = *pszFmt;
727 continue;
730 n = 0;
731 fBreak = FALSE;
733 for (pszTmpFmt = tmpfmt; !fBreak; )
735 *pszTmpFmt++ = *pszFmt;
737 if (!* (++pszFmt))
738 break;
740 switch (*pszFmt)
742 case 'F': n |= LONG_TYPE; break; // (far)
743 case 'l': n |= LONG_TYPE; break;
744 case 'h': n |= SHORT_TYPE; break;
745 case 'X': n |= INT_TYPE; break;
746 case 'x': n |= INT_TYPE; break;
747 case 'O': n |= INT_TYPE; break;
748 case 'o': n |= INT_TYPE; break;
749 case 'd': n |= INT_TYPE; break;
750 case 'u': n |= INT_TYPE; break;
751 case 'c': n |= CHAR_TYPE; break;
752 case 's': n |= STRING_TYPE; break;
753 default: fBreak = TRUE; break;
757 *pszTmpFmt = 0;
759 pch = aPtr[ i ];
760 i++;
763 if (n & STRING_TYPE)
765 wsprintf (pszOut, tmpfmt, (char far *)pch);
767 else if (n & LONG_TYPE)
768 wsprintf (pszOut, tmpfmt, *(long *)pch);
769 else if (n & SHORT_TYPE)
770 wsprintf (pszOut, tmpfmt, *(short *)pch);
771 else if (n & INT_TYPE)
772 wsprintf (pszOut, tmpfmt, *(int *)pch);
773 else if (n & CHAR_TYPE)
774 wsprintf (pszOut, tmpfmt, (char)*(char *)pch);
775 else
776 *pszOut = 0;
778 pszOut = &pszOut[ strlen(pszOut) ];
780 if (! *pszFmt)
781 break;
784 *pszOut = 0;
786 debug << text << "\n";
789 #endif // DEBUG