自用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放在 ...
随机推荐
- 去除angularjs路由的显眼的#号
在接触到angularj并完成第一个demo后,惊奇地发现居然还可以这样开发前端界面.个人喜欢的一个功能点就是ng的路由功能,可以很好地将视图放入多个文件中.但最基础的使用会给url添加一个显眼的#, ...
- 【练习】数据移动---导出(EXPDP)
1.导出表: [oracle@host03 datadump]$ expdp scott/tiger directory=dir_dp dumpfile=emp.dmp tables=emp; Exp ...
- 关于ckeditor ajax提交到后台 问题
ckeditor 提交时 如果有带有html时是提交不了的 解决办法就是 你在提交的时候 将ckeditor获取的只编码(encodeURI) 然后在传到后台提交的时候 在解码 就ok了 ckname ...
- Android 调用系统联系人界面的添加联系人,添加已有联系人,编辑和修改。
一.添加联系人 Intent addIntent = new Intent(Intent.ACTION_INSERT,Uri.withAppendedPath(Uri.parse("cont ...
- Linux 命令 创建文件
1.vi vi 1.txt 会直接创建并打开一个文件1.txt 2.touch touch的作用是更改一个文件或目录的时间.touch 2.txt 如果2.txt不存在,则创建空文件2.txt 3.e ...
- 普通图片预览及demo(非分块)
演示地址: http://codeman35.itongyin.com:19003/v2/image.html 功能:通过加载大图预览,这种方式无法和google art 比较.只能应用于简单的图片预 ...
- AOP和IOC的作用
IOC:控制反转,是一种设计模式.一层含义是控制权的转移:由传统的在程序中控制依赖转移到由容器来控制:第二层是依赖注入:将相互依赖的对象分离,在spring配置文件中描述他们的依赖关系.他们的依赖关系 ...
- javascript模式之模块模式
使用模式来组织代码有很多优点:使代码的结构更清晰,逻辑性更强,更容易维护.还可以避免很多错误. 首先,在javascript主要分为两大类: 编程模式-- 一些专门为javascript语言开发出的最 ...
- 利用npoi导出Excel
npoi库是当下最流行的处理Excel.Word.PPT等Office文件格式 npoi的下载地址:http://npoi.codeplex.com/ npoi的官方学习地址: http://www. ...
- redis 基本数据类型
概述 Redis的键值可以使用物种数据类型:字符串,散列表,列表,集合,有序集合.本文详细介绍这五种数据类型的使用方法.本文命令介绍部分只是列举了基本的命令,至于具体的使用示例,可以参考Redis官方 ...