/* logger_test.c * * Copyright 2025 Francois Techene * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the sale, * use or other dealings in this Software without prior written * authorization. */ #include #include #include #include "logger.h" #define APP_NAME "Logger Test" #define VERS_RES_ID 1 #define ABOUT_DIALOG_ID 130 #define ABOUT_OK_BTN_ID 1 #define MBAR_ID 128 #define APPLE_MENU_ID 128 #define APPLE_MENU_ABOUT_ID 1 #define FILE_MENU_ID 129 #define FILE_MENU_NEW_ID 1 #define FILE_MENU_QUIT_ID 2 void drawHeader(void); void testLogLevels(void); void runTests(void); void loadMenuBar(void); void setMenuDefaults(void); short onMenuClick(long menu_id); void doEvent(EventRecord event); void centerWindow(WindowPtr win); Rect drawBtn(int h, int v, Str255 str); void drawWindow(void); void showAbout(void); WindowPtr mainWindow; DialogPtr dialog; MenuHandle appleMenu; MenuHandle fileMenu; Rect testBtn; Rect printBtn; Rect logBtn; Rect errBtn; Rect warnBtn; Rect infoBtn; Rect debugBtn; Boolean isReady = false; Boolean quitting = false; Boolean isFirstUpdate = true; void drawHeader(void) { logger.log(" \r\r"); logger.log(" ____________________ "); logger.log(" | __________________ | "); logger.log(" | | | | "); logger.log(" | | | | "); logger.log(" | | | | | | | "); logger.log(" | | _| | | "); logger.log(" | | | | "); logger.log(" | | -___- | | "); logger.log(" | |_________________| | "); logger.log(" | | "); logger.log(" | | "); logger.log(" | == ======= | "); logger.log(" | | "); logger.log(" |_____________________| "); logger.log(" |___________________| "); logger.log(" _ "); logger.log(" / / ___ __ _ __ _ ___ _ __ "); logger.log(" / / / _ \\ / _` |/ _` |/ _ \\ '__|"); logger.log("/ /__| (_) | (_| | (_| | __/ | "); logger.log("\\____/\\___/ \\__, |\\__, |\\___|_| "); logger.log(" |___/ |___/ "); logger.log("\r"); } void testLogLevels(void) { logger.logLevel = NONE_LEVEL; logger.print("\r#### Testing NONE_LEVEL: Must not show any log:\r"); logger.debug("This debug log should not be visible"); logger.info("This info log should not be visible"); logger.warn("This warning log should not be visible"); logger.error("This error log should not be visible"); logger.logLevel = ERROR_LEVEL; logger.print("\r#### Testing ERROR_LEVEL:\r"); logger.debug("This debug log should not be visible !!!"); logger.info("This info log should not be visible !!!"); logger.warn("This warning log should not be visible !!!"); logger.error("This error log should be visible"); logger.logLevel = WARNING_LEVEL; logger.print("\r#### Testing WARNING_LEVEL:\r"); logger.debug("This debug log should not be visible !!!"); logger.info("This info log should not be visible !!!"); logger.warn("This warning log should be visible"); logger.error("This error log should be visible"); logger.logLevel = INFO_LEVEL; logger.print("\r#### Testing INFO_LEVEL:\r"); logger.debug("This debug log should not be visible !!!"); logger.info("This info log should be visible"); logger.warn("This warning log should be visible"); logger.error("This error log should be visible"); logger.logLevel = DEBUG_LEVEL; logger.print("\r#### Testing DEBUG_LEVEL:\r"); logger.debug("This is a debug message with number %d ", 1); logger.info("This is an info message with number %d ", 2); logger.warn("This is a warning with number %d ", 3); logger.error("This is an error with number %d ", 4); } void runTests(void) { #ifdef USE_LOGGER // Fail safe LogConsoleScrollToBottom(); #endif drawHeader(); testLogLevels(); logger.log("\rDone!"); } int main(void) { EventRecord event; short dlgItem; short eventMask = mDownMask + mUpMask + keyDownMask + keyUpMask + autoKeyMask + updateMask; SetEventMask(everyEvent); // So we can get keyUp event. FlushEvents(eventMask, 0); InitGraf(&thePort); InitFonts(); InitWindows(); InitMenus(); TEInit(); InitDialogs(0); InitCursor(); MaxApplZone(); // Loa menus // loadMenuBar(); // Init Window // mainWindow = GetNewWindow(128, 0L, (WindowPtr)-1L); drawWindow(); dialog = NULL; isReady = true; InitLogger(DEBUG_LEVEL, CONSOLE_OUT, NULL); // Handle events // while (!quitting) { if (GetNextEvent(eventMask, &event)) { if (dialog && IsDialogEvent(&event)) { DialogSelect(&event, &dialog, &dlgItem); } else { doEvent(event); } } } return EXIT_SUCCESS; } ///////////////////////////////////////////////////// // Windows // void centerWindow(WindowPtr win) { Rect screenRect; Rect winRect; int width, height, scrWidth, scrHeight; int left, top; screenRect = screenBits.bounds; winRect = win->portRect; scrWidth = screenRect.right - screenRect.left; scrHeight = screenRect.bottom - screenRect.top; width = winRect.right - winRect.left; height = winRect.bottom - winRect.top; left = (scrWidth / 2) - (width / 2); top = (scrHeight / 2) - (height / 2); MoveWindow(win, left, top, FALSE); } Rect drawBtn(int h, int v, Str255 str) { Rect r = { 0, 0, 15, 100 }; // top, left, bottom, right TextFont(monaco); TextFace(0); TextSize(9); OffsetRect(&r, h - 1, v - 1); FrameRect(&r); OffsetRect(&r, -1, -1); FillRect(&r, white); FrameRect(&r); MoveTo(r.left + 4, r.bottom - 4); DrawString(str); return r; } void drawWindow(void) { SetPort(mainWindow); SetPortBits(&mainWindow->portBits); TextFont(helvetica); TextFace(bold); TextSize(18); MoveTo(20, 25); DrawString("\pLogger Test App"); TextFont(geneva); TextFace(0); TextSize(9); MoveTo(20, 50); DrawString("\pThis is a simple app to test the Logger library \ to help debug your Macintosh C applications."); MoveTo(20, 65); DrawString("\pThe Logger console should be visible at the bottom of the screen."); MoveTo(20, 90); DrawString("\pThe following buttons highlight the different logging \ functions of the logger."); printBtn = drawBtn(20, 110, "\plogger.print()"); logBtn = drawBtn(20, printBtn.bottom + 10, "\plogger.log()"); errBtn = drawBtn(20, logBtn.bottom + 10, "\plogger.error()"); warnBtn = drawBtn(20, errBtn.bottom + 10, "\plogger.warn()"); infoBtn = drawBtn(20, warnBtn.bottom + 10, "\plogger.info()"); debugBtn = drawBtn(20, infoBtn.bottom + 10, "\plogger.debug()"); testBtn = drawBtn(20, debugBtn.bottom + 25, "\pRun tests"); } void showAbout(void) { Handle versionRes; Str255 versionStr = "\p"; char appName[32]; short item; unsigned char* p; // Get version details from the version resource // versionRes = GetResource('vers', VERS_RES_ID); if (versionRes) { HLock(versionRes); p = (unsigned char*)*versionRes; p += 6; // skip fixed header (6 bytes) p += 1 + p[0]; // skip short version string // Get the long verstion string // BlockMove(p, versionStr, p[0] + 1); HUnlock(versionRes); } strcpy(appName, APP_NAME); appName[strlen(appName)] = '\0'; ParamText(CtoPstr(appName), versionStr, "\p", "\p"); // Load the About dialog // dialog = GetNewDialog(ABOUT_DIALOG_ID, NULL, (WindowPtr)-1); if (!dialog) { return; } centerWindow(dialog); ShowWindow(dialog); do { ModalDialog(NULL, &item); } while (item != ABOUT_OK_BTN_ID); DisposeDialog(dialog); dialog = NULL; } ///////////////////////////////////////////////////// // Menu Bar // void loadMenuBar() { Handle mbar = GetNewMBar(MBAR_ID); SetMenuBar(mbar); appleMenu = GetMHandle(APPLE_MENU_ID); AddResMenu(appleMenu, 'DRVR'); fileMenu = GetMHandle(FILE_MENU_ID); setMenuDefaults(); DrawMenuBar(); } void setMenuDefaults() { DisableItem(fileMenu, FILE_MENU_NEW_ID); } short onMenuClick(long menu_id) { short menu, item; short ret = true; menu = HiWord(menu_id); item = LoWord(menu_id); if (isReady == 0) { return false; } switch (menu) { case APPLE_MENU_ID: switch (item) { case APPLE_MENU_ABOUT_ID: { showAbout(); break; } default: { Str255 da; GrafPtr savePort; GetItem(appleMenu, item, da); GetPort(&savePort); OpenDeskAcc(da); SetPort(savePort); break; } } break; case FILE_MENU_ID: switch(item) { case FILE_MENU_NEW_ID: break; case FILE_MENU_QUIT_ID: quitting = true; break; } break; default: ret = false; } HiliteMenu(0); return ret; } ///////////////////////////////////////////////////// // Events // void doEvent(EventRecord event) { WindowPtr eventWin; short eventIn; char key; Point localPt; if(logger.onEvent(event)) { return; } localPt = event.where; GlobalToLocal(&localPt); switch (event.what) { case nullEvent: break; case keyDown: //case autoKey: key = (char)(event.message & charCodeMask); if ((event.modifiers & cmdKey) != 0) { if (onMenuClick(MenuKey(key))) break; } break; case keyUp: key = (char)(event.message & charCodeMask); break; case mouseDown: eventIn = FindWindow(event.where, &eventWin); switch (eventIn) { case inMenuBar: onMenuClick(MenuSelect(event.where)); break; case inSysWindow: SystemClick(&event, eventWin); break; case inContent: if (PtInRect(localPt, &testBtn)) { runTests(); } else if (PtInRect(localPt, &printBtn)) { logger.print("Printing some text. It doesn't end with a new line. "); } else if (PtInRect(localPt, &logBtn)) { logger.log("This is a simple log"); } else if (PtInRect(localPt, &errBtn)) { logger.error("This is an error log"); } else if (PtInRect(localPt, &warnBtn)) { logger.warn("This is a warning log"); } else if (PtInRect(localPt, &infoBtn)) { logger.info("This is an info log"); } else if (PtInRect(localPt, &debugBtn)) { logger.debug("This is a debug log"); } break; case inDrag: DragWindow(eventWin, event.where, &screenBits.bounds); break; case inGoAway: if (TrackGoAway(eventWin, event.where)) { quitting = true; } break; } break; case updateEvt: eventWin = (WindowPtr)event.message; if (eventWin) { BeginUpdate(eventWin); // We don't redraw on the first update // if(!isFirstUpdate) { drawWindow(); } else { isFirstUpdate = false; } EndUpdate(eventWin); } break; case activateEvt: break; } }