📄 curses.c
字号:
/* * CUnit - A Unit testing framework library for C. * Copyright (C) 2001 Anil Kumar * Copyright (C) 2004,2005,2006 Anil Kumar, Jerry St.Clair * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * Implementation of the Curses based Test Interface. * * 01/Nov/2001 Started Curses based interface for CUnit. (AK) * * 04/Nov/2001 Added Scrolling Capability to the Details Window. (AK) * * 24/Nov/2001 Added List and Show Failure Capability to the Details Window. * Also added group initialization failure message handler. (AK) * * 09-Aug-2004 New interface, made all curses local functions static. (JDS) *//** @file * Curses test interface with interactive output (implementation). *//** @addtogroup Curses @{*/#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <assert.h>#include <string.h>#include <curses.h>#include "CUnit.h"#include "TestDB.h"#include "Util.h"#include "TestRun.h"#include "CUCurses.h"/* * Type Definitions */#ifndef false#define false (0) /**< Local boolean definition for false. */#endif#ifndef true#define true (~false) /**< Local boolean definition for true. */#endif/** Curses interface status flag. */typedef enum{ CONTINUE = 1, /**< Continue processing commands in current menu. */ MOVE_UP, /**< Move up to the previous menu. */ STOP /**< Stop processing (user selected 'Quit'). */} STATUS;/** Menu type. */typedef enum{ MAIN_MENU = 1, GROUP_MENU} MENU_TYPE;/** Pointers to curses interface windows. */typedef struct{ WINDOW* pMainWin; /**< Main window. */ WINDOW* pTitleWin; /**< Title window. */ WINDOW* pProgressWin; /**< Progress bar window. */ WINDOW* pSummaryWin; /**< Summary window. */ WINDOW* pRunSummaryWin; /**< Run Summary window. */ WINDOW* pDetailsWin; /**< Details window. */ WINDOW* pOptionsWin; /**< Options window. */} APPWINDOWS;/** Window elements. */typedef struct{ WINDOW* pPad; /**< Pointer to the pad. */ unsigned int uiRows; /**< Number of rows in pad. */ unsigned int uiColumns; /**< Number of columns in pad. */ unsigned int uiPadRow; /**< Current pad row. */ unsigned int uiPadCol; /**< Current pad column. */ unsigned int uiWinLeft; /**< Left position of containing window. */ unsigned int uiWinTop; /**< Top position of containing window. */ unsigned int uiWinRows; /**< Number of rows in containing window. */ unsigned int uiWinColumns; /**< Number of columns in containing window. */} APPPAD;/* * Constants definitions *//** Standard string length. */#define STRING_LENGTH 128/** String holding main menu run options. */static const char* MAIN_OPTIONS = "(R)un (S)elect Suite (L)ist (F)ailures (Q)uit";/** String holding suite menu run options. */static const char* SUITE_OPTIONS = "(R)un (S)elect Test (L)ist (F)ailures (U)p (Q)uit";/* * Color Pairs Initialized for the Various Parameter Display */static const int CLEAR_COLOR = 1; /**< Clear color.*/static const int TITLE_COLOR = 2; /**< Title color.*/static const int PROGRESS_BACKGROUND_COLOR = 3; /**< progress bar background color.*/static const int PROGRESS_SUCCESS_COLOR = 4; /**< Progress bar success color.*/static const int PROGRESS_FAILURE_COLOR = 5; /**< Progress bar failure color.*/static const int MENU_COLOR = 6; /**< Menu color.*//* * Global Definitions */static const char* const f_szProgress = "Progress "; /**< Test for progress bar. */static const char* f_szOptions = NULL; /**< String containing options. */static CU_pTest f_pCurrentTest = NULL; /**< Pointer to the test currently being run. */static CU_pSuite f_pCurrentSuite = NULL; /**< Pointer to the suite currently being run. */static unsigned int f_uiTotalTests = 0; /**< Number of tests in registered suites. */static unsigned int f_uiTestsRun = 0; /**< Number of tests actually run. */static unsigned int f_uiTestsSkipped = 0; /**< Number of tests skipped during run. */static unsigned int f_uiTestsFailed = 0; /**< Number of tests having failed assertions. */static unsigned int f_uiTestsRunSuccessful = 0; /**< Number of tests run with no failed assertions. */static unsigned int f_uiTotalSuites = 0; /**< Number of registered suites. */static unsigned int f_uiSuitesSkipped = 0; /**< Number of suites skipped during run. */static short f_nLeft; /**< Left window position. */static short f_nTop; /**< Top window position. */static short f_nWidth; /**< Width of window. */static short f_nHeight; /**< Height of window. *//** Pointers to curses interface windows. */static APPWINDOWS application_windows = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};/** Details window definition. */static APPPAD details_pad = {NULL, 0, 0, 0, 0, 0, 0, 0, 0};/* * Function Declarations */static bool initialize_windows(void);static void uninitialize_windows(void);static void refresh_windows(void);static void refresh_title_window(void);static void refresh_progress_window(void);static void refresh_summary_window(void);static void refresh_run_summary_window(void);static void refresh_details_window(void);static void refresh_options_window(void);static bool create_pad(APPPAD* pPad, WINDOW* pParent, unsigned int uiRows, unsigned int uiCols);static void scroll_window(int nCommand, APPPAD* pPad, void (*parent_refresh)(void));static bool test_initialize(void);static void show_progress_bar(void);static const char* get_hotkey(const char* szStr, int* pPos);static void read_input_string(const char szPropmt[], char szValue[], int nBytes);static STATUS curses_registry_level_run(CU_pTestRegistry pRegistry);static STATUS curses_suite_level_run(CU_pSuite pSuite);static CU_ErrorCode curses_run_all_tests(CU_pTestRegistry pRegistry);static CU_ErrorCode curses_run_suite_tests(CU_pSuite pSuite);static CU_ErrorCode curses_run_single_test(CU_pSuite pSuite, CU_pTest pTest);static void curses_test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite);static void curses_test_complete_message_handler(const CU_pTest pTest, const CU_pSuite pSuite, const CU_pFailureRecord pFailure);static void curses_all_tests_complete_message_handler(const CU_pFailureRecord pFailure);static void curses_suite_init_failure_message_handler(const CU_pSuite pSuite);static void list_suites(CU_pTestRegistry pRegistry);static void list_tests(CU_pSuite pSuite);static void show_failures(void);static void reset_run_parameters(void);/*------------------------------------------------------------------------*//** Run registered CUnit tests using the curses interface. */void CU_curses_run_tests(void){ setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); f_szOptions = MAIN_OPTIONS; if (!initialize_windows()) { return; } if (!test_initialize()) { goto test_initialize_fail; } curses_registry_level_run(CU_get_registry()); /* THIS WAS COMMENTED OUT IN THE 1.1-1 SOURCE f_uiTotalTests = 3000; { int i; int iSucc = 0; for (i = 0; i < 3000; i++, iSucc++) { if (i && !(i%2000)) iSucc--; f_uiTestsRun = i + 1; f_uiTestsRunSuccessful = iSucc + 1; refresh_progress_window(); refresh_summary_window(); refresh_run_summary_window(); } } f_uiTestsRunSuccessful = f_uiTestsRun = 0; refresh_windows(); { int i; int iSucc = -1; for (i = 0; i < 3000; i++, iSucc++) { if (i && !(i%2000)) iSucc++; f_uiTestsRun = i + 1; f_uiTestsRunSuccessful = iSucc + 1; refresh_progress_window(); refresh_summary_window(); refresh_run_summary_window(); } } */test_initialize_fail: uninitialize_windows();}/*------------------------------------------------------------------------*//** Initialize the curses interface windows. */static bool initialize_windows(void){ bool bStatus = false; if (NULL == (application_windows.pMainWin = initscr())) { goto main_fail; } start_color(); f_nLeft = application_windows.pMainWin->_begx; f_nTop = application_windows.pMainWin->_begy; f_nWidth = application_windows.pMainWin->_maxx; f_nHeight = application_windows.pMainWin->_maxy; if (NULL == (application_windows.pTitleWin = newwin(3, f_nWidth, 0, 0))) { goto title_fail; } if (NULL == (application_windows.pProgressWin = newwin(2, f_nWidth, 3, 0))) { goto progress_fail; } if (NULL == (application_windows.pSummaryWin = newwin(1, f_nWidth, 5, 0))) { goto summary_fail; } if (NULL == (application_windows.pRunSummaryWin = newwin(1, f_nWidth, 6, 0))) { goto run_summary_fail; } if (NULL == (application_windows.pDetailsWin = newwin(f_nHeight - f_nTop - 7 , f_nWidth, 7, 0))) { goto details_fail; } if (NULL == (application_windows.pOptionsWin = newwin(1, f_nWidth, f_nHeight - f_nTop, 0))) { goto option_fail; } curs_set(0); noecho(); cbreak(); keypad(application_windows.pMainWin, CU_TRUE); init_pair(CLEAR_COLOR, COLOR_WHITE, COLOR_BLACK); init_pair(TITLE_COLOR, COLOR_WHITE, COLOR_BLACK); init_pair(PROGRESS_BACKGROUND_COLOR, COLOR_BLACK, COLOR_WHITE); init_pair(PROGRESS_SUCCESS_COLOR, COLOR_WHITE, COLOR_GREEN); init_pair(PROGRESS_FAILURE_COLOR, COLOR_WHITE, COLOR_RED); init_pair(MENU_COLOR, COLOR_WHITE, COLOR_BLACK); refresh_windows(); bStatus = true; goto main_fail; /* * Error Handlers for all the stages. */option_fail: delwin(application_windows.pDetailsWin);details_fail: delwin(application_windows.pRunSummaryWin);run_summary_fail: delwin(application_windows.pSummaryWin);summary_fail: delwin(application_windows.pProgressWin);progress_fail: delwin(application_windows.pTitleWin);title_fail: endwin();main_fail: return bStatus;}/*------------------------------------------------------------------------*//** Clean up and delete curses interface windows. */static void uninitialize_windows(void){ curs_set(1); echo(); nocbreak(); keypad(application_windows.pMainWin, CU_FALSE); if (details_pad.pPad) { delwin(details_pad.pPad); } delwin(application_windows.pOptionsWin); delwin(application_windows.pDetailsWin); delwin(application_windows.pRunSummaryWin); delwin(application_windows.pSummaryWin); delwin(application_windows.pProgressWin); delwin(application_windows.pTitleWin); clear(); refresh(); endwin();}/*------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -