Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Свой assert, C++Builder 6.0 и Visual C++ 2008 
V
    Опции темы
Alca
Дата 30.3.2009, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



Свой assert, может кому сгодиться, жду критики:

xassert.h
Код

/****************************************************************************
*    xassert.h
*
*****************************************************************************/


#ifndef XASSERT_H
#define XASSERT_H
//---------------------------------------------------------------------------
#include <stddef.h>
//---------------------------------------------------------------------------
#ifdef NDEBUG
    #define XASSERT   (ignore) ((void)0)
    #define XASSERT_EX(ignore) ((void)0)
#else /*NDEBUG*/
    void vAssert(const char *pcszExp, unsigned long int ulLastError, const char *pcszFile, unsigned long int ulLine, const char *pcszFunc, const char *pcszComment = NULL);

    #ifndef __FILE__
    #    define __FILE__ "<unknown>"
    #endif

    #ifndef __LINE__
    #    define __LINE__ "<unknown>"
    #endif

    #ifndef __FUNCTION__
    #    define __FUNCTION__ __FUNC__
    #endif

    #ifndef __FUNC__
    #    define __FUNC__ "<unknown>"
    #endif

    #define XASSERT(exp)             ((exp) ? (void)0 : (vAssert(#exp, ::GetLastError(), __FILE__, __LINE__, __FUNCTION__),          (void)0))
    #define XASSERT_EX(exp, comment) ((exp) ? (void)0 : (vAssert(#exp, ::GetLastError(), __FILE__, __LINE__, __FUNCTION__, comment), (void)0))
#endif /*NDEBUG*/
//---------------------------------------------------------------------------
#endif /*XASSERT_H*/




xassert.cpp
Код

/****************************************************************************
*    xassert.cpp
*
*****************************************************************************/


