自用debug单元
将之前的内存查看单元小幅修改,加上文件操作和计时,组成了一个自用debug单元,使用方法如示例。
此单元便捷之处在于直接将#define DEBUG注释掉而无需改动源码,即可取消debug模式。
#define DEBUG stdi|fileo
#include "debug.h"
using namespace debug;
int main()
{
char str[] = "jiji";
println("this is a %s", str);
}





// mem.h
#ifndef __MEM_H #define __MEM_H #include <stdio.h> #ifndef MEM_DEF_LENGTH #define MEM_DEF_LENGTH (0x80) #endif #include <windows.h> #define BLACK (0) #define BLUE (1) #define GREEN (2) #define RED (4) #define YELLOW (RED|GREEN) #define CYAN (GREEN|BLUE) #define MAGENTA (BLUE|RED) #define WHITE (RED|GREEN|BLUE) #define HL (8) #ifndef HighlightFG #define HighlightFG (WHITE|HL) #endif #ifndef HighlightBG #define HighlightBG (BLACK) #endif void memdispex(FILE* fp, char *srcptr, int size, int len); #include "mem.cpp" #endif
// mem.cpp
void memdispex(FILE* fp, char *srcptr, int size, int len)
{
char *p, *pos;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
fprintf(fp, "\n");
for (pos = (char *)((unsigned int)srcptr & 0xFFFFFFF0);
pos < srcptr + len; pos += 0x10){
fprintf(fp, "%06X: ", pos);
for (p = pos; p < pos + 16; ++p){
if (p >= srcptr && p < srcptr + size){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
(HighlightFG) | (HighlightBG) << 4);
}
if (p < srcptr || p >= srcptr + len)
fprintf(fp, " ");
else if (p == pos + 7)
fprintf(fp, "%02X-", *p & 0xFF);
else
fprintf(fp, "%02X ", *p & 0xFF);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
csbi.wAttributes);
}
fprintf(fp, " ");
for (p = pos; p < pos + 16; ++p){
if (p >= srcptr && p < srcptr + size){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
(HighlightFG) | (HighlightBG) << 4);
}
if (p < srcptr || p >= srcptr + len)
fprintf(fp, " ");
else if (*p < 0x80 && *p >= 0x20)
fprintf(fp, "%c", *p & 0xFF);
else
fprintf(fp, ".");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
csbi.wAttributes);
}
fprintf(fp, "\n");
}
}
// timer.h
#include <ctime>
class TimerBase
{
private:
int _start, _result;
public:
inline void start()
{
_result = 0;
_start = clock();
}
inline void resume()
{
_start = clock();
}
inline int pause()
{
return _result += clock() - _start;
}
inline int stop()
{
return _result += clock() - _start;
}
inline double second()
{
return (double)_result / 1000;
}
inline int tick()
{
return _result;
}
};
// debug.h
#ifndef __DEBUG_H
#define __DEBUG_H
#include <cstdio>
#include <cstdarg>
#include "mem/mem.h"
#include "timer/timer.h"
namespace debug {
#define stdi (1)
#define filei (2)
#define stdo (4)
#define fileo (8)
#define stde (16)
#define stdio (stdi|stdo)
#define fileio (filei|fileo)
#undef __CONFIRM_FILE_INPUT
#undef __CONFIRM_FILE_OUTPUT
#ifdef DEBUG
#if ((DEBUG) & filei) > 0
#define __CONFIRM_FILE_INPUT
#ifndef INPUT
#define INPUT "input.txt"
#endif
#endif
#if ((DEBUG) & fileo) > 0
#define __CONFIRM_FILE_OUTPUT
#ifndef OUTPUT
#define OUTPUT "output.txt"
#endif
#endif
#endif
class DebugFileBase
{
public:
static FILE* fp[256];
};
FILE* DebugFileBase::fp[256] = {};
class FileInitializer: protected DebugFileBase
{
public:
FileInitializer();
~FileInitializer();
} file_initializer;
// IOBase
class InputMethod: protected DebugFileBase
{
public:
InputMethod();
virtual inline void set_device(int);
protected:
int device;
};
class OutputMethod: protected DebugFileBase
{
public:
OutputMethod();
virtual inline void set_device(int);
protected:
int device;
};
// Input Method
class Scan: public InputMethod
{
public:
inline int operator ()(const char* format, ...);
} scan;
// Output Method
class Print: public OutputMethod
{
public:
inline int operator ()(const char* format, ...);
} print;
class Println: public OutputMethod
{
public:
inline int operator ()(const char* format, ...);
} println;
// MemDisplay Method
class Display: public OutputMethod
{
public:
template <typename T>
inline void operator ()(const T&, const int len = (MEM_DEF_LENGTH));
} display;
class DisplayFixed: public OutputMethod
{
public:
template <typename T>
inline void operator ()(const T&);
} display_fixed;
class DisplayAddr: public OutputMethod
{
public:
template <typename T>
inline void operator ()(const T&, const int len = (MEM_DEF_LENGTH));
} display_addr;
// Timer
class Timer: public TimerBase
{
public:
inline int halt();
} timer;
}
#include "debug.cpp"
#endif
// debug.cpp
debug::FileInitializer::FileInitializer()
{
fp[stdi] = stdin;
fp[stdo] = stdout;
fp[stde] = stderr;
#ifdef __CONFIRM_FILE_INPUT
fp[filei] = fopen(INPUT, "r");
#endif
#ifdef __CONFIRM_FILE_OUTPUT
fp[fileo] = fopen(OUTPUT, "w");
#endif
}
debug::FileInitializer::~FileInitializer()
{
#ifdef __CONFIRM_FILE_INPUT
fclose(fp[filei]);
#endif
#ifdef __CONFIRM_FILE_OUTPUT
fclose(fp[fileo]);
#endif
}
debug::InputMethod::InputMethod()
{
#ifdef __CONFIRM_FILE_INPUT
device = filei;
#else
device = stdi;
#endif
}
inline void debug::InputMethod::set_device(int tag)
{
device = tag & filei ? filei : stdi;
}
debug::OutputMethod::OutputMethod()
{
#ifdef __CONFIRM_FILE_OUTPUT
device = fileo;
#else
#ifdef DEBUG
#if (DEBUG & stde) > 0
device = stde;
#else
device = stdo;
#endif
#else
device = stdo;
#endif
#endif
}
inline void debug::OutputMethod::set_device(int tag)
{
device = tag & fileo ? fileo :
tag & stde ? stde : stdo;
}
inline int debug::Scan::operator ()(const char* format, ...)
{
#ifdef DEBUG
va_list args;
va_start(args, format);
return vfscanf(fp[device], format, args);
#else
return 0;
#endif
}
inline int debug::Print::operator ()(const char* format, ...)
{
#ifdef DEBUG
va_list args;
va_start(args, format);
int val = vfprintf(fp[device], format, args);
fflush(fp[device]);
return val;
#else
return 0;
#endif
}
inline int debug::Println::operator ()(const char* format, ...)
{
#ifdef DEBUG
va_list args;
va_start(args, format);
int val = vfprintf(fp[device], format, args);
fprintf(fp[device], "\n");
fflush(fp[device]);
return val;
#else
return 0;
#endif
}
template <typename T>
inline void debug::Display::operator ()(const T& src, const int len)
{
#ifdef DEBUG
memdispex(fp[device], (char*)&src, sizeof(src), len);
#endif
}
template <typename T>
inline void debug::DisplayFixed::operator ()(const T& src)
{
#ifdef DEBUG
memdispex(fp[device], (char*)&src, sizeof(src), sizeof(src));
#endif
}
template <typename T>
inline void debug::DisplayAddr::operator ()(const T& src, const int len)
{
#ifdef DEBUG
memdispex(fp[device], (char*)src, 0, len);
#endif
}
inline int debug::Timer::halt()
{
int val = stop();
#ifdef DEBUG
println("Time: %dms", val);
#endif
return val;
}
自用debug单元的更多相关文章
- delphi一些小技巧 从别处看到
开发环境-------- Delphi 7是一个很经典的版本,在Win2000/XP下推荐安装Delphi 7来开发软件,在Vista下推荐使用Delphi 2007开发软件.安装好Delphi ...
- (转载)Delphi开发经验谈
Delphi开发经验谈 开发环境-------- Delphi 7是一个很经典的版本,在Win2000/XP下推荐安装Delphi 7来开发软件,在Vista下推荐使用Delphi 2007开发软件. ...
- jmeter sampler maven项目排错记
eclipse 创建的maven项目,引入jar包之后出现红色叹号,一直找不到原因,连main方法都无法运行,提示找不到类: 错误: 找不到或无法加载主类 soapsampler.SoapSample ...
- c++debug&注意事项 自用 持续更新
cin后回车程序直接退出: 加system("pause");在return 0;前面 C++ 控制cout输出的小数位数 C++中的cout.setf().cout.precis ...
- jquery操作表格 合并单元格
jquery操作table,合并单元格,合并相同的行 合并的方法 $("#tableid").mergeCell({ cols:[X,X] ///参数为要合并的列}) /** * ...
- 汇编语言基础 debug的使用
-r 查看,改变CPU寄存器的内容 -r 加上寄存器名 在:后输入要写入的数据后 完成更改 debug 随着CS IP的改变 对应的汇编指令也不同 -r ip -r cs修改 ip cs 的值 d 段 ...
- debug命令简介
debug命令不区分大小,debug的命令都是一个字母,后跟或不跟参数 1.debug [路径\文件] [参数] [参数]--[参数] debug相应程序 2. D(Dump) [地址] [范围] 显 ...
- Eclipse Debug
[IT168 专稿]调试的方法虽然千千万万,但归根结底,就是找到引发错误的代码.Eclipse调试器的目标是让程序员能对本地或远程程序进行错误侦测与诊断.该调试器提供所有标准调试功能,包括进行单步执行 ...
- 汇编基础知识之二debug的使用
DEBUG的使用 (要在win32位习题下进行,win7 64位需要安装DosBox和debug这2个软件): 1:win64位下debug的使用教程: 下载debug.exe,这里我把debug放在 ...
随机推荐
- Python-8 元组tuple
#1 特殊的列表:元组 元组中的元素不可改变 #2 创建.访问 >>> tuple1=(1,2,3) >>> tuple1=1,2,3 >>> t ...
- winserver2008 R2 64位 企业版 , IIS 配置运行 asp+access 网站
新建网站,程序池由DefaultAppPool 改为 Classic .NET AppPool, 并在 高级设置中,把启用 32位应用程序 设为 true 对 access 所在目录新加 every ...
- (转)Silverlight 与 JS交互
转自 http://www.cnblogs.com/wt616/archive/2011/10/08/2201987.html 1.Silverlight直接调用JS的函数: 这个很简单,只要在HTM ...
- JAVA Socket 编程学习笔记(二)
在上一篇中,使用了 java Socket+Tcp/IP 协议来实现应用程序或客户端--服务器间的实时双向通信,本篇中,将使用 UDP 协议来实现 Socket 的通信. 1. 关于UDP UDP协 ...
- sublime安装插件步骤
sublime text 3 安装package contol: 快捷键:ctrl+`进入命令行输入 import urllib.request,os;pf='Package Control.sub ...
- Samba日志分析
Samba日志分析 随着我们文件共享安全级别的提高,越来越多的情况下需要对日志进行记录并审计.Linux平台下的Samba服务的配置文件是smb.conf,有不少图形化配置工具例如Webmin.smb ...
- android-----test------模拟来电提醒和短信提醒
为了测试应用是否能处理来电提醒和短信提醒时正常处理,我们需要做个测试,怎么模拟来电提醒和短信提醒呢?? 采用Telnet 命令来模拟. 1.首先看看Telnet 命令是否可以使用,如果不可以使用,则需 ...
- Windows Azure初体验
目前在IT界,云这个概念的第一意思不再是词典里的解释了.不过它们还是有相同点的——也许确实会酝酿出一块大蛋糕,可也是飘在天上,众神分食之,与我等P民无关.所谓云,不过是网络时代发展到一定阶段的必然产物 ...
- Jquery day01
day01: 基础--选择器.属性和CSS.文档处理 day02: 高级--筛选.事件.效果.ajax jQuery介绍 JS类库 JavaScript 库封装了很多预定义的对象和实用函数.能帮助使用 ...
- 关于GPL的一些知识
1.什么是GPL GPL许可协议(GNU General Public License):只要软件中包含有其他GPL协议的产品或代码,那么该软件就必须也采用GPL许可协议且开源及免费.具有以下特点: ...