#include <windows.h>
#include <string> 
//---------------------------------------------------------------------------
std::string sCutFirstDirectory(const std::string &csS) {
    std::string S;
    S.assign(csS);    

    bool   bRoot = false;
    size_t P     = - 1;

    if ("\\" == S) {
        S.clear();
    } else {
        if (S[0] == '\\') {
            bRoot = true;
            S.erase(0, 1);
        } else {
            bRoot = false;
        }

        if ('.' == S[0]) {
            S.erase(0, 4);
        }

        P = S.find_first_of("\\") + 1;

        if (std::string::npos != P) {
            S.erase(0, P);
            S = "...\\" + S;        
        } else {
            S.clear();
        }

        if (bRoot) {
            S = "\\" + S;
        }
    }

    return S;
}
//---------------------------------------------------------------------------
std::string sMinimizeName(const std::string &csFilePath, size_t uiMaxLen) {
    std::string sRes   = csFilePath;    

    TCHAR szDrive[MAX_PATH];    ZeroMemory(szDrive, sizeof(szDrive));
    TCHAR szDir  [MAX_PATH];    ZeroMemory(szDir,   sizeof(szDir));
    TCHAR szName [MAX_PATH];    ZeroMemory(szName,  sizeof(szName));
    TCHAR szExt  [MAX_PATH];    ZeroMemory(szExt,   sizeof(szExt));
    _splitpath(csFilePath.c_str(), szDrive, szDir, szName, szExt);    

    std::string sDrive = std::string(szDrive);
    std::string sDir   = std::string(szDir);
    std::string sName  = std::string(szName) + std::string(szExt);

    //while ((Dir <> '') or (Drive <> '')) and (Canvas.TextWidth(Result) > MaxLen) do
    while (((!sDir.empty()) || (!sDrive.empty())) && (sRes.size()/*sDir.size()*/ > uiMaxLen)) { 
        if ("\\...\\" == sDir ) {
            sDrive.clear();
            sDir = "...\\";
        } else if (sDir.empty()) {
            sDrive.clear();
        } else {
            sDir = sCutFirstDirectory(sDir);          
        }

        sRes = sDrive + sDir + sName;
    }

    return sRes;
}
//---------------------------------------------------------------------------
void vAssert(const char *pcszExp, unsigned long int ulLastError, const char *pcszFile, unsigned long int ulLine, const char *pcszFunc, const char *pcszComment) {
    //-------------------------------------
    //путь к exe-шнику
    TCHAR szExePath[MAX_PATH];    ::ZeroMemory(szExePath, sizeof(szExePath));
    if (!::GetModuleFileName(::GetModuleHandle(NULL), szExePath, MAX_PATH) || 0 == ::lstrlen(szExePath)) {
        ::MessageBox(0, "GetModuleFileName() - fail", "xassert - system message", MB_ICONERROR | MB_OK);
        return;
    }

    //-------------------------------------
    //путь к имя exe-шника
    TCHAR szExeName[MAX_PATH];    ::ZeroMemory(szExeName, sizeof(szExeName));
    _splitpath(szExePath, NULL, NULL, szExeName, NULL);
    if (NULL == szExeName || 0 == ::lstrlen(szExeName)) {
        ::MessageBox(0, "_splitpath() - fail", "xassert - system message", MB_ICONERROR | MB_OK);
        return;
    }

    //-------------------------------------
    //форматируем GetLastError()
    LPVOID lpMsgBuf = NULL;
    ::FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        ulLastError,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),  //язык по умолчанию
        (LPSTR)&lpMsgBuf,
        0,
        NULL);
    if (NULL == lpMsgBuf || 0 == ::lstrlen((LPSTR)lpMsgBuf)) {
        ::MessageBox(0, "FormatMessage() - fail", "xassert - system message", MB_ICONERROR | MB_OK);
        return;
    }

    //-------------------------------------
    //форматиркем сообщение
    const unsigned int cuiMsgSize = 2024; 
    TCHAR              szMsg[cuiMsgSize];    ::ZeroMemory(szMsg, sizeof(szMsg));
    ::wsprintf(szMsg,
             "%s\n\n"
             "%s:  %s\n"
             "%s:  %s\n"
             "%s:  %i\n"
             "%s:  %s\n"
             "%s:  %s\n"
             "%s:  %s"        /*здесь типа \n не надо*/
             "%s:  %s",             
             
             "Assertion failed.",
             "Program",           sMinimizeName(szExePath, 75).c_str(),
             "File",              sMinimizeName(pcszFile,  75).c_str(),
             "Line",              ulLine,
             "Function",          pcszFunc,
             "Expression",        pcszExp,
             "GetLastError()",    (LPSTR)lpMsgBuf,
             "Comment",           pcszComment 
    );

    if (NULL == szMsg || 0 == ::lstrlen(szMsg)) {
        ::MessageBox(0, "wsprintf() - fail", "xassert - system message", MB_ICONERROR | MB_OK);
        return;
    }

    if (NULL != lpMsgBuf) {
        ::LocalFree(lpMsgBuf);    lpMsgBuf = NULL;
    }

    //-------------------------------------
    //выводим MessageBox
    int iRes = ::MessageBox(NULL, szMsg, szExeName, MB_ABORTRETRYIGNORE | MB_ICONSTOP);
    switch (iRes) {
        case IDABORT: {
         exit(- 1);
            break;
        }
        case IDRETRY: {
            _asm {
                int 3
            } 
            break;
        }
        case IDIGNORE: {
            break;
        }
    }
}
//---------------------------------------------------------------------------


Добавлено через 2 минуты и 48 секунд
Использование:
Код

#include "xassert.h"

char *pTest = NULL;
XASSERT   (NULL != pTest);
XASSERT_EX(NULL != pTest, "нулевой поинтер");


Добавлено через 4 минуты и 17 секунд
Код

Результат:
---------------------------
ConsoleTest
---------------------------
Assertion failed.

Program:  f:\...\_MyProjects\MyVC++\Projects\xassert\Project\Debug\ConsoleTest.exe
File:  f:\mycd\!!!!!!!!\_myprojects\myvc++\projects\xassert\project\umain.cpp
Line:  36
Function:  main
Expression:  NULL != pTest
GetLastError():  Операция успешно завершена.

Comment:  
---------------------------
Прервать   Повтор   Пропустить   
---------------------------


---------------------------
ConsoleTest
---------------------------
Assertion failed.

Program:  f:\...\_MyProjects\MyVC++\Projects\xassert\Project\Debug\ConsoleTest.exe
File:  f:\mycd\!!!!!!!!\_myprojects\myvc++\projects\xassert\project\umain.cpp
Line:  37
Function:  main
Expression:  NULL != pTest
GetLastError():  Операция успешно завершена.

Comment:  нулевой поинтер
---------------------------
Прервать   Повтор   Пропустить   
---------------------------


Это сообщение отредактировал(а) Alca - 30.3.2009, 21:13

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  xassert.zip 0,47 Kb


--------------------
PM WWW ICQ Skype Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0603 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.