├── .gitignore ├── LICENSE ├── README.cn.md ├── README.md ├── google └── gtest │ ├── gtest-death-test.h │ ├── gtest-message.h │ ├── gtest-param-test.h │ ├── gtest-param-test.h.pump │ ├── gtest-printers.h │ ├── gtest-spi.h │ ├── gtest-test-part.h │ ├── gtest-typed-test.h │ ├── gtest.h │ ├── gtest_pred_impl.h │ ├── gtest_prod.h │ └── internal │ ├── gtest-death-test-internal.h │ ├── gtest-filepath.h │ ├── gtest-internal.h │ ├── gtest-linked_ptr.h │ ├── gtest-param-util-generated.h │ ├── gtest-param-util-generated.h.pump │ ├── gtest-param-util.h │ ├── gtest-port.h │ ├── gtest-string.h │ ├── gtest-tuple.h │ ├── gtest-tuple.h.pump │ ├── gtest-type-util.h │ └── gtest-type-util.h.pump ├── tracer.sln ├── tracer ├── arg_recorder.hpp ├── call_count_recorder.hpp ├── call_stack_recorder.hpp ├── dbg_helper.cpp ├── dbg_helper.h ├── detours │ ├── creatwth.cpp │ ├── detours.cpp │ ├── detours.h │ ├── detver.h │ ├── disasm.cpp │ ├── image.cpp │ ├── modules.cpp │ ├── syelog.h │ └── uimports.cpp ├── fake_func_keeper.hpp ├── function_type.hpp ├── hook_impl.cpp ├── hook_impl.h ├── hook_manager.cpp ├── hook_manager.h ├── mixin_tracer.hpp ├── real_func_keeper.hpp ├── ret_val_recorder.hpp ├── signal.hpp ├── signal_keeper.hpp ├── singleton.hpp ├── trace.hpp ├── tracer.h ├── tracer.vcxproj └── tracer.vcxproj.filters └── tracer_test ├── dbg_helper_test.cpp ├── function_type_test.cpp ├── gtest-all.cc ├── hook_manager_test.cpp ├── recorder_test.cpp ├── src ├── gtest-death-test.cc ├── gtest-filepath.cc ├── gtest-internal-inl.h ├── gtest-port.cc ├── gtest-printers.cc ├── gtest-test-part.cc ├── gtest-typed-test.cc ├── gtest.cc └── gtest_main.cc ├── trace_test.cpp ├── tracer_test.vcxproj └── tracer_test.vcxproj.filters /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | 11 | [Dd]ebug/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | [Bb]in/ 16 | [Oo]bj/ 17 | 18 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 19 | !packages/*/build/ 20 | 21 | # MSTest test Results 22 | [Tt]est[Rr]esult*/ 23 | [Bb]uild[Ll]og.* 24 | 25 | *_i.c 26 | *_p.c 27 | *.ilk 28 | *.meta 29 | *.obj 30 | *.pch 31 | *.pdb 32 | *.pgc 33 | *.pgd 34 | *.rsp 35 | *.sbr 36 | *.tlb 37 | *.tli 38 | *.tlh 39 | *.tmp 40 | *.tmp_proj 41 | *.log 42 | *.vspscc 43 | *.vssscc 44 | .builds 45 | *.pidb 46 | *.log 47 | *.scc 48 | 49 | # Visual C++ cache files 50 | ipch/ 51 | *.aps 52 | *.ncb 53 | *.opensdf 54 | *.sdf 55 | *.cachefile 56 | 57 | # Visual Studio profiler 58 | *.psess 59 | *.vsp 60 | *.vspx 61 | 62 | # Guidance Automation Toolkit 63 | *.gpState 64 | 65 | # ReSharper is a .NET coding add-in 66 | _ReSharper*/ 67 | *.[Rr]e[Ss]harper 68 | 69 | # TeamCity is a build add-in 70 | _TeamCity* 71 | 72 | # DotCover is a Code Coverage Tool 73 | *.dotCover 74 | 75 | # NCrunch 76 | *.ncrunch* 77 | .*crunch*.local.xml 78 | 79 | # Installshield output folder 80 | [Ee]xpress/ 81 | 82 | # DocProject is a documentation generator add-in 83 | DocProject/buildhelp/ 84 | DocProject/Help/*.HxT 85 | DocProject/Help/*.HxC 86 | DocProject/Help/*.hhc 87 | DocProject/Help/*.hhk 88 | DocProject/Help/*.hhp 89 | DocProject/Help/Html2 90 | DocProject/Help/html 91 | 92 | # Click-Once directory 93 | publish/ 94 | 95 | # Publish Web Output 96 | *.Publish.xml 97 | *.pubxml 98 | 99 | # NuGet Packages Directory 100 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 101 | #packages/ 102 | 103 | # Windows Azure Build Output 104 | csx 105 | *.build.csdef 106 | 107 | # Windows Store app package directory 108 | AppPackages/ 109 | 110 | # Others 111 | sql/ 112 | *.Cache 113 | ClientBin/ 114 | [Ss]tyle[Cc]op.* 115 | ~$* 116 | *~ 117 | *.dbmdl 118 | *.[Pp]ublish.xml 119 | *.pfx 120 | *.publishsettings 121 | 122 | # RIA/Silverlight projects 123 | Generated_Code/ 124 | 125 | # Backup & report files from converting an old project file to a newer 126 | # Visual Studio version. Backup files are not needed, because we have git ;-) 127 | _UpgradeReport_Files/ 128 | Backup*/ 129 | UpgradeLog*.XML 130 | UpgradeLog*.htm 131 | 132 | # SQL Server files 133 | App_Data/*.mdf 134 | App_Data/*.ldf 135 | 136 | # ========================= 137 | # Windows detritus 138 | # ========================= 139 | 140 | # Windows image file caches 141 | Thumbs.db 142 | ehthumbs.db 143 | 144 | # Folder config file 145 | Desktop.ini 146 | 147 | # Recycle Bin used on file shares 148 | $RECYCLE.BIN/ 149 | 150 | # Mac crap 151 | .DS_Store 152 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 QingYun 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.cn.md: -------------------------------------------------------------------------------- 1 | Tracer 2 | ====== 3 | 4 | A simple hook library for testing and debuging 5 | 6 | Introduction 7 | --- 8 | 9 | Tracer可以让你在不修改代码的前提下, 在指定函数调用前后以回调的形式插入代码. 10 | 11 | Usage 12 | --- 13 | 14 | 首先, 包含头文件`tracer/tracer.h`, 然后配置一下Boost路径. 15 | 16 | ###Tracers 17 | 18 | 使用`TRACER_TRACE(func)`来定义一个变量, 这个变量我们称之为一个`tracer`, `func`应该是一个求值为函数指针的表达式, 我们称之为原始函数. 19 | 20 | 这个宏展开后是一个类: 21 | 22 | TRACER_TRACE(&Foo) foo; 23 | // 等价于 24 | typedef TRACER_TRACE(&Foo) FooTracer; 25 | FooTracer foo; 26 | 27 | `tracer`有三个公开的方法: 28 | 29 | - **Before()** 30 | 31 | 返回一个`tracer::Signal`对象的引用, 它会在调用原始函数前被触发. 32 | 33 | `tracer::Signal`派生自`boost.signals2`, 可以使用其所有公开接口, 比如使用`connect(callback)`注册一个回调, 这个回调会在每次信号被触发时被调用. 34 | 35 | 回调应该是一个没有返回值的可调用对象, 其第一个参数应该是`bool&`类型的, 表示是否想要调用原始函数, 将其赋值为`false`将不会调用原始函数; 如果原始函数是一个类的非静态成员函数, 则第二个参数应该是类指针的引用, 传入时它的值即为`this`, 在回调中可以修改它, 将其指向其他对象, 这样可以将调用转移到其他对象上; 剩下的参数依次是原始函数参数的引用, 它们都可以在回调中被修改. 36 | 37 | 比如原始函数的签名为`int(int)`, 则回调的类型应该是`void(bool&, int&)` 38 | 39 | - **After()** 40 | 41 | 返回一个`tracer::Signal`对象的引用, 它会在调用原始函数后被触发. 42 | 43 | 回调类型类似于`Before()`的回调, 但是第一个参数应该是`bool`的, 表示是否已经调用了原始函数, 接下来是返回值的引用, 剩下的和`Before()`一样 44 | 45 | - **RealFunc()** 46 | 47 | 返回一个和原始函数签名一样的函数指针, 调用这个指针可以避免触发信号, 直接调用原始函数. 48 | 49 | 除了`boost.signals2`原有的接口, `tracer::Signal`还提供了两个新的方法: 50 | 51 | - `once(cb)` : 类似于`connect`, 但是这个回调会在被触发一次之后自动断开连接 52 | - `connect_without_params(cb)` : 类似于`connect`, 但是回调的签名应该是`void()`的. 53 | 54 | **示例**: 55 | 56 | class C { 57 | std::string str_; 58 | public: 59 | C(const std::string &str) : 60 | str_(str) 61 | {} 62 | std::string Get() { 63 | return str_; 64 | } 65 | }; 66 | 67 | int main() { 68 | TRACER_TRACE(&C::Get) t; 69 | C a("A"), b("B"); 70 | 71 | // 注册一个在C::Get调用前被调用回调, conn是回调的链接管理器 72 | auto conn = t.Before().connect([&b] (bool&, C *&self) { 73 | // 将所有对C::Get的调用都无条件转移到对象b身上 74 | self = &b; 75 | }); 76 | 77 | std::string result = a.Get(); // result == "B" 78 | conn.disconnect(); 79 | result = a.Get(); // result == "A" 80 | } 81 | 82 | 83 | 传递给宏的可以是任意求值为函数指针的表达式, 因此如果需要追踪有多个重载版本的函数的某一重载版本, 84 | 只需传递`static_cast(&func_name)`即可, 这个技巧还可以用来处理那些在编译期只知道类型, 地址在运行期才能获取的函数 85 | 86 | - - - 87 | 88 | ###Recorders 89 | 90 | `recorder`是用来记录`tracer`调用情况的类. 91 | 92 | ####CallCountRecorder 93 | 94 | 记录调用次数. 95 | 96 | 可以使用`CallCountRecorder recorder(tracer)` 或者 `auto recorder = RecordCallCount(tracer)`创建, 97 | 它有两个公开方法: 98 | 99 | - `bool HasBeenCalled()` : 返回一个`bool`值表示原始函数是否被调用过. 100 | - `std::size_t CallCount()` : 返回原始函数被调用的次数. 101 | 102 | ####ArgRecorder 103 | 104 | 记录传递给原始函数的所有参数 105 | 106 | 可以使用`ArgRecorder recorder(tracer)` 或者 `auto recorder = RecordArgs(tracer)`创建, 它有一个公开方法: 107 | 108 | - `nth-param-type Arg(n)` : 返回开始记录后第`n`次调用时的第`I`个参数. 109 | 110 | ####RetValRecorder 111 | 112 | 记录函数的返回值 113 | 114 | 可以使用`RetValRecorder recorder(tracer)` 或者 `auto recorder = RecordRetVal(tracer)`创建, 115 | 它有一个公开方法: 116 | 117 | - `ret-val-type RetVal(n)` : 返回开始记录后第`n`次调用时的返回值 118 | 119 | ####CallStackRecorder 120 | 121 | 记录调用栈 122 | 123 | 可以使用`CallStackRecorder recorder(tracer)` 或者 `auto recorder = RecordCallStack(tracer)`创建, 124 | 它有一个公开方法 : 125 | 126 | - `CallStack GetCallStack(n)` : 返回开始记录后第`n`次调用时的调用栈. 127 | 128 | `CallStack`对象有两个公开方法 : 129 | 130 | - `vector Entries()` : 返回整个调用栈记录, `Entries()[0]`是原始函数的调用者, `Entries()[1]`是原始函数调用者的调用者, 依此类推 131 | 132 | `CallStackEntry`对象有4个公开方法: 133 | 134 | - `File()` : 返回函数所在的文件名称 135 | - `Line()` : 返回函数在文件中的行号 136 | - `FuncName()` : 返回函数名 137 | - `FuncAddr()` : 返回函数地址 138 | 139 | - `bool IsCalledBy(f)` : `f`可以是字符串形式的函数名或者是函数指针, 如果在调用栈中找到匹配项则返回`true`, 否则返回`false`. 140 | 141 | 示例: 142 | 143 | struct C { 144 | void Foo() {} 145 | }; 146 | 147 | void RunFoo() { 148 | C c; 149 | c.Foo(); 150 | } 151 | 152 | int main() { 153 | TRACER_TRACE(&C::Foo) foo; 154 | auto fc = tracer::RecordCallStack(foo); 155 | 156 | RunFoo(); 157 | 158 | // 输出第一次调用中各个调用者的信息 159 | for (auto itr : fc.GetCallStack(0).Entries()) 160 | std::cout << itr.File() << " " << itr.Line() << " " << itr.FuncName() << std::endl; 161 | 162 | // 检查第一次调用时调用栈中是否有名为"RunFoo"的调用者 163 | assert(true == fc.GetCallStack(0).IsCalledBy("RunFoo")); 164 | 165 | void(*f)(); 166 | f = [] () { RunFoo(); }; 167 | f(); 168 | // 通过比较函数地址检查第二次调用时是否有调用者f 169 | assert(true == fc.GetCallStack(1).IsCalledBy(f)); 170 | } 171 | 172 | - - - 173 | 174 | ###Mixin Tracer 175 | 176 | 使用`TRACER_TRACE_WITH`可以把 tracer 和 recorder 的功能混合到一起. 177 | 178 | 这个宏接受两个参数, 第一个参数是函数名, 第二个宏是要混合的 recorder 列表, 是`(recorder1)(recorder2)`形式的. 179 | 比如要记录`C::Foo`的调用次数和调用栈, 可以这样写 180 | 181 | TRACER_TRACE_WITH(C::Foo, (tracer::CallCountRecorder)(tracer::CallStackRecorder)) foo; 182 | 183 | `foo`继承了这两个 recorder 的接口, 所以你可以用`foo.Before().connect()`插入调用前的回调, 也可以用`foo.HasBeenCalled()`判断`C::Foo`是否被调用过, 还可以用`foo.GetCallStack()`来获取调用栈. 184 | 185 | 除了内置的 recorder 以外, 只要是用`Recorder::Recorder(T&)`形式构造的自定义 recorder 也可以用`TRACER_TRACE_WITH`混合. 186 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Tracer 2 | ====== 3 | 4 | A C++ library that enables you to decorate a function at runtime. 5 | 6 | Introduction 7 | --- 8 | 9 | Tracer can insert callbacks before or after a call to a given function without the need of modifying its code. [中文版](https://github.com/QingYun/tracer/blob/master/README.cn.md) 10 | 11 | Usage 12 | --- 13 | 14 | Include `tracer/tracer.h` and add the path to Boost into the include directories option. 15 | 16 | ###Tracers 17 | 18 | Use `TRACER_TRACE(func)` as a type name to define a variable, which could be called a `tracer`, `func` is a function pointer and we call it the original function. 19 | 20 | This `TRACER_TRACE` macro will expand to a class: 21 | 22 | TRACER_TRACE(&Foo) foo; 23 | 24 | // equals to 25 | typedef TRACER_TRACE(&Foo) FooTracer; 26 | FooTracer foo; 27 | 28 | A `tracer` has three public methods: 29 | 30 | - **Before()** 31 | 32 | Returns a reference to a `tracer::Signal` object, this signal will be triggered just before the original function being called. 33 | 34 | `tracer::Signal` derives from `boost.signals2`, so you can use all its public methods, like using `connect(callback)` to register a new callback which will be called every time when this signal is triggered. 35 | 36 | The callback should not return anything so its signature is like `void(bool&, ...)`. The first parameter is always a `bool&`, a flag with a default value of `true`, indicates if the original function should be called, so if you don't want the original function to be called, just simply assign `false` to it; remained parameters are references to the arguments to the original function, in the same order. If the original function is a non-static function member, then there will be a extra parameter as the second parameter, wich is the reference to `this` 37 | 38 | Examples: 39 | 40 | - `int(int)` => `void(bool&, int&)` 41 | - `std::string (C::*)(std::string)` => `void(bool&, C*&, std::string&)` 42 | 43 | - **After()** 44 | 45 | Returns a reference to a `tracer::Signal` object which will be triggered after the original function is called 46 | 47 | The callback signature is almost the same as the one for `Before()`, the only difference is the first parameter becomes a `bool` instead of a `bool&` to indicates whether the original function has been called and the second parameter will be a reference to its return value. 48 | 49 | - **RealFunc()** 50 | 51 | Returns a function pointer that has the same signature as the original function and invocations to this function pointer will be directly directed to the original function without triggering callbacks. 52 | 53 | Besides methods inherited from `boost.signals2`, there are two new methods in `tracer::Signal`: 54 | 55 | - `once(cb)` : like `connect` but the callback will be disconnected automatically after the first invocation. 56 | - `connect_without_params(cb)` : like `connect` but always receives a `void()` function. It's very handy when you have no interests in parameters. 57 | 58 | **example code**: 59 | 60 | class C { 61 | std::string str_; 62 | public: 63 | C(const std::string &str) : 64 | str_(str) 65 | {} 66 | std::string Get() { 67 | return str_; 68 | } 69 | }; 70 | 71 | int main() { 72 | TRACER_TRACE(&C::Get) t; 73 | C a("A"), b("B"); 74 | 75 | // conn is for managing connection state 76 | auto conn = t.Before().connect([&b] (bool&, C *&self) { 77 | // forward all the calls to b 78 | self = &b; 79 | }); 80 | 81 | std::string result = a.Get(); // result == "B" 82 | conn.disconnect(); 83 | result = a.Get(); // result == "A" 84 | } 85 | 86 | 87 | It doesn't matter whether the argument passed to the `TRACER_TRACE` macro is just a variable or a complex expression, as long as it evaluates to a function pointer. That means if you want to trace a certain function with a set of overloaded functions, you can just convert it to the signature you want, like `static_cast(&func_name)`. It also very useful when you try to trace a function you only got its signature at compile-time and you don't know its address until run-time, such as functions in a COM component. 88 | 89 | - - - 90 | 91 | ###Recorders 92 | 93 | Some helper classes to record calling information of a traced function. 94 | 95 | ####CallCountRecorder 96 | 97 | Record how many times a function is called. 98 | 99 | You can use `CallCountRecorder recorder(tracer)` or `auto recorder = RecordCallCount(tracer)` to create one. 100 | 101 | It has two public methods: 102 | 103 | - `bool HasBeenCalled()` : Returns a `bool` value indicates whether this function is called at least once. 104 | - `std::size_t CallCount()` : Returns the exact times. 105 | 106 | ####ArgRecorder 107 | 108 | Record all the arguments passed. 109 | 110 | You can use `ArgRecorder recorder(tracer)` or `auto recorder = RecordArgs(tracer)` to create one. 111 | 112 | It has one public method: 113 | 114 | - `nth-param-type Arg(n)` : Returns the `I`th argument in the `n`th call. 115 | 116 | ####RetValRecorder 117 | 118 | Record the return value. 119 | 120 | `RetValRecorder recorder(tracer)` or `auto recorder = RecordRetVal(tracer)` 121 | 122 | - `ret-val-type RetVal(n)` : Returns the return value of the `n`th call. 123 | 124 | ####CallStackRecorder 125 | 126 | Record the call stack 127 | 128 | `CallStackRecorder recorder(tracer)` or `auto recorder = RecordCallStack(tracer)` 129 | 130 | - `CallStack GetCallStack(n)` : Returns the call stack of the `n`th call. 131 | 132 | `CallStack` has two public methods : 133 | 134 | - `vector Entries()` : Returns all the records, `Entries()[0]` is the direct caller of the original function, `Entries()[1]` is the caller's caller and so on. 135 | 136 | `CallStackEntry` has four public methods: 137 | 138 | - `File()` : Returns the name of the file. 139 | - `Line()` : Returns the line number 140 | - `FuncName()` : The name of the function 141 | - `FuncAddr()` : The address of the function 142 | 143 | - `bool IsCalledBy(f)` : Returns a `bool` value indicates whether the function `f` appears in the recorded call stack. `f` could be a function name as a string or a function pointer 144 | 145 | Example: 146 | 147 | struct C { 148 | void Foo() {} 149 | }; 150 | 151 | void RunFoo() { 152 | C c; 153 | c.Foo(); 154 | } 155 | 156 | int main() { 157 | TRACER_TRACE(&C::Foo) foo; 158 | auto fc = tracer::RecordCallStack(foo); 159 | 160 | RunFoo(); 161 | 162 | // print the information of the direct caller 163 | for (auto itr : fc.GetCallStack(0).Entries()) 164 | std::cout << itr.File() << " " << itr.Line() << " " << itr.FuncName() << std::endl; 165 | 166 | // check caller by name 167 | assert(true == fc.GetCallStack(0).IsCalledBy("RunFoo")); 168 | 169 | void(*f)(); 170 | f = [] () { RunFoo(); }; 171 | f(); 172 | // or by function pointer 173 | assert(true == fc.GetCallStack(1).IsCalledBy(f)); 174 | } 175 | 176 | - - - 177 | 178 | ###Mixin 179 | 180 | The macro `TRACER_TRACE_WITH` could mix the functions of tracer and recorder. It expects two arguments, a function pointer just like the one you would pass into `TRACER_TRACE`, and a list of recorder in the form of `(RecorderType1)(RecorderType2)`. 181 | 182 | To record how many times the function `C::Foo` is called as well as its call stacks, you write: 183 | 184 | TRACER_TRACE_WITH(C::Foo, (tracer::CallCountRecorder)(tracer::CallStackRecorder)) foo; 185 | 186 | Then, `foo` will inherit all the public methods of `CallCountRecorder` and `CallStackRecorder`. That means you can use `foo.Before().connect()` to insert a callback; use `foo.HasBeenCalled()` check whether it is called and `foo.GetCallStack()` to see the call stacks. 187 | 188 | As you may expect, you can also mix your own recorder into a tracer as long as it has a constructor with the signature of `Recorder::Recorder(TracerType&)` -------------------------------------------------------------------------------- /google/gtest/gtest-death-test.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // The Google C++ Testing Framework (Google Test) 33 | // 34 | // This header file defines the public API for death tests. It is 35 | // #included by gtest.h so a user doesn't need to include this 36 | // directly. 37 | 38 | #ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ 39 | #define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ 40 | 41 | #include "gtest/internal/gtest-death-test-internal.h" 42 | 43 | namespace testing { 44 | 45 | // This flag controls the style of death tests. Valid values are "threadsafe", 46 | // meaning that the death test child process will re-execute the test binary 47 | // from the start, running only a single death test, or "fast", 48 | // meaning that the child process will execute the test logic immediately 49 | // after forking. 50 | GTEST_DECLARE_string_(death_test_style); 51 | 52 | #if GTEST_HAS_DEATH_TEST 53 | 54 | // The following macros are useful for writing death tests. 55 | 56 | // Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is 57 | // executed: 58 | // 59 | // 1. It generates a warning if there is more than one active 60 | // thread. This is because it's safe to fork() or clone() only 61 | // when there is a single thread. 62 | // 63 | // 2. The parent process clone()s a sub-process and runs the death 64 | // test in it; the sub-process exits with code 0 at the end of the 65 | // death test, if it hasn't exited already. 66 | // 67 | // 3. The parent process waits for the sub-process to terminate. 68 | // 69 | // 4. The parent process checks the exit code and error message of 70 | // the sub-process. 71 | // 72 | // Examples: 73 | // 74 | // ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); 75 | // for (int i = 0; i < 5; i++) { 76 | // EXPECT_DEATH(server.ProcessRequest(i), 77 | // "Invalid request .* in ProcessRequest()") 78 | // << "Failed to die on request " << i); 79 | // } 80 | // 81 | // ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); 82 | // 83 | // bool KilledBySIGHUP(int exit_code) { 84 | // return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; 85 | // } 86 | // 87 | // ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); 88 | // 89 | // On the regular expressions used in death tests: 90 | // 91 | // On POSIX-compliant systems (*nix), we use the library, 92 | // which uses the POSIX extended regex syntax. 93 | // 94 | // On other platforms (e.g. Windows), we only support a simple regex 95 | // syntax implemented as part of Google Test. This limited 96 | // implementation should be enough most of the time when writing 97 | // death tests; though it lacks many features you can find in PCRE 98 | // or POSIX extended regex syntax. For example, we don't support 99 | // union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and 100 | // repetition count ("x{5,7}"), among others. 101 | // 102 | // Below is the syntax that we do support. We chose it to be a 103 | // subset of both PCRE and POSIX extended regex, so it's easy to 104 | // learn wherever you come from. In the following: 'A' denotes a 105 | // literal character, period (.), or a single \\ escape sequence; 106 | // 'x' and 'y' denote regular expressions; 'm' and 'n' are for 107 | // natural numbers. 108 | // 109 | // c matches any literal character c 110 | // \\d matches any decimal digit 111 | // \\D matches any character that's not a decimal digit 112 | // \\f matches \f 113 | // \\n matches \n 114 | // \\r matches \r 115 | // \\s matches any ASCII whitespace, including \n 116 | // \\S matches any character that's not a whitespace 117 | // \\t matches \t 118 | // \\v matches \v 119 | // \\w matches any letter, _, or decimal digit 120 | // \\W matches any character that \\w doesn't match 121 | // \\c matches any literal character c, which must be a punctuation 122 | // . matches any single character except \n 123 | // A? matches 0 or 1 occurrences of A 124 | // A* matches 0 or many occurrences of A 125 | // A+ matches 1 or many occurrences of A 126 | // ^ matches the beginning of a string (not that of each line) 127 | // $ matches the end of a string (not that of each line) 128 | // xy matches x followed by y 129 | // 130 | // If you accidentally use PCRE or POSIX extended regex features 131 | // not implemented by us, you will get a run-time failure. In that 132 | // case, please try to rewrite your regular expression within the 133 | // above syntax. 134 | // 135 | // This implementation is *not* meant to be as highly tuned or robust 136 | // as a compiled regex library, but should perform well enough for a 137 | // death test, which already incurs significant overhead by launching 138 | // a child process. 139 | // 140 | // Known caveats: 141 | // 142 | // A "threadsafe" style death test obtains the path to the test 143 | // program from argv[0] and re-executes it in the sub-process. For 144 | // simplicity, the current implementation doesn't search the PATH 145 | // when launching the sub-process. This means that the user must 146 | // invoke the test program via a path that contains at least one 147 | // path separator (e.g. path/to/foo_test and 148 | // /absolute/path/to/bar_test are fine, but foo_test is not). This 149 | // is rarely a problem as people usually don't put the test binary 150 | // directory in PATH. 151 | // 152 | // TODO(wan@google.com): make thread-safe death tests search the PATH. 153 | 154 | // Asserts that a given statement causes the program to exit, with an 155 | // integer exit status that satisfies predicate, and emitting error output 156 | // that matches regex. 157 | # define ASSERT_EXIT(statement, predicate, regex) \ 158 | GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) 159 | 160 | // Like ASSERT_EXIT, but continues on to successive tests in the 161 | // test case, if any: 162 | # define EXPECT_EXIT(statement, predicate, regex) \ 163 | GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) 164 | 165 | // Asserts that a given statement causes the program to exit, either by 166 | // explicitly exiting with a nonzero exit code or being killed by a 167 | // signal, and emitting error output that matches regex. 168 | # define ASSERT_DEATH(statement, regex) \ 169 | ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) 170 | 171 | // Like ASSERT_DEATH, but continues on to successive tests in the 172 | // test case, if any: 173 | # define EXPECT_DEATH(statement, regex) \ 174 | EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) 175 | 176 | // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: 177 | 178 | // Tests that an exit code describes a normal exit with a given exit code. 179 | class GTEST_API_ ExitedWithCode { 180 | public: 181 | explicit ExitedWithCode(int exit_code); 182 | bool operator()(int exit_status) const; 183 | private: 184 | // No implementation - assignment is unsupported. 185 | void operator=(const ExitedWithCode& other); 186 | 187 | const int exit_code_; 188 | }; 189 | 190 | # if !GTEST_OS_WINDOWS 191 | // Tests that an exit code describes an exit due to termination by a 192 | // given signal. 193 | class GTEST_API_ KilledBySignal { 194 | public: 195 | explicit KilledBySignal(int signum); 196 | bool operator()(int exit_status) const; 197 | private: 198 | const int signum_; 199 | }; 200 | # endif // !GTEST_OS_WINDOWS 201 | 202 | // EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. 203 | // The death testing framework causes this to have interesting semantics, 204 | // since the sideeffects of the call are only visible in opt mode, and not 205 | // in debug mode. 206 | // 207 | // In practice, this can be used to test functions that utilize the 208 | // LOG(DFATAL) macro using the following style: 209 | // 210 | // int DieInDebugOr12(int* sideeffect) { 211 | // if (sideeffect) { 212 | // *sideeffect = 12; 213 | // } 214 | // LOG(DFATAL) << "death"; 215 | // return 12; 216 | // } 217 | // 218 | // TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { 219 | // int sideeffect = 0; 220 | // // Only asserts in dbg. 221 | // EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); 222 | // 223 | // #ifdef NDEBUG 224 | // // opt-mode has sideeffect visible. 225 | // EXPECT_EQ(12, sideeffect); 226 | // #else 227 | // // dbg-mode no visible sideeffect. 228 | // EXPECT_EQ(0, sideeffect); 229 | // #endif 230 | // } 231 | // 232 | // This will assert that DieInDebugReturn12InOpt() crashes in debug 233 | // mode, usually due to a DCHECK or LOG(DFATAL), but returns the 234 | // appropriate fallback value (12 in this case) in opt mode. If you 235 | // need to test that a function has appropriate side-effects in opt 236 | // mode, include assertions against the side-effects. A general 237 | // pattern for this is: 238 | // 239 | // EXPECT_DEBUG_DEATH({ 240 | // // Side-effects here will have an effect after this statement in 241 | // // opt mode, but none in debug mode. 242 | // EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); 243 | // }, "death"); 244 | // 245 | # ifdef NDEBUG 246 | 247 | # define EXPECT_DEBUG_DEATH(statement, regex) \ 248 | do { statement; } while (::testing::internal::AlwaysFalse()) 249 | 250 | # define ASSERT_DEBUG_DEATH(statement, regex) \ 251 | do { statement; } while (::testing::internal::AlwaysFalse()) 252 | 253 | # else 254 | 255 | # define EXPECT_DEBUG_DEATH(statement, regex) \ 256 | EXPECT_DEATH(statement, regex) 257 | 258 | # define ASSERT_DEBUG_DEATH(statement, regex) \ 259 | ASSERT_DEATH(statement, regex) 260 | 261 | # endif // NDEBUG for EXPECT_DEBUG_DEATH 262 | #endif // GTEST_HAS_DEATH_TEST 263 | 264 | // EXPECT_DEATH_IF_SUPPORTED(statement, regex) and 265 | // ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if 266 | // death tests are supported; otherwise they just issue a warning. This is 267 | // useful when you are combining death test assertions with normal test 268 | // assertions in one test. 269 | #if GTEST_HAS_DEATH_TEST 270 | # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ 271 | EXPECT_DEATH(statement, regex) 272 | # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ 273 | ASSERT_DEATH(statement, regex) 274 | #else 275 | # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ 276 | GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) 277 | # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ 278 | GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) 279 | #endif 280 | 281 | } // namespace testing 282 | 283 | #endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ 284 | -------------------------------------------------------------------------------- /google/gtest/gtest-message.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // The Google C++ Testing Framework (Google Test) 33 | // 34 | // This header file defines the Message class. 35 | // 36 | // IMPORTANT NOTE: Due to limitation of the C++ language, we have to 37 | // leave some internal implementation details in this header file. 38 | // They are clearly marked by comments like this: 39 | // 40 | // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 41 | // 42 | // Such code is NOT meant to be used by a user directly, and is subject 43 | // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user 44 | // program! 45 | 46 | #ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 47 | #define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 48 | 49 | #include 50 | 51 | #include "gtest/internal/gtest-string.h" 52 | #include "gtest/internal/gtest-internal.h" 53 | 54 | namespace testing { 55 | 56 | // The Message class works like an ostream repeater. 57 | // 58 | // Typical usage: 59 | // 60 | // 1. You stream a bunch of values to a Message object. 61 | // It will remember the text in a stringstream. 62 | // 2. Then you stream the Message object to an ostream. 63 | // This causes the text in the Message to be streamed 64 | // to the ostream. 65 | // 66 | // For example; 67 | // 68 | // testing::Message foo; 69 | // foo << 1 << " != " << 2; 70 | // std::cout << foo; 71 | // 72 | // will print "1 != 2". 73 | // 74 | // Message is not intended to be inherited from. In particular, its 75 | // destructor is not virtual. 76 | // 77 | // Note that stringstream behaves differently in gcc and in MSVC. You 78 | // can stream a NULL char pointer to it in the former, but not in the 79 | // latter (it causes an access violation if you do). The Message 80 | // class hides this difference by treating a NULL char pointer as 81 | // "(null)". 82 | class GTEST_API_ Message { 83 | private: 84 | // The type of basic IO manipulators (endl, ends, and flush) for 85 | // narrow streams. 86 | typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); 87 | 88 | public: 89 | // Constructs an empty Message. 90 | // We allocate the stringstream separately because otherwise each use of 91 | // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's 92 | // stack frame leading to huge stack frames in some cases; gcc does not reuse 93 | // the stack space. 94 | Message() : ss_(new ::std::stringstream) { 95 | // By default, we want there to be enough precision when printing 96 | // a double to a Message. 97 | *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); 98 | } 99 | 100 | // Copy constructor. 101 | Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT 102 | *ss_ << msg.GetString(); 103 | } 104 | 105 | // Constructs a Message from a C-string. 106 | explicit Message(const char* str) : ss_(new ::std::stringstream) { 107 | *ss_ << str; 108 | } 109 | 110 | #if GTEST_OS_SYMBIAN 111 | // Streams a value (either a pointer or not) to this object. 112 | template 113 | inline Message& operator <<(const T& value) { 114 | StreamHelper(typename internal::is_pointer::type(), value); 115 | return *this; 116 | } 117 | #else 118 | // Streams a non-pointer value to this object. 119 | template 120 | inline Message& operator <<(const T& val) { 121 | ::GTestStreamToHelper(ss_.get(), val); 122 | return *this; 123 | } 124 | 125 | // Streams a pointer value to this object. 126 | // 127 | // This function is an overload of the previous one. When you 128 | // stream a pointer to a Message, this definition will be used as it 129 | // is more specialized. (The C++ Standard, section 130 | // [temp.func.order].) If you stream a non-pointer, then the 131 | // previous definition will be used. 132 | // 133 | // The reason for this overload is that streaming a NULL pointer to 134 | // ostream is undefined behavior. Depending on the compiler, you 135 | // may get "0", "(nil)", "(null)", or an access violation. To 136 | // ensure consistent result across compilers, we always treat NULL 137 | // as "(null)". 138 | template 139 | inline Message& operator <<(T* const& pointer) { // NOLINT 140 | if (pointer == NULL) { 141 | *ss_ << "(null)"; 142 | } else { 143 | ::GTestStreamToHelper(ss_.get(), pointer); 144 | } 145 | return *this; 146 | } 147 | #endif // GTEST_OS_SYMBIAN 148 | 149 | // Since the basic IO manipulators are overloaded for both narrow 150 | // and wide streams, we have to provide this specialized definition 151 | // of operator <<, even though its body is the same as the 152 | // templatized version above. Without this definition, streaming 153 | // endl or other basic IO manipulators to Message will confuse the 154 | // compiler. 155 | Message& operator <<(BasicNarrowIoManip val) { 156 | *ss_ << val; 157 | return *this; 158 | } 159 | 160 | // Instead of 1/0, we want to see true/false for bool values. 161 | Message& operator <<(bool b) { 162 | return *this << (b ? "true" : "false"); 163 | } 164 | 165 | // These two overloads allow streaming a wide C string to a Message 166 | // using the UTF-8 encoding. 167 | Message& operator <<(const wchar_t* wide_c_str) { 168 | return *this << internal::String::ShowWideCString(wide_c_str); 169 | } 170 | Message& operator <<(wchar_t* wide_c_str) { 171 | return *this << internal::String::ShowWideCString(wide_c_str); 172 | } 173 | 174 | #if GTEST_HAS_STD_WSTRING 175 | // Converts the given wide string to a narrow string using the UTF-8 176 | // encoding, and streams the result to this Message object. 177 | Message& operator <<(const ::std::wstring& wstr); 178 | #endif // GTEST_HAS_STD_WSTRING 179 | 180 | #if GTEST_HAS_GLOBAL_WSTRING 181 | // Converts the given wide string to a narrow string using the UTF-8 182 | // encoding, and streams the result to this Message object. 183 | Message& operator <<(const ::wstring& wstr); 184 | #endif // GTEST_HAS_GLOBAL_WSTRING 185 | 186 | // Gets the text streamed to this object so far as a String. 187 | // Each '\0' character in the buffer is replaced with "\\0". 188 | // 189 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 190 | internal::String GetString() const { 191 | return internal::StringStreamToString(ss_.get()); 192 | } 193 | 194 | private: 195 | 196 | #if GTEST_OS_SYMBIAN 197 | // These are needed as the Nokia Symbian Compiler cannot decide between 198 | // const T& and const T* in a function template. The Nokia compiler _can_ 199 | // decide between class template specializations for T and T*, so a 200 | // tr1::type_traits-like is_pointer works, and we can overload on that. 201 | template 202 | inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) { 203 | if (pointer == NULL) { 204 | *ss_ << "(null)"; 205 | } else { 206 | ::GTestStreamToHelper(ss_.get(), pointer); 207 | } 208 | } 209 | template 210 | inline void StreamHelper(internal::false_type /*dummy*/, const T& value) { 211 | ::GTestStreamToHelper(ss_.get(), value); 212 | } 213 | #endif // GTEST_OS_SYMBIAN 214 | 215 | // We'll hold the text streamed to this object here. 216 | const internal::scoped_ptr< ::std::stringstream> ss_; 217 | 218 | // We declare (but don't implement) this to prevent the compiler 219 | // from implementing the assignment operator. 220 | void operator=(const Message&); 221 | }; 222 | 223 | // Streams a Message to an ostream. 224 | inline std::ostream& operator <<(std::ostream& os, const Message& sb) { 225 | return os << sb.GetString(); 226 | } 227 | 228 | } // namespace testing 229 | 230 | #endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 231 | -------------------------------------------------------------------------------- /google/gtest/gtest-spi.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // Utilities for testing Google Test itself and code that uses Google Test 33 | // (e.g. frameworks built on top of Google Test). 34 | 35 | #ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ 36 | #define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ 37 | 38 | #include "gtest/gtest.h" 39 | 40 | namespace testing { 41 | 42 | // This helper class can be used to mock out Google Test failure reporting 43 | // so that we can test Google Test or code that builds on Google Test. 44 | // 45 | // An object of this class appends a TestPartResult object to the 46 | // TestPartResultArray object given in the constructor whenever a Google Test 47 | // failure is reported. It can either intercept only failures that are 48 | // generated in the same thread that created this object or it can intercept 49 | // all generated failures. The scope of this mock object can be controlled with 50 | // the second argument to the two arguments constructor. 51 | class GTEST_API_ ScopedFakeTestPartResultReporter 52 | : public TestPartResultReporterInterface { 53 | public: 54 | // The two possible mocking modes of this object. 55 | enum InterceptMode { 56 | INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. 57 | INTERCEPT_ALL_THREADS // Intercepts all failures. 58 | }; 59 | 60 | // The c'tor sets this object as the test part result reporter used 61 | // by Google Test. The 'result' parameter specifies where to report the 62 | // results. This reporter will only catch failures generated in the current 63 | // thread. DEPRECATED 64 | explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); 65 | 66 | // Same as above, but you can choose the interception scope of this object. 67 | ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, 68 | TestPartResultArray* result); 69 | 70 | // The d'tor restores the previous test part result reporter. 71 | virtual ~ScopedFakeTestPartResultReporter(); 72 | 73 | // Appends the TestPartResult object to the TestPartResultArray 74 | // received in the constructor. 75 | // 76 | // This method is from the TestPartResultReporterInterface 77 | // interface. 78 | virtual void ReportTestPartResult(const TestPartResult& result); 79 | private: 80 | void Init(); 81 | 82 | const InterceptMode intercept_mode_; 83 | TestPartResultReporterInterface* old_reporter_; 84 | TestPartResultArray* const result_; 85 | 86 | GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); 87 | }; 88 | 89 | namespace internal { 90 | 91 | // A helper class for implementing EXPECT_FATAL_FAILURE() and 92 | // EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given 93 | // TestPartResultArray contains exactly one failure that has the given 94 | // type and contains the given substring. If that's not the case, a 95 | // non-fatal failure will be generated. 96 | class GTEST_API_ SingleFailureChecker { 97 | public: 98 | // The constructor remembers the arguments. 99 | SingleFailureChecker(const TestPartResultArray* results, 100 | TestPartResult::Type type, 101 | const string& substr); 102 | ~SingleFailureChecker(); 103 | private: 104 | const TestPartResultArray* const results_; 105 | const TestPartResult::Type type_; 106 | const string substr_; 107 | 108 | GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); 109 | }; 110 | 111 | } // namespace internal 112 | 113 | } // namespace testing 114 | 115 | // A set of macros for testing Google Test assertions or code that's expected 116 | // to generate Google Test fatal failures. It verifies that the given 117 | // statement will cause exactly one fatal Google Test failure with 'substr' 118 | // being part of the failure message. 119 | // 120 | // There are two different versions of this macro. EXPECT_FATAL_FAILURE only 121 | // affects and considers failures generated in the current thread and 122 | // EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. 123 | // 124 | // The verification of the assertion is done correctly even when the statement 125 | // throws an exception or aborts the current function. 126 | // 127 | // Known restrictions: 128 | // - 'statement' cannot reference local non-static variables or 129 | // non-static members of the current object. 130 | // - 'statement' cannot return a value. 131 | // - You cannot stream a failure message to this macro. 132 | // 133 | // Note that even though the implementations of the following two 134 | // macros are much alike, we cannot refactor them to use a common 135 | // helper macro, due to some peculiarity in how the preprocessor 136 | // works. The AcceptsMacroThatExpandsToUnprotectedComma test in 137 | // gtest_unittest.cc will fail to compile if we do that. 138 | #define EXPECT_FATAL_FAILURE(statement, substr) \ 139 | do { \ 140 | class GTestExpectFatalFailureHelper {\ 141 | public:\ 142 | static void Execute() { statement; }\ 143 | };\ 144 | ::testing::TestPartResultArray gtest_failures;\ 145 | ::testing::internal::SingleFailureChecker gtest_checker(\ 146 | >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ 147 | {\ 148 | ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ 149 | ::testing::ScopedFakeTestPartResultReporter:: \ 150 | INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ 151 | GTestExpectFatalFailureHelper::Execute();\ 152 | }\ 153 | } while (::testing::internal::AlwaysFalse()) 154 | 155 | #define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ 156 | do { \ 157 | class GTestExpectFatalFailureHelper {\ 158 | public:\ 159 | static void Execute() { statement; }\ 160 | };\ 161 | ::testing::TestPartResultArray gtest_failures;\ 162 | ::testing::internal::SingleFailureChecker gtest_checker(\ 163 | >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ 164 | {\ 165 | ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ 166 | ::testing::ScopedFakeTestPartResultReporter:: \ 167 | INTERCEPT_ALL_THREADS, >est_failures);\ 168 | GTestExpectFatalFailureHelper::Execute();\ 169 | }\ 170 | } while (::testing::internal::AlwaysFalse()) 171 | 172 | // A macro for testing Google Test assertions or code that's expected to 173 | // generate Google Test non-fatal failures. It asserts that the given 174 | // statement will cause exactly one non-fatal Google Test failure with 'substr' 175 | // being part of the failure message. 176 | // 177 | // There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only 178 | // affects and considers failures generated in the current thread and 179 | // EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. 180 | // 181 | // 'statement' is allowed to reference local variables and members of 182 | // the current object. 183 | // 184 | // The verification of the assertion is done correctly even when the statement 185 | // throws an exception or aborts the current function. 186 | // 187 | // Known restrictions: 188 | // - You cannot stream a failure message to this macro. 189 | // 190 | // Note that even though the implementations of the following two 191 | // macros are much alike, we cannot refactor them to use a common 192 | // helper macro, due to some peculiarity in how the preprocessor 193 | // works. If we do that, the code won't compile when the user gives 194 | // EXPECT_NONFATAL_FAILURE() a statement that contains a macro that 195 | // expands to code containing an unprotected comma. The 196 | // AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc 197 | // catches that. 198 | // 199 | // For the same reason, we have to write 200 | // if (::testing::internal::AlwaysTrue()) { statement; } 201 | // instead of 202 | // GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) 203 | // to avoid an MSVC warning on unreachable code. 204 | #define EXPECT_NONFATAL_FAILURE(statement, substr) \ 205 | do {\ 206 | ::testing::TestPartResultArray gtest_failures;\ 207 | ::testing::internal::SingleFailureChecker gtest_checker(\ 208 | >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ 209 | (substr));\ 210 | {\ 211 | ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ 212 | ::testing::ScopedFakeTestPartResultReporter:: \ 213 | INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ 214 | if (::testing::internal::AlwaysTrue()) { statement; }\ 215 | }\ 216 | } while (::testing::internal::AlwaysFalse()) 217 | 218 | #define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ 219 | do {\ 220 | ::testing::TestPartResultArray gtest_failures;\ 221 | ::testing::internal::SingleFailureChecker gtest_checker(\ 222 | >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ 223 | (substr));\ 224 | {\ 225 | ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ 226 | ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\ 227 | >est_failures);\ 228 | if (::testing::internal::AlwaysTrue()) { statement; }\ 229 | }\ 230 | } while (::testing::internal::AlwaysFalse()) 231 | 232 | #endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ 233 | -------------------------------------------------------------------------------- /google/gtest/gtest-test-part.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | 33 | #ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 34 | #define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 35 | 36 | #include 37 | #include 38 | #include "gtest/internal/gtest-internal.h" 39 | #include "gtest/internal/gtest-string.h" 40 | 41 | namespace testing { 42 | 43 | // A copyable object representing the result of a test part (i.e. an 44 | // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). 45 | // 46 | // Don't inherit from TestPartResult as its destructor is not virtual. 47 | class GTEST_API_ TestPartResult { 48 | public: 49 | // The possible outcomes of a test part (i.e. an assertion or an 50 | // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). 51 | enum Type { 52 | kSuccess, // Succeeded. 53 | kNonFatalFailure, // Failed but the test can continue. 54 | kFatalFailure // Failed and the test should be terminated. 55 | }; 56 | 57 | // C'tor. TestPartResult does NOT have a default constructor. 58 | // Always use this constructor (with parameters) to create a 59 | // TestPartResult object. 60 | TestPartResult(Type a_type, 61 | const char* a_file_name, 62 | int a_line_number, 63 | const char* a_message) 64 | : type_(a_type), 65 | file_name_(a_file_name), 66 | line_number_(a_line_number), 67 | summary_(ExtractSummary(a_message)), 68 | message_(a_message) { 69 | } 70 | 71 | // Gets the outcome of the test part. 72 | Type type() const { return type_; } 73 | 74 | // Gets the name of the source file where the test part took place, or 75 | // NULL if it's unknown. 76 | const char* file_name() const { return file_name_.c_str(); } 77 | 78 | // Gets the line in the source file where the test part took place, 79 | // or -1 if it's unknown. 80 | int line_number() const { return line_number_; } 81 | 82 | // Gets the summary of the failure message. 83 | const char* summary() const { return summary_.c_str(); } 84 | 85 | // Gets the message associated with the test part. 86 | const char* message() const { return message_.c_str(); } 87 | 88 | // Returns true iff the test part passed. 89 | bool passed() const { return type_ == kSuccess; } 90 | 91 | // Returns true iff the test part failed. 92 | bool failed() const { return type_ != kSuccess; } 93 | 94 | // Returns true iff the test part non-fatally failed. 95 | bool nonfatally_failed() const { return type_ == kNonFatalFailure; } 96 | 97 | // Returns true iff the test part fatally failed. 98 | bool fatally_failed() const { return type_ == kFatalFailure; } 99 | private: 100 | Type type_; 101 | 102 | // Gets the summary of the failure message by omitting the stack 103 | // trace in it. 104 | static internal::String ExtractSummary(const char* message); 105 | 106 | // The name of the source file where the test part took place, or 107 | // NULL if the source file is unknown. 108 | internal::String file_name_; 109 | // The line in the source file where the test part took place, or -1 110 | // if the line number is unknown. 111 | int line_number_; 112 | internal::String summary_; // The test failure summary. 113 | internal::String message_; // The test failure message. 114 | }; 115 | 116 | // Prints a TestPartResult object. 117 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result); 118 | 119 | // An array of TestPartResult objects. 120 | // 121 | // Don't inherit from TestPartResultArray as its destructor is not 122 | // virtual. 123 | class GTEST_API_ TestPartResultArray { 124 | public: 125 | TestPartResultArray() {} 126 | 127 | // Appends the given TestPartResult to the array. 128 | void Append(const TestPartResult& result); 129 | 130 | // Returns the TestPartResult at the given index (0-based). 131 | const TestPartResult& GetTestPartResult(int index) const; 132 | 133 | // Returns the number of TestPartResult objects in the array. 134 | int size() const; 135 | 136 | private: 137 | std::vector array_; 138 | 139 | GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); 140 | }; 141 | 142 | // This interface knows how to report a test part result. 143 | class TestPartResultReporterInterface { 144 | public: 145 | virtual ~TestPartResultReporterInterface() {} 146 | 147 | virtual void ReportTestPartResult(const TestPartResult& result) = 0; 148 | }; 149 | 150 | namespace internal { 151 | 152 | // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a 153 | // statement generates new fatal failures. To do so it registers itself as the 154 | // current test part result reporter. Besides checking if fatal failures were 155 | // reported, it only delegates the reporting to the former result reporter. 156 | // The original result reporter is restored in the destructor. 157 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 158 | class GTEST_API_ HasNewFatalFailureHelper 159 | : public TestPartResultReporterInterface { 160 | public: 161 | HasNewFatalFailureHelper(); 162 | virtual ~HasNewFatalFailureHelper(); 163 | virtual void ReportTestPartResult(const TestPartResult& result); 164 | bool has_new_fatal_failure() const { return has_new_fatal_failure_; } 165 | private: 166 | bool has_new_fatal_failure_; 167 | TestPartResultReporterInterface* original_reporter_; 168 | 169 | GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); 170 | }; 171 | 172 | } // namespace internal 173 | 174 | } // namespace testing 175 | 176 | #endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 177 | -------------------------------------------------------------------------------- /google/gtest/gtest-typed-test.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | #ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ 33 | #define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ 34 | 35 | // This header implements typed tests and type-parameterized tests. 36 | 37 | // Typed (aka type-driven) tests repeat the same test for types in a 38 | // list. You must know which types you want to test with when writing 39 | // typed tests. Here's how you do it: 40 | 41 | #if 0 42 | 43 | // First, define a fixture class template. It should be parameterized 44 | // by a type. Remember to derive it from testing::Test. 45 | template 46 | class FooTest : public testing::Test { 47 | public: 48 | ... 49 | typedef std::list List; 50 | static T shared_; 51 | T value_; 52 | }; 53 | 54 | // Next, associate a list of types with the test case, which will be 55 | // repeated for each type in the list. The typedef is necessary for 56 | // the macro to parse correctly. 57 | typedef testing::Types MyTypes; 58 | TYPED_TEST_CASE(FooTest, MyTypes); 59 | 60 | // If the type list contains only one type, you can write that type 61 | // directly without Types<...>: 62 | // TYPED_TEST_CASE(FooTest, int); 63 | 64 | // Then, use TYPED_TEST() instead of TEST_F() to define as many typed 65 | // tests for this test case as you want. 66 | TYPED_TEST(FooTest, DoesBlah) { 67 | // Inside a test, refer to TypeParam to get the type parameter. 68 | // Since we are inside a derived class template, C++ requires use to 69 | // visit the members of FooTest via 'this'. 70 | TypeParam n = this->value_; 71 | 72 | // To visit static members of the fixture, add the TestFixture:: 73 | // prefix. 74 | n += TestFixture::shared_; 75 | 76 | // To refer to typedefs in the fixture, add the "typename 77 | // TestFixture::" prefix. 78 | typename TestFixture::List values; 79 | values.push_back(n); 80 | ... 81 | } 82 | 83 | TYPED_TEST(FooTest, HasPropertyA) { ... } 84 | 85 | #endif // 0 86 | 87 | // Type-parameterized tests are abstract test patterns parameterized 88 | // by a type. Compared with typed tests, type-parameterized tests 89 | // allow you to define the test pattern without knowing what the type 90 | // parameters are. The defined pattern can be instantiated with 91 | // different types any number of times, in any number of translation 92 | // units. 93 | // 94 | // If you are designing an interface or concept, you can define a 95 | // suite of type-parameterized tests to verify properties that any 96 | // valid implementation of the interface/concept should have. Then, 97 | // each implementation can easily instantiate the test suite to verify 98 | // that it conforms to the requirements, without having to write 99 | // similar tests repeatedly. Here's an example: 100 | 101 | #if 0 102 | 103 | // First, define a fixture class template. It should be parameterized 104 | // by a type. Remember to derive it from testing::Test. 105 | template 106 | class FooTest : public testing::Test { 107 | ... 108 | }; 109 | 110 | // Next, declare that you will define a type-parameterized test case 111 | // (the _P suffix is for "parameterized" or "pattern", whichever you 112 | // prefer): 113 | TYPED_TEST_CASE_P(FooTest); 114 | 115 | // Then, use TYPED_TEST_P() to define as many type-parameterized tests 116 | // for this type-parameterized test case as you want. 117 | TYPED_TEST_P(FooTest, DoesBlah) { 118 | // Inside a test, refer to TypeParam to get the type parameter. 119 | TypeParam n = 0; 120 | ... 121 | } 122 | 123 | TYPED_TEST_P(FooTest, HasPropertyA) { ... } 124 | 125 | // Now the tricky part: you need to register all test patterns before 126 | // you can instantiate them. The first argument of the macro is the 127 | // test case name; the rest are the names of the tests in this test 128 | // case. 129 | REGISTER_TYPED_TEST_CASE_P(FooTest, 130 | DoesBlah, HasPropertyA); 131 | 132 | // Finally, you are free to instantiate the pattern with the types you 133 | // want. If you put the above code in a header file, you can #include 134 | // it in multiple C++ source files and instantiate it multiple times. 135 | // 136 | // To distinguish different instances of the pattern, the first 137 | // argument to the INSTANTIATE_* macro is a prefix that will be added 138 | // to the actual test case name. Remember to pick unique prefixes for 139 | // different instances. 140 | typedef testing::Types MyTypes; 141 | INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); 142 | 143 | // If the type list contains only one type, you can write that type 144 | // directly without Types<...>: 145 | // INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); 146 | 147 | #endif // 0 148 | 149 | #include "gtest/internal/gtest-port.h" 150 | #include "gtest/internal/gtest-type-util.h" 151 | 152 | // Implements typed tests. 153 | 154 | #if GTEST_HAS_TYPED_TEST 155 | 156 | // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 157 | // 158 | // Expands to the name of the typedef for the type parameters of the 159 | // given test case. 160 | # define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ 161 | 162 | // The 'Types' template argument below must have spaces around it 163 | // since some compilers may choke on '>>' when passing a template 164 | // instance (e.g. Types) 165 | # define TYPED_TEST_CASE(CaseName, Types) \ 166 | typedef ::testing::internal::TypeList< Types >::type \ 167 | GTEST_TYPE_PARAMS_(CaseName) 168 | 169 | # define TYPED_TEST(CaseName, TestName) \ 170 | template \ 171 | class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ 172 | : public CaseName { \ 173 | private: \ 174 | typedef CaseName TestFixture; \ 175 | typedef gtest_TypeParam_ TypeParam; \ 176 | virtual void TestBody(); \ 177 | }; \ 178 | bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ 179 | ::testing::internal::TypeParameterizedTest< \ 180 | CaseName, \ 181 | ::testing::internal::TemplateSel< \ 182 | GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ 183 | GTEST_TYPE_PARAMS_(CaseName)>::Register(\ 184 | "", #CaseName, #TestName, 0); \ 185 | template \ 186 | void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() 187 | 188 | #endif // GTEST_HAS_TYPED_TEST 189 | 190 | // Implements type-parameterized tests. 191 | 192 | #if GTEST_HAS_TYPED_TEST_P 193 | 194 | // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 195 | // 196 | // Expands to the namespace name that the type-parameterized tests for 197 | // the given type-parameterized test case are defined in. The exact 198 | // name of the namespace is subject to change without notice. 199 | # define GTEST_CASE_NAMESPACE_(TestCaseName) \ 200 | gtest_case_##TestCaseName##_ 201 | 202 | // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 203 | // 204 | // Expands to the name of the variable used to remember the names of 205 | // the defined tests in the given test case. 206 | # define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ 207 | gtest_typed_test_case_p_state_##TestCaseName##_ 208 | 209 | // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. 210 | // 211 | // Expands to the name of the variable used to remember the names of 212 | // the registered tests in the given test case. 213 | # define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ 214 | gtest_registered_test_names_##TestCaseName##_ 215 | 216 | // The variables defined in the type-parameterized test macros are 217 | // static as typically these macros are used in a .h file that can be 218 | // #included in multiple translation units linked together. 219 | # define TYPED_TEST_CASE_P(CaseName) \ 220 | static ::testing::internal::TypedTestCasePState \ 221 | GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) 222 | 223 | # define TYPED_TEST_P(CaseName, TestName) \ 224 | namespace GTEST_CASE_NAMESPACE_(CaseName) { \ 225 | template \ 226 | class TestName : public CaseName { \ 227 | private: \ 228 | typedef CaseName TestFixture; \ 229 | typedef gtest_TypeParam_ TypeParam; \ 230 | virtual void TestBody(); \ 231 | }; \ 232 | static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ 233 | GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ 234 | __FILE__, __LINE__, #CaseName, #TestName); \ 235 | } \ 236 | template \ 237 | void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() 238 | 239 | # define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ 240 | namespace GTEST_CASE_NAMESPACE_(CaseName) { \ 241 | typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ 242 | } \ 243 | static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ 244 | GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ 245 | __FILE__, __LINE__, #__VA_ARGS__) 246 | 247 | // The 'Types' template argument below must have spaces around it 248 | // since some compilers may choke on '>>' when passing a template 249 | // instance (e.g. Types) 250 | # define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ 251 | bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ 252 | ::testing::internal::TypeParameterizedTestCase::type>::Register(\ 255 | #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) 256 | 257 | #endif // GTEST_HAS_TYPED_TEST_P 258 | 259 | #endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ 260 | -------------------------------------------------------------------------------- /google/gtest/gtest_prod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // Google C++ Testing Framework definitions useful in production code. 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 35 | #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 36 | 37 | // When you need to test the private or protected members of a class, 38 | // use the FRIEND_TEST macro to declare your tests as friends of the 39 | // class. For example: 40 | // 41 | // class MyClass { 42 | // private: 43 | // void MyMethod(); 44 | // FRIEND_TEST(MyClassTest, MyMethod); 45 | // }; 46 | // 47 | // class MyClassTest : public testing::Test { 48 | // // ... 49 | // }; 50 | // 51 | // TEST_F(MyClassTest, MyMethod) { 52 | // // Can call MyClass::MyMethod() here. 53 | // } 54 | 55 | #define FRIEND_TEST(test_case_name, test_name)\ 56 | friend class test_case_name##_##test_name##_Test 57 | 58 | #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 59 | -------------------------------------------------------------------------------- /google/gtest/internal/gtest-death-test-internal.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) 31 | // 32 | // The Google C++ Testing Framework (Google Test) 33 | // 34 | // This header file defines internal utilities needed for implementing 35 | // death tests. They are subject to change without notice. 36 | 37 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ 38 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ 39 | 40 | #include "gtest/internal/gtest-internal.h" 41 | 42 | #include 43 | 44 | namespace testing { 45 | namespace internal { 46 | 47 | GTEST_DECLARE_string_(internal_run_death_test); 48 | 49 | // Names of the flags (needed for parsing Google Test flags). 50 | const char kDeathTestStyleFlag[] = "death_test_style"; 51 | const char kDeathTestUseFork[] = "death_test_use_fork"; 52 | const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; 53 | 54 | #if GTEST_HAS_DEATH_TEST 55 | 56 | // DeathTest is a class that hides much of the complexity of the 57 | // GTEST_DEATH_TEST_ macro. It is abstract; its static Create method 58 | // returns a concrete class that depends on the prevailing death test 59 | // style, as defined by the --gtest_death_test_style and/or 60 | // --gtest_internal_run_death_test flags. 61 | 62 | // In describing the results of death tests, these terms are used with 63 | // the corresponding definitions: 64 | // 65 | // exit status: The integer exit information in the format specified 66 | // by wait(2) 67 | // exit code: The integer code passed to exit(3), _exit(2), or 68 | // returned from main() 69 | class GTEST_API_ DeathTest { 70 | public: 71 | // Create returns false if there was an error determining the 72 | // appropriate action to take for the current death test; for example, 73 | // if the gtest_death_test_style flag is set to an invalid value. 74 | // The LastMessage method will return a more detailed message in that 75 | // case. Otherwise, the DeathTest pointer pointed to by the "test" 76 | // argument is set. If the death test should be skipped, the pointer 77 | // is set to NULL; otherwise, it is set to the address of a new concrete 78 | // DeathTest object that controls the execution of the current test. 79 | static bool Create(const char* statement, const RE* regex, 80 | const char* file, int line, DeathTest** test); 81 | DeathTest(); 82 | virtual ~DeathTest() { } 83 | 84 | // A helper class that aborts a death test when it's deleted. 85 | class ReturnSentinel { 86 | public: 87 | explicit ReturnSentinel(DeathTest* test) : test_(test) { } 88 | ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } 89 | private: 90 | DeathTest* const test_; 91 | GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); 92 | } GTEST_ATTRIBUTE_UNUSED_; 93 | 94 | // An enumeration of possible roles that may be taken when a death 95 | // test is encountered. EXECUTE means that the death test logic should 96 | // be executed immediately. OVERSEE means that the program should prepare 97 | // the appropriate environment for a child process to execute the death 98 | // test, then wait for it to complete. 99 | enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; 100 | 101 | // An enumeration of the three reasons that a test might be aborted. 102 | enum AbortReason { 103 | TEST_ENCOUNTERED_RETURN_STATEMENT, 104 | TEST_THREW_EXCEPTION, 105 | TEST_DID_NOT_DIE 106 | }; 107 | 108 | // Assumes one of the above roles. 109 | virtual TestRole AssumeRole() = 0; 110 | 111 | // Waits for the death test to finish and returns its status. 112 | virtual int Wait() = 0; 113 | 114 | // Returns true if the death test passed; that is, the test process 115 | // exited during the test, its exit status matches a user-supplied 116 | // predicate, and its stderr output matches a user-supplied regular 117 | // expression. 118 | // The user-supplied predicate may be a macro expression rather 119 | // than a function pointer or functor, or else Wait and Passed could 120 | // be combined. 121 | virtual bool Passed(bool exit_status_ok) = 0; 122 | 123 | // Signals that the death test did not die as expected. 124 | virtual void Abort(AbortReason reason) = 0; 125 | 126 | // Returns a human-readable outcome message regarding the outcome of 127 | // the last death test. 128 | static const char* LastMessage(); 129 | 130 | static void set_last_death_test_message(const String& message); 131 | 132 | private: 133 | // A string containing a description of the outcome of the last death test. 134 | static String last_death_test_message_; 135 | 136 | GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); 137 | }; 138 | 139 | // Factory interface for death tests. May be mocked out for testing. 140 | class DeathTestFactory { 141 | public: 142 | virtual ~DeathTestFactory() { } 143 | virtual bool Create(const char* statement, const RE* regex, 144 | const char* file, int line, DeathTest** test) = 0; 145 | }; 146 | 147 | // A concrete DeathTestFactory implementation for normal use. 148 | class DefaultDeathTestFactory : public DeathTestFactory { 149 | public: 150 | virtual bool Create(const char* statement, const RE* regex, 151 | const char* file, int line, DeathTest** test); 152 | }; 153 | 154 | // Returns true if exit_status describes a process that was terminated 155 | // by a signal, or exited normally with a nonzero exit code. 156 | GTEST_API_ bool ExitedUnsuccessfully(int exit_status); 157 | 158 | // Traps C++ exceptions escaping statement and reports them as test 159 | // failures. Note that trapping SEH exceptions is not implemented here. 160 | # if GTEST_HAS_EXCEPTIONS 161 | # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ 162 | try { \ 163 | GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ 164 | } catch (const ::std::exception& gtest_exception) { \ 165 | fprintf(\ 166 | stderr, \ 167 | "\n%s: Caught std::exception-derived exception escaping the " \ 168 | "death test statement. Exception message: %s\n", \ 169 | ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ 170 | gtest_exception.what()); \ 171 | fflush(stderr); \ 172 | death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ 173 | } catch (...) { \ 174 | death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ 175 | } 176 | 177 | # else 178 | # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ 179 | GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) 180 | 181 | # endif 182 | 183 | // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, 184 | // ASSERT_EXIT*, and EXPECT_EXIT*. 185 | # define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ 186 | GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ 187 | if (::testing::internal::AlwaysTrue()) { \ 188 | const ::testing::internal::RE& gtest_regex = (regex); \ 189 | ::testing::internal::DeathTest* gtest_dt; \ 190 | if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ 191 | __FILE__, __LINE__, >est_dt)) { \ 192 | goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ 193 | } \ 194 | if (gtest_dt != NULL) { \ 195 | ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ 196 | gtest_dt_ptr(gtest_dt); \ 197 | switch (gtest_dt->AssumeRole()) { \ 198 | case ::testing::internal::DeathTest::OVERSEE_TEST: \ 199 | if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ 200 | goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ 201 | } \ 202 | break; \ 203 | case ::testing::internal::DeathTest::EXECUTE_TEST: { \ 204 | ::testing::internal::DeathTest::ReturnSentinel \ 205 | gtest_sentinel(gtest_dt); \ 206 | GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ 207 | gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ 208 | break; \ 209 | } \ 210 | default: \ 211 | break; \ 212 | } \ 213 | } \ 214 | } else \ 215 | GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ 216 | fail(::testing::internal::DeathTest::LastMessage()) 217 | // The symbol "fail" here expands to something into which a message 218 | // can be streamed. 219 | 220 | // A class representing the parsed contents of the 221 | // --gtest_internal_run_death_test flag, as it existed when 222 | // RUN_ALL_TESTS was called. 223 | class InternalRunDeathTestFlag { 224 | public: 225 | InternalRunDeathTestFlag(const String& a_file, 226 | int a_line, 227 | int an_index, 228 | int a_write_fd) 229 | : file_(a_file), line_(a_line), index_(an_index), 230 | write_fd_(a_write_fd) {} 231 | 232 | ~InternalRunDeathTestFlag() { 233 | if (write_fd_ >= 0) 234 | posix::Close(write_fd_); 235 | } 236 | 237 | String file() const { return file_; } 238 | int line() const { return line_; } 239 | int index() const { return index_; } 240 | int write_fd() const { return write_fd_; } 241 | 242 | private: 243 | String file_; 244 | int line_; 245 | int index_; 246 | int write_fd_; 247 | 248 | GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); 249 | }; 250 | 251 | // Returns a newly created InternalRunDeathTestFlag object with fields 252 | // initialized from the GTEST_FLAG(internal_run_death_test) flag if 253 | // the flag is specified; otherwise returns NULL. 254 | InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); 255 | 256 | #else // GTEST_HAS_DEATH_TEST 257 | 258 | // This macro is used for implementing macros such as 259 | // EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where 260 | // death tests are not supported. Those macros must compile on such systems 261 | // iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on 262 | // systems that support death tests. This allows one to write such a macro 263 | // on a system that does not support death tests and be sure that it will 264 | // compile on a death-test supporting system. 265 | // 266 | // Parameters: 267 | // statement - A statement that a macro such as EXPECT_DEATH would test 268 | // for program termination. This macro has to make sure this 269 | // statement is compiled but not executed, to ensure that 270 | // EXPECT_DEATH_IF_SUPPORTED compiles with a certain 271 | // parameter iff EXPECT_DEATH compiles with it. 272 | // regex - A regex that a macro such as EXPECT_DEATH would use to test 273 | // the output of statement. This parameter has to be 274 | // compiled but not evaluated by this macro, to ensure that 275 | // this macro only accepts expressions that a macro such as 276 | // EXPECT_DEATH would accept. 277 | // terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED 278 | // and a return statement for ASSERT_DEATH_IF_SUPPORTED. 279 | // This ensures that ASSERT_DEATH_IF_SUPPORTED will not 280 | // compile inside functions where ASSERT_DEATH doesn't 281 | // compile. 282 | // 283 | // The branch that has an always false condition is used to ensure that 284 | // statement and regex are compiled (and thus syntactically correct) but 285 | // never executed. The unreachable code macro protects the terminator 286 | // statement from generating an 'unreachable code' warning in case 287 | // statement unconditionally returns or throws. The Message constructor at 288 | // the end allows the syntax of streaming additional messages into the 289 | // macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. 290 | # define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ 291 | GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ 292 | if (::testing::internal::AlwaysTrue()) { \ 293 | GTEST_LOG_(WARNING) \ 294 | << "Death tests are not supported on this platform.\n" \ 295 | << "Statement '" #statement "' cannot be verified."; \ 296 | } else if (::testing::internal::AlwaysFalse()) { \ 297 | ::testing::internal::RE::PartialMatch(".*", (regex)); \ 298 | GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ 299 | terminator; \ 300 | } else \ 301 | ::testing::Message() 302 | 303 | #endif // GTEST_HAS_DEATH_TEST 304 | 305 | } // namespace internal 306 | } // namespace testing 307 | 308 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ 309 | -------------------------------------------------------------------------------- /google/gtest/internal/gtest-filepath.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: keith.ray@gmail.com (Keith Ray) 31 | // 32 | // Google Test filepath utilities 33 | // 34 | // This header file declares classes and functions used internally by 35 | // Google Test. They are subject to change without notice. 36 | // 37 | // This file is #included in . 38 | // Do not include this header file separately! 39 | 40 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ 41 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ 42 | 43 | #include "gtest/internal/gtest-string.h" 44 | 45 | namespace testing { 46 | namespace internal { 47 | 48 | // FilePath - a class for file and directory pathname manipulation which 49 | // handles platform-specific conventions (like the pathname separator). 50 | // Used for helper functions for naming files in a directory for xml output. 51 | // Except for Set methods, all methods are const or static, which provides an 52 | // "immutable value object" -- useful for peace of mind. 53 | // A FilePath with a value ending in a path separator ("like/this/") represents 54 | // a directory, otherwise it is assumed to represent a file. In either case, 55 | // it may or may not represent an actual file or directory in the file system. 56 | // Names are NOT checked for syntax correctness -- no checking for illegal 57 | // characters, malformed paths, etc. 58 | 59 | class GTEST_API_ FilePath { 60 | public: 61 | FilePath() : pathname_("") { } 62 | FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } 63 | 64 | explicit FilePath(const char* pathname) : pathname_(pathname) { 65 | Normalize(); 66 | } 67 | 68 | explicit FilePath(const String& pathname) : pathname_(pathname) { 69 | Normalize(); 70 | } 71 | 72 | FilePath& operator=(const FilePath& rhs) { 73 | Set(rhs); 74 | return *this; 75 | } 76 | 77 | void Set(const FilePath& rhs) { 78 | pathname_ = rhs.pathname_; 79 | } 80 | 81 | String ToString() const { return pathname_; } 82 | const char* c_str() const { return pathname_.c_str(); } 83 | 84 | // Returns the current working directory, or "" if unsuccessful. 85 | static FilePath GetCurrentDir(); 86 | 87 | // Given directory = "dir", base_name = "test", number = 0, 88 | // extension = "xml", returns "dir/test.xml". If number is greater 89 | // than zero (e.g., 12), returns "dir/test_12.xml". 90 | // On Windows platform, uses \ as the separator rather than /. 91 | static FilePath MakeFileName(const FilePath& directory, 92 | const FilePath& base_name, 93 | int number, 94 | const char* extension); 95 | 96 | // Given directory = "dir", relative_path = "test.xml", 97 | // returns "dir/test.xml". 98 | // On Windows, uses \ as the separator rather than /. 99 | static FilePath ConcatPaths(const FilePath& directory, 100 | const FilePath& relative_path); 101 | 102 | // Returns a pathname for a file that does not currently exist. The pathname 103 | // will be directory/base_name.extension or 104 | // directory/base_name_.extension if directory/base_name.extension 105 | // already exists. The number will be incremented until a pathname is found 106 | // that does not already exist. 107 | // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. 108 | // There could be a race condition if two or more processes are calling this 109 | // function at the same time -- they could both pick the same filename. 110 | static FilePath GenerateUniqueFileName(const FilePath& directory, 111 | const FilePath& base_name, 112 | const char* extension); 113 | 114 | // Returns true iff the path is NULL or "". 115 | bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; } 116 | 117 | // If input name has a trailing separator character, removes it and returns 118 | // the name, otherwise return the name string unmodified. 119 | // On Windows platform, uses \ as the separator, other platforms use /. 120 | FilePath RemoveTrailingPathSeparator() const; 121 | 122 | // Returns a copy of the FilePath with the directory part removed. 123 | // Example: FilePath("path/to/file").RemoveDirectoryName() returns 124 | // FilePath("file"). If there is no directory part ("just_a_file"), it returns 125 | // the FilePath unmodified. If there is no file part ("just_a_dir/") it 126 | // returns an empty FilePath (""). 127 | // On Windows platform, '\' is the path separator, otherwise it is '/'. 128 | FilePath RemoveDirectoryName() const; 129 | 130 | // RemoveFileName returns the directory path with the filename removed. 131 | // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". 132 | // If the FilePath is "a_file" or "/a_file", RemoveFileName returns 133 | // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does 134 | // not have a file, like "just/a/dir/", it returns the FilePath unmodified. 135 | // On Windows platform, '\' is the path separator, otherwise it is '/'. 136 | FilePath RemoveFileName() const; 137 | 138 | // Returns a copy of the FilePath with the case-insensitive extension removed. 139 | // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns 140 | // FilePath("dir/file"). If a case-insensitive extension is not 141 | // found, returns a copy of the original FilePath. 142 | FilePath RemoveExtension(const char* extension) const; 143 | 144 | // Creates directories so that path exists. Returns true if successful or if 145 | // the directories already exist; returns false if unable to create 146 | // directories for any reason. Will also return false if the FilePath does 147 | // not represent a directory (that is, it doesn't end with a path separator). 148 | bool CreateDirectoriesRecursively() const; 149 | 150 | // Create the directory so that path exists. Returns true if successful or 151 | // if the directory already exists; returns false if unable to create the 152 | // directory for any reason, including if the parent directory does not 153 | // exist. Not named "CreateDirectory" because that's a macro on Windows. 154 | bool CreateFolder() const; 155 | 156 | // Returns true if FilePath describes something in the file-system, 157 | // either a file, directory, or whatever, and that something exists. 158 | bool FileOrDirectoryExists() const; 159 | 160 | // Returns true if pathname describes a directory in the file-system 161 | // that exists. 162 | bool DirectoryExists() const; 163 | 164 | // Returns true if FilePath ends with a path separator, which indicates that 165 | // it is intended to represent a directory. Returns false otherwise. 166 | // This does NOT check that a directory (or file) actually exists. 167 | bool IsDirectory() const; 168 | 169 | // Returns true if pathname describes a root directory. (Windows has one 170 | // root directory per disk drive.) 171 | bool IsRootDirectory() const; 172 | 173 | // Returns true if pathname describes an absolute path. 174 | bool IsAbsolutePath() const; 175 | 176 | private: 177 | // Replaces multiple consecutive separators with a single separator. 178 | // For example, "bar///foo" becomes "bar/foo". Does not eliminate other 179 | // redundancies that might be in a pathname involving "." or "..". 180 | // 181 | // A pathname with multiple consecutive separators may occur either through 182 | // user error or as a result of some scripts or APIs that generate a pathname 183 | // with a trailing separator. On other platforms the same API or script 184 | // may NOT generate a pathname with a trailing "/". Then elsewhere that 185 | // pathname may have another "/" and pathname components added to it, 186 | // without checking for the separator already being there. 187 | // The script language and operating system may allow paths like "foo//bar" 188 | // but some of the functions in FilePath will not handle that correctly. In 189 | // particular, RemoveTrailingPathSeparator() only removes one separator, and 190 | // it is called in CreateDirectoriesRecursively() assuming that it will change 191 | // a pathname from directory syntax (trailing separator) to filename syntax. 192 | // 193 | // On Windows this method also replaces the alternate path separator '/' with 194 | // the primary path separator '\\', so that for example "bar\\/\\foo" becomes 195 | // "bar\\foo". 196 | 197 | void Normalize(); 198 | 199 | // Returns a pointer to the last occurence of a valid path separator in 200 | // the FilePath. On Windows, for example, both '/' and '\' are valid path 201 | // separators. Returns NULL if no path separator was found. 202 | const char* FindLastPathSeparator() const; 203 | 204 | String pathname_; 205 | }; // class FilePath 206 | 207 | } // namespace internal 208 | } // namespace testing 209 | 210 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ 211 | -------------------------------------------------------------------------------- /google/gtest/internal/gtest-linked_ptr.h: -------------------------------------------------------------------------------- 1 | // Copyright 2003 Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Authors: Dan Egnor (egnor@google.com) 31 | // 32 | // A "smart" pointer type with reference tracking. Every pointer to a 33 | // particular object is kept on a circular linked list. When the last pointer 34 | // to an object is destroyed or reassigned, the object is deleted. 35 | // 36 | // Used properly, this deletes the object when the last reference goes away. 37 | // There are several caveats: 38 | // - Like all reference counting schemes, cycles lead to leaks. 39 | // - Each smart pointer is actually two pointers (8 bytes instead of 4). 40 | // - Every time a pointer is assigned, the entire list of pointers to that 41 | // object is traversed. This class is therefore NOT SUITABLE when there 42 | // will often be more than two or three pointers to a particular object. 43 | // - References are only tracked as long as linked_ptr<> objects are copied. 44 | // If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS 45 | // will happen (double deletion). 46 | // 47 | // A good use of this class is storing object references in STL containers. 48 | // You can safely put linked_ptr<> in a vector<>. 49 | // Other uses may not be as good. 50 | // 51 | // Note: If you use an incomplete type with linked_ptr<>, the class 52 | // *containing* linked_ptr<> must have a constructor and destructor (even 53 | // if they do nothing!). 54 | // 55 | // Bill Gibbons suggested we use something like this. 56 | // 57 | // Thread Safety: 58 | // Unlike other linked_ptr implementations, in this implementation 59 | // a linked_ptr object is thread-safe in the sense that: 60 | // - it's safe to copy linked_ptr objects concurrently, 61 | // - it's safe to copy *from* a linked_ptr and read its underlying 62 | // raw pointer (e.g. via get()) concurrently, and 63 | // - it's safe to write to two linked_ptrs that point to the same 64 | // shared object concurrently. 65 | // TODO(wan@google.com): rename this to safe_linked_ptr to avoid 66 | // confusion with normal linked_ptr. 67 | 68 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ 69 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ 70 | 71 | #include 72 | #include 73 | 74 | #include "gtest/internal/gtest-port.h" 75 | 76 | namespace testing { 77 | namespace internal { 78 | 79 | // Protects copying of all linked_ptr objects. 80 | GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); 81 | 82 | // This is used internally by all instances of linked_ptr<>. It needs to be 83 | // a non-template class because different types of linked_ptr<> can refer to 84 | // the same object (linked_ptr(obj) vs linked_ptr(obj)). 85 | // So, it needs to be possible for different types of linked_ptr to participate 86 | // in the same circular linked list, so we need a single class type here. 87 | // 88 | // DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. 89 | class linked_ptr_internal { 90 | public: 91 | // Create a new circle that includes only this instance. 92 | void join_new() { 93 | next_ = this; 94 | } 95 | 96 | // Many linked_ptr operations may change p.link_ for some linked_ptr 97 | // variable p in the same circle as this object. Therefore we need 98 | // to prevent two such operations from occurring concurrently. 99 | // 100 | // Note that different types of linked_ptr objects can coexist in a 101 | // circle (e.g. linked_ptr, linked_ptr, and 102 | // linked_ptr). Therefore we must use a single mutex to 103 | // protect all linked_ptr objects. This can create serious 104 | // contention in production code, but is acceptable in a testing 105 | // framework. 106 | 107 | // Join an existing circle. 108 | // L < g_linked_ptr_mutex 109 | void join(linked_ptr_internal const* ptr) { 110 | MutexLock lock(&g_linked_ptr_mutex); 111 | 112 | linked_ptr_internal const* p = ptr; 113 | while (p->next_ != ptr) p = p->next_; 114 | p->next_ = this; 115 | next_ = ptr; 116 | } 117 | 118 | // Leave whatever circle we're part of. Returns true if we were the 119 | // last member of the circle. Once this is done, you can join() another. 120 | // L < g_linked_ptr_mutex 121 | bool depart() { 122 | MutexLock lock(&g_linked_ptr_mutex); 123 | 124 | if (next_ == this) return true; 125 | linked_ptr_internal const* p = next_; 126 | while (p->next_ != this) p = p->next_; 127 | p->next_ = next_; 128 | return false; 129 | } 130 | 131 | private: 132 | mutable linked_ptr_internal const* next_; 133 | }; 134 | 135 | template 136 | class linked_ptr { 137 | public: 138 | typedef T element_type; 139 | 140 | // Take over ownership of a raw pointer. This should happen as soon as 141 | // possible after the object is created. 142 | explicit linked_ptr(T* ptr = NULL) { capture(ptr); } 143 | ~linked_ptr() { depart(); } 144 | 145 | // Copy an existing linked_ptr<>, adding ourselves to the list of references. 146 | template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } 147 | linked_ptr(linked_ptr const& ptr) { // NOLINT 148 | assert(&ptr != this); 149 | copy(&ptr); 150 | } 151 | 152 | // Assignment releases the old value and acquires the new. 153 | template linked_ptr& operator=(linked_ptr const& ptr) { 154 | depart(); 155 | copy(&ptr); 156 | return *this; 157 | } 158 | 159 | linked_ptr& operator=(linked_ptr const& ptr) { 160 | if (&ptr != this) { 161 | depart(); 162 | copy(&ptr); 163 | } 164 | return *this; 165 | } 166 | 167 | // Smart pointer members. 168 | void reset(T* ptr = NULL) { 169 | depart(); 170 | capture(ptr); 171 | } 172 | T* get() const { return value_; } 173 | T* operator->() const { return value_; } 174 | T& operator*() const { return *value_; } 175 | 176 | bool operator==(T* p) const { return value_ == p; } 177 | bool operator!=(T* p) const { return value_ != p; } 178 | template 179 | bool operator==(linked_ptr const& ptr) const { 180 | return value_ == ptr.get(); 181 | } 182 | template 183 | bool operator!=(linked_ptr const& ptr) const { 184 | return value_ != ptr.get(); 185 | } 186 | 187 | private: 188 | template 189 | friend class linked_ptr; 190 | 191 | T* value_; 192 | linked_ptr_internal link_; 193 | 194 | void depart() { 195 | if (link_.depart()) delete value_; 196 | } 197 | 198 | void capture(T* ptr) { 199 | value_ = ptr; 200 | link_.join_new(); 201 | } 202 | 203 | template void copy(linked_ptr const* ptr) { 204 | value_ = ptr->get(); 205 | if (value_) 206 | link_.join(&ptr->link_); 207 | else 208 | link_.join_new(); 209 | } 210 | }; 211 | 212 | template inline 213 | bool operator==(T* ptr, const linked_ptr& x) { 214 | return ptr == x.get(); 215 | } 216 | 217 | template inline 218 | bool operator!=(T* ptr, const linked_ptr& x) { 219 | return ptr != x.get(); 220 | } 221 | 222 | // A function to convert T* into linked_ptr 223 | // Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation 224 | // for linked_ptr >(new FooBarBaz(arg)) 225 | template 226 | linked_ptr make_linked_ptr(T* ptr) { 227 | return linked_ptr(ptr); 228 | } 229 | 230 | } // namespace internal 231 | } // namespace testing 232 | 233 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ 234 | -------------------------------------------------------------------------------- /google/gtest/internal/gtest-param-util-generated.h.pump: -------------------------------------------------------------------------------- 1 | $$ -*- mode: c++; -*- 2 | $var n = 50 $$ Maximum length of Values arguments we want to support. 3 | $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. 4 | // Copyright 2008 Google Inc. 5 | // All Rights Reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without 8 | // modification, are permitted provided that the following conditions are 9 | // met: 10 | // 11 | // * Redistributions of source code must retain the above copyright 12 | // notice, this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above 14 | // copyright notice, this list of conditions and the following disclaimer 15 | // in the documentation and/or other materials provided with the 16 | // distribution. 17 | // * Neither the name of Google Inc. nor the names of its 18 | // contributors may be used to endorse or promote products derived from 19 | // this software without specific prior written permission. 20 | // 21 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | // 33 | // Author: vladl@google.com (Vlad Losev) 34 | 35 | // Type and function utilities for implementing parameterized tests. 36 | // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! 37 | // 38 | // Currently Google Test supports at most $n arguments in Values, 39 | // and at most $maxtuple arguments in Combine. Please contact 40 | // googletestframework@googlegroups.com if you need more. 41 | // Please note that the number of arguments to Combine is limited 42 | // by the maximum arity of the implementation of tr1::tuple which is 43 | // currently set at $maxtuple. 44 | 45 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ 46 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ 47 | 48 | // scripts/fuse_gtest.py depends on gtest's own header being #included 49 | // *unconditionally*. Therefore these #includes cannot be moved 50 | // inside #if GTEST_HAS_PARAM_TEST. 51 | #include "gtest/internal/gtest-param-util.h" 52 | #include "gtest/internal/gtest-port.h" 53 | 54 | #if GTEST_HAS_PARAM_TEST 55 | 56 | namespace testing { 57 | 58 | // Forward declarations of ValuesIn(), which is implemented in 59 | // include/gtest/gtest-param-test.h. 60 | template 61 | internal::ParamGenerator< 62 | typename ::testing::internal::IteratorTraits::value_type> 63 | ValuesIn(ForwardIterator begin, ForwardIterator end); 64 | 65 | template 66 | internal::ParamGenerator ValuesIn(const T (&array)[N]); 67 | 68 | template 69 | internal::ParamGenerator ValuesIn( 70 | const Container& container); 71 | 72 | namespace internal { 73 | 74 | // Used in the Values() function to provide polymorphic capabilities. 75 | template 76 | class ValueArray1 { 77 | public: 78 | explicit ValueArray1(T1 v1) : v1_(v1) {} 79 | 80 | template 81 | operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } 82 | 83 | private: 84 | // No implementation - assignment is unsupported. 85 | void operator=(const ValueArray1& other); 86 | 87 | const T1 v1_; 88 | }; 89 | 90 | $range i 2..n 91 | $for i [[ 92 | $range j 1..i 93 | 94 | template <$for j, [[typename T$j]]> 95 | class ValueArray$i { 96 | public: 97 | ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {} 98 | 99 | template 100 | operator ParamGenerator() const { 101 | const T array[] = {$for j, [[v$(j)_]]}; 102 | return ValuesIn(array); 103 | } 104 | 105 | private: 106 | // No implementation - assignment is unsupported. 107 | void operator=(const ValueArray$i& other); 108 | 109 | $for j [[ 110 | 111 | const T$j v$(j)_; 112 | ]] 113 | 114 | }; 115 | 116 | ]] 117 | 118 | # if GTEST_HAS_COMBINE 119 | // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 120 | // 121 | // Generates values from the Cartesian product of values produced 122 | // by the argument generators. 123 | // 124 | $range i 2..maxtuple 125 | $for i [[ 126 | $range j 1..i 127 | $range k 2..i 128 | 129 | template <$for j, [[typename T$j]]> 130 | class CartesianProductGenerator$i 131 | : public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > { 132 | public: 133 | typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType; 134 | 135 | CartesianProductGenerator$i($for j, [[const ParamGenerator& g$j]]) 136 | : $for j, [[g$(j)_(g$j)]] {} 137 | virtual ~CartesianProductGenerator$i() {} 138 | 139 | virtual ParamIteratorInterface* Begin() const { 140 | return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]); 141 | } 142 | virtual ParamIteratorInterface* End() const { 143 | return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]); 144 | } 145 | 146 | private: 147 | class Iterator : public ParamIteratorInterface { 148 | public: 149 | Iterator(const ParamGeneratorInterface* base, $for j, [[ 150 | 151 | const ParamGenerator& g$j, 152 | const typename ParamGenerator::iterator& current$(j)]]) 153 | : base_(base), 154 | $for j, [[ 155 | 156 | begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j) 157 | ]] { 158 | ComputeCurrentValue(); 159 | } 160 | virtual ~Iterator() {} 161 | 162 | virtual const ParamGeneratorInterface* BaseGenerator() const { 163 | return base_; 164 | } 165 | // Advance should not be called on beyond-of-range iterators 166 | // so no component iterators must be beyond end of range, either. 167 | virtual void Advance() { 168 | assert(!AtEnd()); 169 | ++current$(i)_; 170 | 171 | $for k [[ 172 | if (current$(i+2-k)_ == end$(i+2-k)_) { 173 | current$(i+2-k)_ = begin$(i+2-k)_; 174 | ++current$(i+2-k-1)_; 175 | } 176 | 177 | ]] 178 | ComputeCurrentValue(); 179 | } 180 | virtual ParamIteratorInterface* Clone() const { 181 | return new Iterator(*this); 182 | } 183 | virtual const ParamType* Current() const { return ¤t_value_; } 184 | virtual bool Equals(const ParamIteratorInterface& other) const { 185 | // Having the same base generator guarantees that the other 186 | // iterator is of the same type and we can downcast. 187 | GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) 188 | << "The program attempted to compare iterators " 189 | << "from different generators." << std::endl; 190 | const Iterator* typed_other = 191 | CheckedDowncastToActualType(&other); 192 | // We must report iterators equal if they both point beyond their 193 | // respective ranges. That can happen in a variety of fashions, 194 | // so we have to consult AtEnd(). 195 | return (AtEnd() && typed_other->AtEnd()) || 196 | ($for j && [[ 197 | 198 | current$(j)_ == typed_other->current$(j)_ 199 | ]]); 200 | } 201 | 202 | private: 203 | Iterator(const Iterator& other) 204 | : base_(other.base_), $for j, [[ 205 | 206 | begin$(j)_(other.begin$(j)_), 207 | end$(j)_(other.end$(j)_), 208 | current$(j)_(other.current$(j)_) 209 | ]] { 210 | ComputeCurrentValue(); 211 | } 212 | 213 | void ComputeCurrentValue() { 214 | if (!AtEnd()) 215 | current_value_ = ParamType($for j, [[*current$(j)_]]); 216 | } 217 | bool AtEnd() const { 218 | // We must report iterator past the end of the range when either of the 219 | // component iterators has reached the end of its range. 220 | return 221 | $for j || [[ 222 | 223 | current$(j)_ == end$(j)_ 224 | ]]; 225 | } 226 | 227 | // No implementation - assignment is unsupported. 228 | void operator=(const Iterator& other); 229 | 230 | const ParamGeneratorInterface* const base_; 231 | // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. 232 | // current[i]_ is the actual traversing iterator. 233 | $for j [[ 234 | 235 | const typename ParamGenerator::iterator begin$(j)_; 236 | const typename ParamGenerator::iterator end$(j)_; 237 | typename ParamGenerator::iterator current$(j)_; 238 | ]] 239 | 240 | ParamType current_value_; 241 | }; // class CartesianProductGenerator$i::Iterator 242 | 243 | // No implementation - assignment is unsupported. 244 | void operator=(const CartesianProductGenerator$i& other); 245 | 246 | 247 | $for j [[ 248 | const ParamGenerator g$(j)_; 249 | 250 | ]] 251 | }; // class CartesianProductGenerator$i 252 | 253 | 254 | ]] 255 | 256 | // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 257 | // 258 | // Helper classes providing Combine() with polymorphic features. They allow 259 | // casting CartesianProductGeneratorN to ParamGenerator if T is 260 | // convertible to U. 261 | // 262 | $range i 2..maxtuple 263 | $for i [[ 264 | $range j 1..i 265 | 266 | template <$for j, [[class Generator$j]]> 267 | class CartesianProductHolder$i { 268 | public: 269 | CartesianProductHolder$i($for j, [[const Generator$j& g$j]]) 270 | : $for j, [[g$(j)_(g$j)]] {} 271 | template <$for j, [[typename T$j]]> 272 | operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const { 273 | return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >( 274 | new CartesianProductGenerator$i<$for j, [[T$j]]>( 275 | $for j,[[ 276 | 277 | static_cast >(g$(j)_) 278 | ]])); 279 | } 280 | 281 | private: 282 | // No implementation - assignment is unsupported. 283 | void operator=(const CartesianProductHolder$i& other); 284 | 285 | 286 | $for j [[ 287 | const Generator$j g$(j)_; 288 | 289 | ]] 290 | }; // class CartesianProductHolder$i 291 | 292 | ]] 293 | 294 | # endif // GTEST_HAS_COMBINE 295 | 296 | } // namespace internal 297 | } // namespace testing 298 | 299 | #endif // GTEST_HAS_PARAM_TEST 300 | 301 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ 302 | -------------------------------------------------------------------------------- /google/gtest/internal/gtest-tuple.h.pump: -------------------------------------------------------------------------------- 1 | $$ -*- mode: c++; -*- 2 | $var n = 10 $$ Maximum number of tuple fields we want to support. 3 | $$ This meta comment fixes auto-indentation in Emacs. }} 4 | // Copyright 2009 Google Inc. 5 | // All Rights Reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without 8 | // modification, are permitted provided that the following conditions are 9 | // met: 10 | // 11 | // * Redistributions of source code must retain the above copyright 12 | // notice, this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above 14 | // copyright notice, this list of conditions and the following disclaimer 15 | // in the documentation and/or other materials provided with the 16 | // distribution. 17 | // * Neither the name of Google Inc. nor the names of its 18 | // contributors may be used to endorse or promote products derived from 19 | // this software without specific prior written permission. 20 | // 21 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | // 33 | // Author: wan@google.com (Zhanyong Wan) 34 | 35 | // Implements a subset of TR1 tuple needed by Google Test and Google Mock. 36 | 37 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ 38 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ 39 | 40 | #include // For ::std::pair. 41 | 42 | // The compiler used in Symbian has a bug that prevents us from declaring the 43 | // tuple template as a friend (it complains that tuple is redefined). This 44 | // hack bypasses the bug by declaring the members that should otherwise be 45 | // private as public. 46 | // Sun Studio versions < 12 also have the above bug. 47 | #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) 48 | # define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: 49 | #else 50 | # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ 51 | template friend class tuple; \ 52 | private: 53 | #endif 54 | 55 | 56 | $range i 0..n-1 57 | $range j 0..n 58 | $range k 1..n 59 | // GTEST_n_TUPLE_(T) is the type of an n-tuple. 60 | #define GTEST_0_TUPLE_(T) tuple<> 61 | 62 | $for k [[ 63 | $range m 0..k-1 64 | $range m2 k..n-1 65 | #define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]> 66 | 67 | ]] 68 | 69 | // GTEST_n_TYPENAMES_(T) declares a list of n typenames. 70 | 71 | $for j [[ 72 | $range m 0..j-1 73 | #define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]] 74 | 75 | 76 | ]] 77 | 78 | // In theory, defining stuff in the ::std namespace is undefined 79 | // behavior. We can do this as we are playing the role of a standard 80 | // library vendor. 81 | namespace std { 82 | namespace tr1 { 83 | 84 | template <$for i, [[typename T$i = void]]> 85 | class tuple; 86 | 87 | // Anything in namespace gtest_internal is Google Test's INTERNAL 88 | // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. 89 | namespace gtest_internal { 90 | 91 | // ByRef::type is T if T is a reference; otherwise it's const T&. 92 | template 93 | struct ByRef { typedef const T& type; }; // NOLINT 94 | template 95 | struct ByRef { typedef T& type; }; // NOLINT 96 | 97 | // A handy wrapper for ByRef. 98 | #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type 99 | 100 | // AddRef::type is T if T is a reference; otherwise it's T&. This 101 | // is the same as tr1::add_reference::type. 102 | template 103 | struct AddRef { typedef T& type; }; // NOLINT 104 | template 105 | struct AddRef { typedef T& type; }; // NOLINT 106 | 107 | // A handy wrapper for AddRef. 108 | #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type 109 | 110 | // A helper for implementing get(). 111 | template class Get; 112 | 113 | // A helper for implementing tuple_element. kIndexValid is true 114 | // iff k < the number of fields in tuple type T. 115 | template 116 | struct TupleElement; 117 | 118 | 119 | $for i [[ 120 | template 121 | struct TupleElement [[]] 122 | { typedef T$i type; }; 123 | 124 | 125 | ]] 126 | } // namespace gtest_internal 127 | 128 | template <> 129 | class tuple<> { 130 | public: 131 | tuple() {} 132 | tuple(const tuple& /* t */) {} 133 | tuple& operator=(const tuple& /* t */) { return *this; } 134 | }; 135 | 136 | 137 | $for k [[ 138 | $range m 0..k-1 139 | template 140 | class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { 141 | public: 142 | template friend class gtest_internal::Get; 143 | 144 | tuple() : $for m, [[f$(m)_()]] {} 145 | 146 | explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]] 147 | $for m, [[f$(m)_(f$m)]] {} 148 | 149 | tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} 150 | 151 | template 152 | tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} 153 | 154 | $if k == 2 [[ 155 | template 156 | tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} 157 | 158 | ]] 159 | 160 | tuple& operator=(const tuple& t) { return CopyFrom(t); } 161 | 162 | template 163 | tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) { 164 | return CopyFrom(t); 165 | } 166 | 167 | $if k == 2 [[ 168 | template 169 | tuple& operator=(const ::std::pair& p) { 170 | f0_ = p.first; 171 | f1_ = p.second; 172 | return *this; 173 | } 174 | 175 | ]] 176 | 177 | GTEST_DECLARE_TUPLE_AS_FRIEND_ 178 | 179 | template 180 | tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) { 181 | 182 | $for m [[ 183 | f$(m)_ = t.f$(m)_; 184 | 185 | ]] 186 | return *this; 187 | } 188 | 189 | 190 | $for m [[ 191 | T$m f$(m)_; 192 | 193 | ]] 194 | }; 195 | 196 | 197 | ]] 198 | // 6.1.3.2 Tuple creation functions. 199 | 200 | // Known limitations: we don't support passing an 201 | // std::tr1::reference_wrapper to make_tuple(). And we don't 202 | // implement tie(). 203 | 204 | inline tuple<> make_tuple() { return tuple<>(); } 205 | 206 | $for k [[ 207 | $range m 0..k-1 208 | 209 | template 210 | inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) { 211 | return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]); 212 | } 213 | 214 | ]] 215 | 216 | // 6.1.3.3 Tuple helper classes. 217 | 218 | template struct tuple_size; 219 | 220 | 221 | $for j [[ 222 | template 223 | struct tuple_size { static const int value = $j; }; 224 | 225 | 226 | ]] 227 | template 228 | struct tuple_element { 229 | typedef typename gtest_internal::TupleElement< 230 | k < (tuple_size::value), k, Tuple>::type type; 231 | }; 232 | 233 | #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type 234 | 235 | // 6.1.3.4 Element access. 236 | 237 | namespace gtest_internal { 238 | 239 | 240 | $for i [[ 241 | template <> 242 | class Get<$i> { 243 | public: 244 | template 245 | static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) 246 | Field(Tuple& t) { return t.f$(i)_; } // NOLINT 247 | 248 | template 249 | static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) 250 | ConstField(const Tuple& t) { return t.f$(i)_; } 251 | }; 252 | 253 | 254 | ]] 255 | } // namespace gtest_internal 256 | 257 | template 258 | GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) 259 | get(GTEST_$(n)_TUPLE_(T)& t) { 260 | return gtest_internal::Get::Field(t); 261 | } 262 | 263 | template 264 | GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) 265 | get(const GTEST_$(n)_TUPLE_(T)& t) { 266 | return gtest_internal::Get::ConstField(t); 267 | } 268 | 269 | // 6.1.3.5 Relational operators 270 | 271 | // We only implement == and !=, as we don't have a need for the rest yet. 272 | 273 | namespace gtest_internal { 274 | 275 | // SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the 276 | // first k fields of t1 equals the first k fields of t2. 277 | // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if 278 | // k1 != k2. 279 | template 280 | struct SameSizeTuplePrefixComparator; 281 | 282 | template <> 283 | struct SameSizeTuplePrefixComparator<0, 0> { 284 | template 285 | static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { 286 | return true; 287 | } 288 | }; 289 | 290 | template 291 | struct SameSizeTuplePrefixComparator { 292 | template 293 | static bool Eq(const Tuple1& t1, const Tuple2& t2) { 294 | return SameSizeTuplePrefixComparator::Eq(t1, t2) && 295 | ::std::tr1::get(t1) == ::std::tr1::get(t2); 296 | } 297 | }; 298 | 299 | } // namespace gtest_internal 300 | 301 | template 302 | inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t, 303 | const GTEST_$(n)_TUPLE_(U)& u) { 304 | return gtest_internal::SameSizeTuplePrefixComparator< 305 | tuple_size::value, 306 | tuple_size::value>::Eq(t, u); 307 | } 308 | 309 | template 310 | inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t, 311 | const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); } 312 | 313 | // 6.1.4 Pairs. 314 | // Unimplemented. 315 | 316 | } // namespace tr1 317 | } // namespace std 318 | 319 | 320 | $for j [[ 321 | #undef GTEST_$(j)_TUPLE_ 322 | 323 | ]] 324 | 325 | 326 | $for j [[ 327 | #undef GTEST_$(j)_TYPENAMES_ 328 | 329 | ]] 330 | 331 | #undef GTEST_DECLARE_TUPLE_AS_FRIEND_ 332 | #undef GTEST_BY_REF_ 333 | #undef GTEST_ADD_REF_ 334 | #undef GTEST_TUPLE_ELEMENT_ 335 | 336 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ 337 | -------------------------------------------------------------------------------- /google/gtest/internal/gtest-type-util.h.pump: -------------------------------------------------------------------------------- 1 | $$ -*- mode: c++; -*- 2 | $var n = 50 $$ Maximum length of type lists we want to support. 3 | // Copyright 2008 Google Inc. 4 | // All Rights Reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | // 32 | // Author: wan@google.com (Zhanyong Wan) 33 | 34 | // Type utilities needed for implementing typed and type-parameterized 35 | // tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! 36 | // 37 | // Currently we support at most $n types in a list, and at most $n 38 | // type-parameterized tests in one type-parameterized test case. 39 | // Please contact googletestframework@googlegroups.com if you need 40 | // more. 41 | 42 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 43 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 44 | 45 | #include "gtest/internal/gtest-port.h" 46 | #include "gtest/internal/gtest-string.h" 47 | 48 | // #ifdef __GNUC__ is too general here. It is possible to use gcc without using 49 | // libstdc++ (which is where cxxabi.h comes from). 50 | # ifdef __GLIBCXX__ 51 | # include 52 | # elif defined(__HP_aCC) 53 | # include 54 | # endif // __GLIBCXX__ 55 | 56 | namespace testing { 57 | namespace internal { 58 | 59 | // GetTypeName() returns a human-readable name of type T. 60 | // NB: This function is also used in Google Mock, so don't move it inside of 61 | // the typed-test-only section below. 62 | template 63 | String GetTypeName() { 64 | # if GTEST_HAS_RTTI 65 | 66 | const char* const name = typeid(T).name(); 67 | # if defined(__GLIBCXX__) || defined(__HP_aCC) 68 | int status = 0; 69 | // gcc's implementation of typeid(T).name() mangles the type name, 70 | // so we have to demangle it. 71 | # ifdef __GLIBCXX__ 72 | using abi::__cxa_demangle; 73 | # endif // __GLIBCXX__ 74 | char* const readable_name = __cxa_demangle(name, 0, 0, &status); 75 | const String name_str(status == 0 ? readable_name : name); 76 | free(readable_name); 77 | return name_str; 78 | # else 79 | return name; 80 | # endif // __GLIBCXX__ || __HP_aCC 81 | 82 | # else 83 | 84 | return ""; 85 | 86 | # endif // GTEST_HAS_RTTI 87 | } 88 | 89 | #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P 90 | 91 | // AssertyTypeEq::type is defined iff T1 and T2 are the same 92 | // type. This can be used as a compile-time assertion to ensure that 93 | // two types are equal. 94 | 95 | template 96 | struct AssertTypeEq; 97 | 98 | template 99 | struct AssertTypeEq { 100 | typedef bool type; 101 | }; 102 | 103 | // A unique type used as the default value for the arguments of class 104 | // template Types. This allows us to simulate variadic templates 105 | // (e.g. Types, Type, and etc), which C++ doesn't 106 | // support directly. 107 | struct None {}; 108 | 109 | // The following family of struct and struct templates are used to 110 | // represent type lists. In particular, TypesN 111 | // represents a type list with N types (T1, T2, ..., and TN) in it. 112 | // Except for Types0, every struct in the family has two member types: 113 | // Head for the first type in the list, and Tail for the rest of the 114 | // list. 115 | 116 | // The empty type list. 117 | struct Types0 {}; 118 | 119 | // Type lists of length 1, 2, 3, and so on. 120 | 121 | template 122 | struct Types1 { 123 | typedef T1 Head; 124 | typedef Types0 Tail; 125 | }; 126 | 127 | $range i 2..n 128 | 129 | $for i [[ 130 | $range j 1..i 131 | $range k 2..i 132 | template <$for j, [[typename T$j]]> 133 | struct Types$i { 134 | typedef T1 Head; 135 | typedef Types$(i-1)<$for k, [[T$k]]> Tail; 136 | }; 137 | 138 | 139 | ]] 140 | 141 | } // namespace internal 142 | 143 | // We don't want to require the users to write TypesN<...> directly, 144 | // as that would require them to count the length. Types<...> is much 145 | // easier to write, but generates horrible messages when there is a 146 | // compiler error, as gcc insists on printing out each template 147 | // argument, even if it has the default value (this means Types 148 | // will appear as Types in the compiler 149 | // errors). 150 | // 151 | // Our solution is to combine the best part of the two approaches: a 152 | // user would write Types, and Google Test will translate 153 | // that to TypesN internally to make error messages 154 | // readable. The translation is done by the 'type' member of the 155 | // Types template. 156 | 157 | $range i 1..n 158 | template <$for i, [[typename T$i = internal::None]]> 159 | struct Types { 160 | typedef internal::Types$n<$for i, [[T$i]]> type; 161 | }; 162 | 163 | template <> 164 | struct Types<$for i, [[internal::None]]> { 165 | typedef internal::Types0 type; 166 | }; 167 | 168 | $range i 1..n-1 169 | $for i [[ 170 | $range j 1..i 171 | $range k i+1..n 172 | template <$for j, [[typename T$j]]> 173 | struct Types<$for j, [[T$j]]$for k[[, internal::None]]> { 174 | typedef internal::Types$i<$for j, [[T$j]]> type; 175 | }; 176 | 177 | ]] 178 | 179 | namespace internal { 180 | 181 | # define GTEST_TEMPLATE_ template class 182 | 183 | // The template "selector" struct TemplateSel is used to 184 | // represent Tmpl, which must be a class template with one type 185 | // parameter, as a type. TemplateSel::Bind::type is defined 186 | // as the type Tmpl. This allows us to actually instantiate the 187 | // template "selected" by TemplateSel. 188 | // 189 | // This trick is necessary for simulating typedef for class templates, 190 | // which C++ doesn't support directly. 191 | template 192 | struct TemplateSel { 193 | template 194 | struct Bind { 195 | typedef Tmpl type; 196 | }; 197 | }; 198 | 199 | # define GTEST_BIND_(TmplSel, T) \ 200 | TmplSel::template Bind::type 201 | 202 | // A unique struct template used as the default value for the 203 | // arguments of class template Templates. This allows us to simulate 204 | // variadic templates (e.g. Templates, Templates, 205 | // and etc), which C++ doesn't support directly. 206 | template 207 | struct NoneT {}; 208 | 209 | // The following family of struct and struct templates are used to 210 | // represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except 212 | // for Templates0, every struct in the family has two member types: 213 | // Head for the selector of the first template in the list, and Tail 214 | // for the rest of the list. 215 | 216 | // The empty template list. 217 | struct Templates0 {}; 218 | 219 | // Template lists of length 1, 2, 3, and so on. 220 | 221 | template 222 | struct Templates1 { 223 | typedef TemplateSel Head; 224 | typedef Templates0 Tail; 225 | }; 226 | 227 | $range i 2..n 228 | 229 | $for i [[ 230 | $range j 1..i 231 | $range k 2..i 232 | template <$for j, [[GTEST_TEMPLATE_ T$j]]> 233 | struct Templates$i { 234 | typedef TemplateSel Head; 235 | typedef Templates$(i-1)<$for k, [[T$k]]> Tail; 236 | }; 237 | 238 | 239 | ]] 240 | 241 | // We don't want to require the users to write TemplatesN<...> directly, 242 | // as that would require them to count the length. Templates<...> is much 243 | // easier to write, but generates horrible messages when there is a 244 | // compiler error, as gcc insists on printing out each template 245 | // argument, even if it has the default value (this means Templates 246 | // will appear as Templates in the compiler 247 | // errors). 248 | // 249 | // Our solution is to combine the best part of the two approaches: a 250 | // user would write Templates, and Google Test will translate 251 | // that to TemplatesN internally to make error messages 252 | // readable. The translation is done by the 'type' member of the 253 | // Templates template. 254 | 255 | $range i 1..n 256 | template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]> 257 | struct Templates { 258 | typedef Templates$n<$for i, [[T$i]]> type; 259 | }; 260 | 261 | template <> 262 | struct Templates<$for i, [[NoneT]]> { 263 | typedef Templates0 type; 264 | }; 265 | 266 | $range i 1..n-1 267 | $for i [[ 268 | $range j 1..i 269 | $range k i+1..n 270 | template <$for j, [[GTEST_TEMPLATE_ T$j]]> 271 | struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> { 272 | typedef Templates$i<$for j, [[T$j]]> type; 273 | }; 274 | 275 | ]] 276 | 277 | // The TypeList template makes it possible to use either a single type 278 | // or a Types<...> list in TYPED_TEST_CASE() and 279 | // INSTANTIATE_TYPED_TEST_CASE_P(). 280 | 281 | template 282 | struct TypeList { typedef Types1 type; }; 283 | 284 | 285 | $range i 1..n 286 | template <$for i, [[typename T$i]]> 287 | struct TypeList > { 288 | typedef typename Types<$for i, [[T$i]]>::type type; 289 | }; 290 | 291 | #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P 292 | 293 | } // namespace internal 294 | } // namespace testing 295 | 296 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 297 | -------------------------------------------------------------------------------- /tracer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tracer", "tracer\tracer.vcxproj", "{DA952C05-1E1C-4CDE-A35A-C7CB6B171B2B}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tracer_test", "tracer_test\tracer_test.vcxproj", "{233597F6-A348-4844-B3F4-904D0099CA44}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {DA952C05-1E1C-4CDE-A35A-C7CB6B171B2B}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {DA952C05-1E1C-4CDE-A35A-C7CB6B171B2B}.Debug|Win32.Build.0 = Debug|Win32 16 | {DA952C05-1E1C-4CDE-A35A-C7CB6B171B2B}.Release|Win32.ActiveCfg = Release|Win32 17 | {DA952C05-1E1C-4CDE-A35A-C7CB6B171B2B}.Release|Win32.Build.0 = Release|Win32 18 | {233597F6-A348-4844-B3F4-904D0099CA44}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {233597F6-A348-4844-B3F4-904D0099CA44}.Debug|Win32.Build.0 = Debug|Win32 20 | {233597F6-A348-4844-B3F4-904D0099CA44}.Release|Win32.ActiveCfg = Release|Win32 21 | {233597F6-A348-4844-B3F4-904D0099CA44}.Release|Win32.Build.0 = Release|Win32 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /tracer/arg_recorder.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/arg_recorder.hpp -------------------------------------------------------------------------------- /tracer/call_count_recorder.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/call_count_recorder.hpp -------------------------------------------------------------------------------- /tracer/call_stack_recorder.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/call_stack_recorder.hpp -------------------------------------------------------------------------------- /tracer/dbg_helper.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/dbg_helper.cpp -------------------------------------------------------------------------------- /tracer/dbg_helper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/dbg_helper.h -------------------------------------------------------------------------------- /tracer/detours/detver.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Common version parameters. 4 | // 5 | // Microsoft Research Detours Package, Version 3.0 Build_316. 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #ifndef DETOURS_STRINGIFY 11 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 12 | #define DETOURS_STRINGIFY_(x) #x 13 | #endif 14 | 15 | #define VER_FILEFLAGSMASK 0x3fL 16 | #define VER_FILEFLAGS 0x0L 17 | #define VER_FILEOS 0x00040004L 18 | #define VER_FILETYPE 0x00000002L 19 | #define VER_FILESUBTYPE 0x00000000L 20 | 21 | #define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS) 22 | -------------------------------------------------------------------------------- /tracer/detours/syelog.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Detours Test Program (syelog.h of syelog.lib) 4 | // 5 | // Microsoft Research Detours Package, Version 3.0. 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | #pragma once 10 | #ifndef _SYELOGD_H_ 11 | #define _SYELOGD_H_ 12 | #include 13 | 14 | #pragma pack(push, 1) 15 | #pragma warning(push) 16 | #pragma warning(disable: 4200) 17 | 18 | ////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // 21 | #define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog" 22 | #define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog" 23 | #ifdef UNICODE 24 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW 25 | #else 26 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA 27 | #endif 28 | 29 | ////////////////////////////////////////////////////////////////////////////// 30 | // 31 | #define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff) 32 | 33 | typedef struct _SYELOG_MESSAGE 34 | { 35 | USHORT nBytes; 36 | BYTE nFacility; 37 | BYTE nSeverity; 38 | DWORD nProcessId; 39 | FILETIME ftOccurance; 40 | BOOL fTerminate; 41 | CHAR szMessage[SYELOG_MAXIMUM_MESSAGE]; 42 | } SYELOG_MESSAGE, *PSYELOG_MESSAGE; 43 | 44 | 45 | // Facility Codes. 46 | // 47 | #define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel 48 | #define SYELOG_FACILITY_SECURITY 0x20 // OS Security 49 | #define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal 50 | #define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon 51 | #define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application 52 | #define SYELOG_FACILITY_USER 0x60 // User self-generated. 53 | #define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined. 54 | #define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined. 55 | #define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined. 56 | #define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined. 57 | #define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined. 58 | #define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined. 59 | #define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined. 60 | #define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined. 61 | #define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined. 62 | #define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined. 63 | 64 | // Severity Codes. 65 | // 66 | #define SYELOG_SEVERITY_FATAL 0x00 // System is dead. 67 | #define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately. 68 | #define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition. 69 | #define SYELOG_SEVERITY_ERROR 0x30 // Error 70 | #define SYELOG_SEVERITY_WARNING 0x40 // Warning 71 | #define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition. 72 | #define SYELOG_SEVERITY_INFORMATION 0x60 // Informational 73 | #define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed 74 | #define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded 75 | #define SYELOG_SEVERITY_DEBUG 0x70 // Debugging 76 | 77 | // Logging Functions. 78 | // 79 | VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility); 80 | VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...); 81 | VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args); 82 | VOID SyelogClose(BOOL fTerminate); 83 | 84 | #pragma warning(pop) 85 | #pragma pack(pop) 86 | 87 | #endif // _SYELOGD_H_ 88 | // 89 | ///////////////////////////////////////////////////////////////// End of File. 90 | -------------------------------------------------------------------------------- /tracer/detours/uimports.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Add DLLs to a module import table (uimports.cpp of detours.lib) 4 | // 5 | // Microsoft Research Detours Package, Version 3.0 Build_316. 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | // Note that this file is included into creatwth.cpp one or more times 10 | // (once for each supported module format). 11 | // 12 | 13 | // UpdateImports32 aka UpdateImports64 14 | static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess, 15 | HMODULE hModule, 16 | LPCSTR *plpDlls, 17 | DWORD nDlls) 18 | { 19 | BOOL fSucceeded = FALSE; 20 | BYTE * pbNew = NULL; 21 | DWORD i; 22 | 23 | PBYTE pbModule = (PBYTE)hModule; 24 | 25 | IMAGE_DOS_HEADER idh; 26 | ZeroMemory(&idh, sizeof(idh)); 27 | if (!ReadProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) { 28 | DETOUR_TRACE(("ReadProcessMemory(idh@%p..%p) failed: %d\n", 29 | pbModule, pbModule + sizeof(idh), GetLastError())); 30 | 31 | finish: 32 | if (pbNew != NULL) { 33 | delete[] pbNew; 34 | pbNew = NULL; 35 | } 36 | return fSucceeded; 37 | } 38 | 39 | IMAGE_NT_HEADERS_XX inh; 40 | ZeroMemory(&inh, sizeof(inh)); 41 | 42 | if (!ReadProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), NULL)) { 43 | DETOUR_TRACE(("ReadProcessMemory(inh@%p..%p) failed: %d\n", 44 | pbModule + idh.e_lfanew, 45 | pbModule + idh.e_lfanew + sizeof(inh), 46 | GetLastError())); 47 | goto finish; 48 | } 49 | 50 | if (inh.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC_XX) { 51 | DETOUR_TRACE(("Wrong size image (%04x != %04x).\n", 52 | inh.OptionalHeader.Magic, IMAGE_NT_OPTIONAL_HDR_MAGIC_XX)); 53 | SetLastError(ERROR_INVALID_BLOCK); 54 | goto finish; 55 | } 56 | 57 | // Zero out the bound table so loader doesn't use it instead of our new table. 58 | inh.BOUND_DIRECTORY.VirtualAddress = 0; 59 | inh.BOUND_DIRECTORY.Size = 0; 60 | 61 | // Find the size of the mapped file. 62 | DWORD dwFileSize = 0; 63 | DWORD dwSec = idh.e_lfanew + 64 | FIELD_OFFSET(IMAGE_NT_HEADERS_XX, OptionalHeader) + 65 | inh.FileHeader.SizeOfOptionalHeader; 66 | 67 | for (i = 0; i < inh.FileHeader.NumberOfSections; i++) { 68 | IMAGE_SECTION_HEADER ish; 69 | ZeroMemory(&ish, sizeof(ish)); 70 | 71 | if (!ReadProcessMemory(hProcess, pbModule + dwSec + sizeof(ish) * i, &ish, 72 | sizeof(ish), NULL)) { 73 | DETOUR_TRACE(("ReadProcessMemory(ish@%p..%p) failed: %d\n", 74 | pbModule + dwSec + sizeof(ish) * i, 75 | pbModule + dwSec + sizeof(ish) * (i + 1), 76 | GetLastError())); 77 | goto finish; 78 | } 79 | 80 | DETOUR_TRACE(("ish[%d] : va=%08x sr=%d\n", i, ish.VirtualAddress, ish.SizeOfRawData)); 81 | 82 | // If the file didn't have an IAT_DIRECTORY, we assign it... 83 | if (inh.IAT_DIRECTORY.VirtualAddress == 0 && 84 | inh.IMPORT_DIRECTORY.VirtualAddress >= ish.VirtualAddress && 85 | inh.IMPORT_DIRECTORY.VirtualAddress < ish.VirtualAddress + ish.SizeOfRawData) { 86 | 87 | inh.IAT_DIRECTORY.VirtualAddress = ish.VirtualAddress; 88 | inh.IAT_DIRECTORY.Size = ish.SizeOfRawData; 89 | } 90 | 91 | // Find the end of the file... 92 | if (dwFileSize < ish.PointerToRawData + ish.SizeOfRawData) { 93 | dwFileSize = ish.PointerToRawData + ish.SizeOfRawData; 94 | } 95 | } 96 | DETOUR_TRACE(("dwFileSize = %08x\n", dwFileSize)); 97 | 98 | #if IGNORE_CHECKSUMS 99 | // Find the current checksum. 100 | WORD wBefore = ComputeChkSum(hProcess, pbModule, &inh); 101 | DETOUR_TRACE(("ChkSum: %04x + %08x => %08x\n", wBefore, dwFileSize, wBefore + dwFileSize)); 102 | #endif 103 | 104 | DETOUR_TRACE((" Imports: %p..%p\n", 105 | (DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress, 106 | (DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress + 107 | inh.IMPORT_DIRECTORY.Size)); 108 | 109 | DWORD obRem = sizeof(IMAGE_IMPORT_DESCRIPTOR) * nDlls; 110 | DWORD obTab = PadToDwordPtr(obRem + 111 | inh.IMPORT_DIRECTORY.Size + 112 | sizeof(IMAGE_IMPORT_DESCRIPTOR)); 113 | DWORD obDll = obTab + sizeof(DWORD_XX) * 4 * nDlls; 114 | DWORD obStr = obDll; 115 | DWORD cbNew = obStr; 116 | DWORD n; 117 | for (n = 0; n < nDlls; n++) { 118 | cbNew += PadToDword((DWORD)strlen(plpDlls[n]) + 1); 119 | } 120 | 121 | pbNew = new BYTE [cbNew]; 122 | if (pbNew == NULL) { 123 | DETOUR_TRACE(("new BYTE [cbNew] failed.\n")); 124 | goto finish; 125 | } 126 | ZeroMemory(pbNew, cbNew); 127 | 128 | PBYTE pbBase = pbModule; 129 | PBYTE pbNext = pbBase 130 | + inh.OptionalHeader.BaseOfCode 131 | + inh.OptionalHeader.SizeOfCode 132 | + inh.OptionalHeader.SizeOfInitializedData 133 | + inh.OptionalHeader.SizeOfUninitializedData; 134 | if (pbBase < pbNext) { 135 | pbBase = pbNext; 136 | } 137 | DETOUR_TRACE(("pbBase = %p\n", pbBase)); 138 | 139 | PBYTE pbNewIid = FindAndAllocateNearBase(hProcess, pbBase, cbNew); 140 | if (pbNewIid == NULL) { 141 | DETOUR_TRACE(("FindAndAllocateNearBase failed.\n")); 142 | goto finish; 143 | } 144 | 145 | DWORD obBase = (DWORD)(pbNewIid - pbModule); 146 | DWORD dwProtect = 0; 147 | if (inh.IMPORT_DIRECTORY.VirtualAddress != 0) { 148 | // Read the old import directory if it exists. 149 | #if 0 150 | if (!VirtualProtectEx(hProcess, 151 | pbModule + inh.IMPORT_DIRECTORY.VirtualAddress, 152 | inh.IMPORT_DIRECTORY.Size, PAGE_EXECUTE_READWRITE, &dwProtect)) { 153 | DETOUR_TRACE(("VirtualProtectEx(import) write failed: %d\n", GetLastError())); 154 | goto finish; 155 | } 156 | #endif 157 | DETOUR_TRACE(("IMPORT_DIRECTORY perms=%x\n", dwProtect)); 158 | 159 | if (!ReadProcessMemory(hProcess, 160 | pbModule + inh.IMPORT_DIRECTORY.VirtualAddress, 161 | pbNew + obRem, 162 | inh.IMPORT_DIRECTORY.Size, NULL)) { 163 | DETOUR_TRACE(("ReadProcessMemory(imports) failed: %d\n", GetLastError())); 164 | goto finish; 165 | } 166 | } 167 | 168 | PIMAGE_IMPORT_DESCRIPTOR piid = (PIMAGE_IMPORT_DESCRIPTOR)pbNew; 169 | DWORD_XX *pt; 170 | 171 | for (n = 0; n < nDlls; n++) { 172 | HRESULT hrRet = StringCchCopyA((char*)pbNew + obStr, cbNew - obStr, plpDlls[n]); 173 | if (FAILED(hrRet)) { 174 | DETOUR_TRACE(("StringCchCopyA failed: %d\n", GetLastError())); 175 | goto finish; 176 | } 177 | 178 | // After copying the string, we patch up the size "??" bits if any. 179 | hrRet = ReplaceOptionalSizeA((char*)pbNew + obStr, 180 | cbNew - obStr, 181 | DETOURS_STRINGIFY(DETOURS_BITS_XX)); 182 | if (FAILED(hrRet)) { 183 | DETOUR_TRACE(("ReplaceOptionalSizeA failed: %d\n", GetLastError())); 184 | goto finish; 185 | } 186 | 187 | DWORD nOffset = obTab + (sizeof(DWORD_XX) * (4 * n)); 188 | piid[n].OriginalFirstThunk = obBase + nOffset; 189 | pt = ((DWORD_XX*)(pbNew + nOffset)); 190 | pt[0] = IMAGE_ORDINAL_FLAG_XX + 1; 191 | pt[1] = 0; 192 | 193 | nOffset = obTab + (sizeof(DWORD_XX) * ((4 * n) + 2)); 194 | piid[n].FirstThunk = obBase + nOffset; 195 | pt = ((DWORD_XX*)(pbNew + nOffset)); 196 | pt[0] = IMAGE_ORDINAL_FLAG_XX + 1; 197 | pt[1] = 0; 198 | piid[n].TimeDateStamp = 0; 199 | piid[n].ForwarderChain = 0; 200 | piid[n].Name = obBase + obStr; 201 | 202 | obStr += PadToDword((DWORD)strlen(plpDlls[n]) + 1); 203 | } 204 | 205 | for (i = 0; i < nDlls + (inh.IMPORT_DIRECTORY.Size / sizeof(*piid)); i++) { 206 | DETOUR_TRACE(("%8d. Look=%08x Time=%08x Fore=%08x Name=%08x Addr=%08x\n", 207 | i, 208 | piid[i].OriginalFirstThunk, 209 | piid[i].TimeDateStamp, 210 | piid[i].ForwarderChain, 211 | piid[i].Name, 212 | piid[i].FirstThunk)); 213 | if (piid[i].OriginalFirstThunk == 0 && piid[i].FirstThunk == 0) { 214 | break; 215 | } 216 | } 217 | 218 | if (!WriteProcessMemory(hProcess, pbNewIid, pbNew, obStr, NULL)) { 219 | DETOUR_TRACE(("WriteProcessMemory(iid) failed: %d\n", GetLastError())); 220 | goto finish; 221 | } 222 | 223 | DETOUR_TRACE(("obBaseBef = %08x..%08x\n", 224 | inh.IMPORT_DIRECTORY.VirtualAddress, 225 | inh.IMPORT_DIRECTORY.VirtualAddress + inh.IMPORT_DIRECTORY.Size)); 226 | DETOUR_TRACE(("obBaseAft = %08x..%08x\n", obBase, obBase + obStr)); 227 | 228 | // If the file doesn't have an IAT_DIRECTORY, we create it... 229 | if (inh.IAT_DIRECTORY.VirtualAddress == 0) { 230 | inh.IAT_DIRECTORY.VirtualAddress = obBase; 231 | inh.IAT_DIRECTORY.Size = cbNew; 232 | } 233 | 234 | inh.IMPORT_DIRECTORY.VirtualAddress = obBase; 235 | inh.IMPORT_DIRECTORY.Size = cbNew; 236 | 237 | /////////////////////// Update the NT header for the new import directory. 238 | /////////////////////////////// Update the DOS header to fix the checksum. 239 | // 240 | if (!VirtualProtectEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders, 241 | PAGE_EXECUTE_READWRITE, &dwProtect)) { 242 | DETOUR_TRACE(("VirtualProtectEx(inh) write failed: %d\n", GetLastError())); 243 | goto finish; 244 | } 245 | 246 | #if IGNORE_CHECKSUMS 247 | idh.e_res[0] = 0; 248 | #else 249 | inh.OptionalHeader.CheckSum = 0; 250 | #endif // IGNORE_CHECKSUMS 251 | 252 | if (!WriteProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) { 253 | DETOUR_TRACE(("WriteProcessMemory(idh) failed: %d\n", GetLastError())); 254 | goto finish; 255 | } 256 | DETOUR_TRACE(("WriteProcessMemory(idh:%p..%p)\n", pbModule, pbModule + sizeof(idh))); 257 | 258 | if (!WriteProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), NULL)) { 259 | DETOUR_TRACE(("WriteProcessMemory(inh) failed: %d\n", GetLastError())); 260 | goto finish; 261 | } 262 | DETOUR_TRACE(("WriteProcessMemory(inh:%p..%p)\n", 263 | pbModule + idh.e_lfanew, 264 | pbModule + idh.e_lfanew + sizeof(inh))); 265 | 266 | #if IGNORE_CHECKSUMS 267 | WORD wDuring = ComputeChkSum(hProcess, pbModule, &inh); 268 | DETOUR_TRACE(("ChkSum: %04x + %08x => %08x\n", wDuring, dwFileSize, wDuring + dwFileSize)); 269 | 270 | idh.e_res[0] = detour_sum_minus(idh.e_res[0], detour_sum_minus(wDuring, wBefore)); 271 | 272 | if (!WriteProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) { 273 | DETOUR_TRACE(("WriteProcessMemory(idh) failed: %d\n", GetLastError())); 274 | goto finish; 275 | } 276 | #endif // IGNORE_CHECKSUMS 277 | 278 | if (!VirtualProtectEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders, 279 | dwProtect, &dwProtect)) { 280 | DETOUR_TRACE(("VirtualProtectEx(idh) restore failed: %d\n", GetLastError())); 281 | goto finish; 282 | } 283 | 284 | #if IGNORE_CHECKSUMS 285 | WORD wAfter = ComputeChkSum(hProcess, pbModule, &inh); 286 | DETOUR_TRACE(("ChkSum: %04x + %08x => %08x\n", wAfter, dwFileSize, wAfter + dwFileSize)); 287 | DETOUR_TRACE(("Before: %08x, After: %08x\n", wBefore + dwFileSize, wAfter + dwFileSize)); 288 | 289 | if (wBefore != wAfter) { 290 | DETOUR_TRACE(("Restore of checksum failed %04x != %04x.\n", wBefore, wAfter)); 291 | goto finish; 292 | } 293 | #endif // IGNORE_CHECKSUMS 294 | 295 | fSucceeded = TRUE; 296 | goto finish; 297 | } 298 | 299 | -------------------------------------------------------------------------------- /tracer/fake_func_keeper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "function_type.hpp" 4 | 5 | #define GEN_FAKE_FUNC(cc) \ 6 | template struct Fake::value>::type> { \ 8 | static R cc Func(Args... args) { \ 9 | bool call_ori = true; \ 10 | SignalKeeper::signal(call_ori, args...); \ 11 | if (call_ori) { \ 12 | R ret(RealFuncKeeper::real(args...)); \ 13 | SignalKeeper::signal(call_ori, ret, args...); \ 14 | return ret; \ 15 | } \ 16 | R ret; \ 17 | SignalKeeper::signal(call_ori, ret, args...); \ 18 | return ret; \ 19 | } \ 20 | }; 21 | 22 | #define GEN_FAKE_VOID_FUNC(cc) \ 23 | template struct Fake::value>::type> { \ 25 | static void cc Func(Args... args) { \ 26 | bool call_ori = true; \ 27 | SignalKeeper::signal(call_ori, args...); \ 28 | if (call_ori) \ 29 | RealFuncKeeper::real(args...); \ 30 | SignalKeeper::signal(call_ori, args...); \ 31 | } \ 32 | }; 33 | 34 | #define GEN_FAKE_MEMBER(cc) \ 35 | template \ 36 | struct Fake::value>::type> : public C { \ 38 | R cc Func(Args... args) { \ 39 | bool call_ori = true; \ 40 | C *self = this; \ 41 | SignalKeeper::signal(call_ori, self, args...); \ 42 | if (call_ori) { \ 43 | R ret((self->*RealFuncKeeper::real)(args...)); \ 44 | SignalKeeper::signal(call_ori, ret, self, args...); \ 45 | return ret; \ 46 | } \ 47 | R ret; \ 48 | SignalKeeper::signal(call_ori, ret, self, args...); \ 49 | return ret; \ 50 | } \ 51 | }; 52 | 53 | #define GEN_FAKE_VOID_MEMBER(cc) \ 54 | template \ 55 | struct Fake::value>::type> : public C { \ 57 | void cc Func(Args... args) { \ 58 | bool call_ori = true; \ 59 | C *self = this; \ 60 | SignalKeeper::signal(call_ori, self, args...); \ 61 | if (call_ori) \ 62 | (self->*RealFuncKeeper::real)(args...); \ 63 | SignalKeeper::signal(call_ori, self, args...); \ 64 | } \ 65 | }; 66 | 67 | #define GEN_FAKE_CC(cc) \ 68 | GEN_FAKE_FUNC(cc) \ 69 | GEN_FAKE_VOID_FUNC(cc) \ 70 | GEN_FAKE_MEMBER(cc) \ 71 | GEN_FAKE_VOID_MEMBER(cc) 72 | 73 | #define GEN_FAKE \ 74 | GEN_FAKE_CC() \ 75 | GEN_FAKE_CC( __stdcall) 76 | 77 | namespace tracer { 78 | 79 | template 80 | struct FakeFuncKeeper { 81 | typedef typename FunctionPointer::type Pointer; 82 | static Pointer fake; 83 | 84 | template struct Fake; 85 | GEN_FAKE 86 | }; 87 | 88 | template 89 | typename FakeFuncKeeper::Pointer FakeFuncKeeper::fake = 90 | reinterpret_cast::Pointer>( 91 | &FakeFuncKeeper::Fake::Pointer>::Func); 92 | 93 | } // namespace tracer 94 | 95 | #undef GEN_FAKE 96 | #undef GEN_FAKE_CC 97 | #undef GEN_FAKE_FUNC 98 | #undef GEN_FAKE_VOID_FUNC 99 | #undef GEN_FAKE_MEMBER 100 | #undef GEN_FAKE_VOID_MEMBER -------------------------------------------------------------------------------- /tracer/function_type.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/function_type.hpp -------------------------------------------------------------------------------- /tracer/hook_impl.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/hook_impl.cpp -------------------------------------------------------------------------------- /tracer/hook_impl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/hook_impl.h -------------------------------------------------------------------------------- /tracer/hook_manager.cpp: -------------------------------------------------------------------------------- 1 | #include "hook_manager.h" 2 | 3 | namespace tracer { 4 | 5 | void HookManager::Clear() { 6 | for (auto itr : hooks_) 7 | RemoveImpl(itr.first, itr.second); 8 | hooks_.clear(); 9 | } 10 | 11 | LONG HookManager::Install_( void **target, void *detour ) { 12 | std::lock_guard l(lock_); 13 | 14 | auto itr = hooks_.find(target); 15 | if (itr != hooks_.end()) 16 | return ERROR_INVALID_HANDLE; 17 | 18 | LONG ret = InstallImpl(target, detour); 19 | if (NO_ERROR == ret) 20 | hooks_[target] = detour; 21 | return ret; 22 | } 23 | 24 | LONG HookManager::Remove_( void **target ) { 25 | std::lock_guard l(lock_); 26 | 27 | auto itr = hooks_.find(target); 28 | if (itr == hooks_.end()) 29 | return ERROR_INVALID_HANDLE; 30 | 31 | LONG ret = RemoveImpl(target, itr->second); 32 | if (NO_ERROR == ret) 33 | hooks_.erase(itr); 34 | return ret; 35 | } 36 | 37 | } // namespace tracer -------------------------------------------------------------------------------- /tracer/hook_manager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/hook_manager.h -------------------------------------------------------------------------------- /tracer/mixin_tracer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "trace.hpp" 4 | 5 | #define TRACER_MIXIN_TRACER_INHERIT_LIST(_, i, tuple) \ 6 | public BOOST_PP_SEQ_ELEM(i, BOOST_PP_TUPLE_ELEM(2, 1, tuple)) \ 7 | 8 | 9 | #define TRACER_MIXIN_TRACER_INIT_LIST(_, i, tuple) \ 10 | BOOST_PP_SEQ_ELEM(i, BOOST_PP_TUPLE_ELEM(2, 1, tuple)) \ 11 | ( \ 12 | *static_cast(this)) 13 | 14 | #define TRACER_MIXIN_TRACER_NAME \ 15 | BOOST_PP_CAT(MixinTracer, __LINE__) 16 | 17 | #define TRACER_TRACE_WITH(func, recorders) \ 18 | TRACER_TRACE(func); \ 19 | struct TRACER_MIXIN_TRACER_NAME : \ 20 | public TRACER_CLASS_NAME \ 21 | BOOST_PP_COMMA_IF(BOOST_PP_SEQ_SIZE(recorders)) \ 22 | BOOST_PP_ENUM(BOOST_PP_SEQ_SIZE(recorders), TRACER_MIXIN_TRACER_INHERIT_LIST, \ 23 | (TRACER_CLASS_NAME, recorders)) { \ 24 | TRACER_MIXIN_TRACER_NAME() BOOST_PP_IF(BOOST_PP_SEQ_SIZE(recorders), :, ) \ 25 | BOOST_PP_ENUM(BOOST_PP_SEQ_SIZE(recorders), TRACER_MIXIN_TRACER_INIT_LIST, \ 26 | (TRACER_CLASS_NAME, recorders)) \ 27 | {} \ 28 | } -------------------------------------------------------------------------------- /tracer/real_func_keeper.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/real_func_keeper.hpp -------------------------------------------------------------------------------- /tracer/ret_val_recorder.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/ret_val_recorder.hpp -------------------------------------------------------------------------------- /tracer/signal.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/signal.hpp -------------------------------------------------------------------------------- /tracer/signal_keeper.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/signal_keeper.hpp -------------------------------------------------------------------------------- /tracer/singleton.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QingYun/tracer/47b928db69e8fdd5746bffa00f775d73768576bf/tracer/singleton.hpp -------------------------------------------------------------------------------- /tracer/trace.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "function_type.hpp" 4 | #include "signal_keeper.hpp" 5 | #include "fake_func_keeper.hpp" 6 | #include "real_func_keeper.hpp" 7 | #include "hook_manager.h" 8 | 9 | namespace tracer { 10 | 11 | template struct BeforeSignalSignature; 12 | template struct AfterSignalSignature; 13 | 14 | template 15 | struct BeforeSignalSignature::value>::type> { 17 | typedef 18 | typename AllParamsToRef< 19 | typename PrependParameter< 20 | typename SetResultType< 21 | typename MemberToNormal::type, 22 | void 23 | >::type, 24 | bool 25 | >::type 26 | >::type type; 27 | }; 28 | 29 | template 30 | struct BeforeSignalSignature::value>::type> { 32 | typedef 33 | typename AllParamsToRef< 34 | typename PrependParameter< 35 | typename SetResultType::type, 36 | bool 37 | >::type 38 | >::type type; 39 | }; 40 | 41 | template 42 | struct AfterSignalSignature::value>::type> { 44 | typedef 45 | typename PrependParameter< 46 | typename AllParamsToRef< 47 | typename PrependParameter< 48 | typename SetResultType< 49 | typename MemberToNormal::type, 50 | void 51 | >::type, 52 | typename ResultType< 53 | typename MemberToNormal::type 54 | >::type 55 | >::type 56 | >::type, 57 | bool 58 | >::type type; 59 | }; 60 | 61 | template 62 | struct AfterSignalSignature::value>::type> { 64 | typedef 65 | typename PrependParameter< 66 | typename AllParamsToRef< 67 | typename PrependParameter< 68 | typename SetResultType::type, 69 | typename ResultType::type 70 | >::type 71 | >::type, 72 | bool 73 | >::type type; 74 | }; 75 | 76 | } // namespace tracer 77 | 78 | #define TRACER_CLASS_NAME BOOST_PP_CAT(Tracer, __LINE__) 79 | 80 | #define TRACER_TRACE(func) \ 81 | struct TRACER_CLASS_NAME { \ 82 | typedef ::std::remove_pointer::type Signature; \ 83 | struct BeforeSignal { \ 84 | typedef ::tracer::BeforeSignalSignature::type Signature; \ 85 | }; \ 86 | struct AfterSignal { \ 87 | typedef ::tracer::AfterSignalSignature::type Signature; \ 88 | }; \ 89 | private: \ 90 | ::tracer::Signal &before_signal_; \ 91 | ::tracer::Signal &after_signal_; \ 92 | public: \ 93 | TRACER_CLASS_NAME() : \ 94 | before_signal_(::tracer::SignalKeeper::signal), \ 95 | after_signal_(::tracer::SignalKeeper::signal) { \ 96 | ::tracer::RealFuncKeeper::real = func; \ 97 | if (NO_ERROR != ::tracer::HookManager::Instance().Install( \ 98 | reinterpret_cast(&::tracer::RealFuncKeeper< \ 99 | TRACER_CLASS_NAME>::real), \ 100 | reinterpret_cast(::tracer::FakeFuncKeeper< \ 101 | TRACER_CLASS_NAME>::fake))) \ 102 | throw ::std::runtime_error(BOOST_PP_STRINGIZE( \ 103 | BOOST_PP_CAT(BOOST_PP_CAT(Hook, \ 104 | TRACER_CLASS_NAME), fail))); \ 105 | } \ 106 | ~TRACER_CLASS_NAME() { \ 107 | ::tracer::HookManager::Instance().Remove(reinterpret_cast( \ 108 | &::tracer::RealFuncKeeper::real)); \ 109 | } \ 110 | ::tracer::Signal &Before() { return before_signal_; } \ 111 | ::tracer::Signal &After() { return after_signal_; } \ 112 | ::tracer::FunctionPointer::type RealFunc() { \ 113 | return ::tracer::RealFuncKeeper::real; \ 114 | } \ 115 | } 116 | -------------------------------------------------------------------------------- /tracer/tracer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "trace.hpp" 3 | #include "call_count_recorder.hpp" 4 | #include "arg_recorder.hpp" 5 | #include "ret_val_recorder.hpp" 6 | #include "call_stack_recorder.hpp" 7 | #include "mixin_tracer.hpp" -------------------------------------------------------------------------------- /tracer/tracer.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {DA952C05-1E1C-4CDE-A35A-C7CB6B171B2B} 15 | tracer 16 | 17 | 18 | 19 | StaticLibrary 20 | true 21 | v120 22 | MultiByte 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Level3 45 | Disabled 46 | DETOURS_X86;DETOURS_32BIT;%(PreprocessorDefinitions) 47 | D:\boost\boost-trunk\ 48 | 49 | 50 | true 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /tracer/tracer.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {49d1b2b7-3bb0-460d-9219-a2312b8a8d41} 18 | 19 | 20 | {da6a4689-63ec-429c-9567-78ddd6c8817a} 21 | 22 | 23 | 24 | 25 | detours 26 | 27 | 28 | detours 29 | 30 | 31 | detours 32 | 33 | 34 | detours 35 | 36 | 37 | detours 38 | 39 | 40 | detours 41 | 42 | 43 | 源文件 44 | 45 | 46 | 源文件 47 | 48 | 49 | 源文件 50 | 51 | 52 | 53 | 54 | detours 55 | 56 | 57 | detours 58 | 59 | 60 | detours 61 | 62 | 63 | 头文件 64 | 65 | 66 | 头文件 67 | 68 | 69 | 头文件 70 | 71 | 72 | 头文件 73 | 74 | 75 | 头文件 76 | 77 | 78 | 头文件 79 | 80 | 81 | 头文件 82 | 83 | 84 | 头文件 85 | 86 | 87 | 头文件 88 | 89 | 90 | 头文件 91 | 92 | 93 | recorders 94 | 95 | 96 | recorders 97 | 98 | 99 | recorders 100 | 101 | 102 | recorders 103 | 104 | 105 | 头文件 106 | 107 | 108 | 头文件 109 | 110 | 111 | -------------------------------------------------------------------------------- /tracer_test/dbg_helper_test.cpp: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "dbg_helper.h" 3 | 4 | namespace tracer { 5 | 6 | void Foo() {} 7 | 8 | TEST(DbgHelperTest, GetSymbolNameTest) { 9 | EXPECT_NO_THROW(DbgHelper::Instance().GetSymbolName(reinterpret_cast(Foo))); 10 | } 11 | 12 | TEST(DbgHelperTest, StackWalkTest) { 13 | CONTEXT c; 14 | c.ContextFlags = CONTEXT_FULL; 15 | RtlCaptureContext(&c); 16 | for (auto itr = DbgHelper::Instance().StackWalk(&c); itr; ++itr) { 17 | EXPECT_NO_THROW(DbgHelper::Instance().GetSymbolName(itr->AddrPC.Offset)); 18 | EXPECT_NO_THROW(DbgHelper::Instance().GetFileName(itr->AddrPC.Offset)); 19 | EXPECT_NO_THROW(DbgHelper::Instance().GetLine(itr->AddrPC.Offset)); 20 | } 21 | } 22 | 23 | } // namespace tracer -------------------------------------------------------------------------------- /tracer_test/function_type_test.cpp: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include 3 | #include "function_type.hpp" 4 | 5 | namespace tracer { 6 | 7 | using namespace testing; 8 | 9 | struct A { 10 | HRESULT WINAPI F0(); 11 | HRESULT WINAPI F1(int); 12 | HRESULT WINAPI F2(char, short, int, long, long long, 13 | unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long); 14 | }; 15 | 16 | TEST(FunctionTypeTest, COMToNormalTest) { 17 | StaticAssertTypeEq::type>(); 18 | StaticAssertTypeEq::type>(); 19 | StaticAssertTypeEq::type>(); 22 | } 23 | 24 | void WINAPI F1(); 25 | int F2(double); 26 | A F3(char, short, int, long, long long, 27 | unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long); 28 | 29 | TEST(FunctionTypeTest, PrependParameterTest) { 30 | StaticAssertTypeEq::type>(); 31 | StaticAssertTypeEq::type>(); 32 | StaticAssertTypeEq::type>(); 34 | StaticAssertTypeEq::type>(); 35 | } 36 | 37 | void F4(char*, short&); 38 | int WINAPI F5(int&&); 39 | 40 | TEST(FunctionTypeTest, AllParamsToRefTest) { 41 | StaticAssertTypeEq::type>(); 42 | StaticAssertTypeEq::type>(); 43 | StaticAssertTypeEq::type>(); 44 | StaticAssertTypeEq::type>(); 45 | } 46 | 47 | TEST(FunctionTypeTest, SetResultTypeTest) { 48 | StaticAssertTypeEq::type>(); 49 | StaticAssertTypeEq::type>(); 50 | StaticAssertTypeEq::type>(); 51 | StaticAssertTypeEq::type>(); 52 | } 53 | 54 | TEST(FunctionTypeTest, RemoveStdcallTest) { 55 | StaticAssertTypeEq::type>(); 56 | StaticAssertTypeEq::type>(); 57 | } 58 | 59 | char &F6(); 60 | int&& WINAPI F7(); 61 | A *F8(); 62 | 63 | TEST(FunctionTypeTest, ResultTypeTest) { 64 | StaticAssertTypeEq::type>(); 65 | StaticAssertTypeEq::type>(); 66 | StaticAssertTypeEq::type>(); 67 | StaticAssertTypeEq::type>(); 68 | StaticAssertTypeEq::type>(); 69 | } 70 | 71 | } // namespace tracer -------------------------------------------------------------------------------- /tracer_test/gtest-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // Google C++ Testing Framework (Google Test) 33 | // 34 | // Sometimes it's desirable to build Google Test by compiling a single file. 35 | // This file serves this purpose. 36 | 37 | // This line ensures that gtest.h can be compiled on its own, even 38 | // when it's fused. 39 | #include "gtest/gtest.h" 40 | 41 | // The following lines pull in the real gtest *.cc files. 42 | #include "src/gtest.cc" 43 | #include "src/gtest-death-test.cc" 44 | #include "src/gtest-filepath.cc" 45 | #include "src/gtest-port.cc" 46 | #include "src/gtest-printers.cc" 47 | #include "src/gtest-test-part.cc" 48 | #include "src/gtest-typed-test.cc" 49 | -------------------------------------------------------------------------------- /tracer_test/hook_manager_test.cpp: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "hook_manager.h" 3 | #include 4 | 5 | namespace tracer { 6 | namespace { 7 | 8 | std::size_t StrSize(std::string str) { 9 | return str.size(); 10 | } 11 | 12 | decltype(StrSize) *RealStrSize = StrSize; 13 | std::string s2("12345"); 14 | std::size_t FakeStrSize(std::string str) { 15 | EXPECT_EQ(4, RealStrSize(str)); 16 | return RealStrSize(s2); 17 | } 18 | 19 | } 20 | 21 | TEST(HookManagerTest, NormalFuncTest) { 22 | HookManager hm; 23 | std::string s1("abcd"); 24 | 25 | EXPECT_EQ(s1.size(), StrSize(s1)); 26 | 27 | hm.Install(&RealStrSize, FakeStrSize); 28 | EXPECT_EQ(s2.size(), StrSize(s1)); 29 | 30 | hm.Remove(&RealStrSize); 31 | EXPECT_EQ(s1.size(), StrSize(s1)); 32 | } 33 | 34 | TEST(HookManagerTest, DtorTest) { 35 | std::string s1("abcd"); 36 | { 37 | HookManager hm; 38 | 39 | EXPECT_EQ(s1.size(), StrSize(s1)); 40 | 41 | hm.Install(&RealStrSize, FakeStrSize); 42 | EXPECT_EQ(s2.size(), StrSize(s1)); 43 | } 44 | EXPECT_EQ(s1.size(), StrSize(s1)); 45 | } 46 | 47 | namespace { 48 | 49 | decltype(GetCurrentProcessId) *RealGetCurrentProcessId = GetCurrentProcessId; 50 | DWORD WINAPI FakeGetCurrentProcessId() { 51 | return 0x1234; 52 | } 53 | 54 | } 55 | 56 | TEST(HookManagerTest, APITest) { 57 | HookManager hm; 58 | DWORD pid = GetCurrentProcessId(); 59 | 60 | hm.Install(&RealGetCurrentProcessId, FakeGetCurrentProcessId); 61 | EXPECT_EQ(0x1234, GetCurrentProcessId()); 62 | 63 | hm.Remove(&RealGetCurrentProcessId); 64 | EXPECT_EQ(pid, GetCurrentProcessId()); 65 | } 66 | 67 | } // namespace tracer -------------------------------------------------------------------------------- /tracer_test/recorder_test.cpp: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "trace.hpp" 3 | #include "call_count_recorder.hpp" 4 | #include "arg_recorder.hpp" 5 | #include "ret_val_recorder.hpp" 6 | #include "call_stack_recorder.hpp" 7 | #include "mixin_tracer.hpp" 8 | 9 | namespace { 10 | 11 | int F1(int a) { 12 | return a * a; 13 | } 14 | 15 | void F2(int a) { 16 | if (a != 0) 17 | F2(a - 1); 18 | } 19 | 20 | int Fac(int n) { 21 | if (n == 0) 22 | return 1; 23 | return n * Fac(n - 1); 24 | } 25 | 26 | struct C { 27 | void Foo() {} 28 | }; 29 | 30 | } 31 | 32 | void RunFoo() { 33 | C c; 34 | c.Foo(); 35 | } 36 | 37 | TEST(RecorderTest, CallCountTest) { 38 | TRACER_TRACE(&F1) f1; 39 | auto f1c = tracer::RecordCallCount(f1); 40 | F1(10); 41 | EXPECT_EQ(true, f1c.HasBeenCalled()); 42 | F1(20); 43 | EXPECT_EQ(2, f1c.CallCount()); 44 | EXPECT_EQ(100, f1.RealFunc()(10)); 45 | EXPECT_EQ(2, f1c.CallCount()); 46 | } 47 | 48 | TEST(RecorderTest, ArgRecorderTest) { 49 | TRACER_TRACE(&F2) f2; 50 | auto f2a = tracer::RecordArgs(f2); 51 | int a = 5; 52 | F2(a); 53 | for (int i = a; i >= 0; i--) 54 | EXPECT_EQ(5 - i, f2a.Arg<0>(i)); 55 | } 56 | 57 | TEST(RecorderTest, RetValRecorderTest) { 58 | TRACER_TRACE(&Fac) fac; 59 | auto facr = tracer::RecordRetVal(fac); 60 | Fac(3); 61 | int result[] = {1, 1, 2, 6}; 62 | for (int i = 0; i < 4; ++i) 63 | EXPECT_EQ(result[i], facr.RetVal(i)); 64 | } 65 | 66 | TEST(RecorderTest, CallStackRecorderTest) { 67 | TRACER_TRACE(&C::Foo) foo; 68 | auto fc = tracer::RecordCallStack(foo); 69 | 70 | RunFoo(); 71 | for (auto itr : fc.GetCallStack(0).Entries()) 72 | ;//std::cout << itr.File() << " " << itr.Line() << " " << itr.FuncName() << std::endl; 73 | EXPECT_EQ(true, fc.GetCallStack(0).IsCalledBy("RunFoo")); 74 | 75 | void(*f)(); 76 | f = [] () { RunFoo(); }; 77 | f(); 78 | EXPECT_EQ(true, fc.GetCallStack(1).IsCalledBy(f)); 79 | } 80 | 81 | TEST(RecorderTest, MixinTest) { 82 | TRACER_TRACE_WITH( 83 | &C::Foo, (tracer::CallCountRecorder)(tracer::CallStackRecorder)) foo; 84 | EXPECT_EQ(false, foo.HasBeenCalled()); 85 | 86 | RunFoo(); 87 | EXPECT_EQ(1, foo.CallCount()); 88 | EXPECT_EQ(true, foo.GetCallStack(0).IsCalledBy(RunFoo)); 89 | } -------------------------------------------------------------------------------- /tracer_test/src/gtest-printers.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | // Google Test - The Google C++ Testing Framework 33 | // 34 | // This file implements a universal value printer that can print a 35 | // value of any type T: 36 | // 37 | // void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); 38 | // 39 | // It uses the << operator when possible, and prints the bytes in the 40 | // object otherwise. A user can override its behavior for a class 41 | // type Foo by defining either operator<<(::std::ostream&, const Foo&) 42 | // or void PrintTo(const Foo&, ::std::ostream*) in the namespace that 43 | // defines Foo. 44 | 45 | #include "gtest/gtest-printers.h" 46 | #include 47 | #include 48 | #include // NOLINT 49 | #include 50 | #include "gtest/internal/gtest-port.h" 51 | 52 | namespace testing { 53 | 54 | namespace { 55 | 56 | using ::std::ostream; 57 | 58 | #if GTEST_OS_WINDOWS_MOBILE // Windows CE does not define _snprintf_s. 59 | # define snprintf _snprintf 60 | #elif _MSC_VER >= 1400 // VC 8.0 and later deprecate snprintf and _snprintf. 61 | # define snprintf _snprintf_s 62 | #elif _MSC_VER 63 | # define snprintf _snprintf 64 | #endif // GTEST_OS_WINDOWS_MOBILE 65 | 66 | // Prints a segment of bytes in the given object. 67 | void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, 68 | size_t count, ostream* os) { 69 | char text[5] = ""; 70 | for (size_t i = 0; i != count; i++) { 71 | const size_t j = start + i; 72 | if (i != 0) { 73 | // Organizes the bytes into groups of 2 for easy parsing by 74 | // human. 75 | if ((j % 2) == 0) 76 | *os << ' '; 77 | else 78 | *os << '-'; 79 | } 80 | snprintf(text, sizeof(text), "%02X", obj_bytes[j]); 81 | *os << text; 82 | } 83 | } 84 | 85 | // Prints the bytes in the given value to the given ostream. 86 | void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, 87 | ostream* os) { 88 | // Tells the user how big the object is. 89 | *os << count << "-byte object <"; 90 | 91 | const size_t kThreshold = 132; 92 | const size_t kChunkSize = 64; 93 | // If the object size is bigger than kThreshold, we'll have to omit 94 | // some details by printing only the first and the last kChunkSize 95 | // bytes. 96 | // TODO(wan): let the user control the threshold using a flag. 97 | if (count < kThreshold) { 98 | PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); 99 | } else { 100 | PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); 101 | *os << " ... "; 102 | // Rounds up to 2-byte boundary. 103 | const size_t resume_pos = (count - kChunkSize + 1)/2*2; 104 | PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); 105 | } 106 | *os << ">"; 107 | } 108 | 109 | } // namespace 110 | 111 | namespace internal2 { 112 | 113 | // Delegates to PrintBytesInObjectToImpl() to print the bytes in the 114 | // given object. The delegation simplifies the implementation, which 115 | // uses the << operator and thus is easier done outside of the 116 | // ::testing::internal namespace, which contains a << operator that 117 | // sometimes conflicts with the one in STL. 118 | void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, 119 | ostream* os) { 120 | PrintBytesInObjectToImpl(obj_bytes, count, os); 121 | } 122 | 123 | } // namespace internal2 124 | 125 | namespace internal { 126 | 127 | // Depending on the value of a char (or wchar_t), we print it in one 128 | // of three formats: 129 | // - as is if it's a printable ASCII (e.g. 'a', '2', ' '), 130 | // - as a hexidecimal escape sequence (e.g. '\x7F'), or 131 | // - as a special escape sequence (e.g. '\r', '\n'). 132 | enum CharFormat { 133 | kAsIs, 134 | kHexEscape, 135 | kSpecialEscape 136 | }; 137 | 138 | // Returns true if c is a printable ASCII character. We test the 139 | // value of c directly instead of calling isprint(), which is buggy on 140 | // Windows Mobile. 141 | inline bool IsPrintableAscii(wchar_t c) { 142 | return 0x20 <= c && c <= 0x7E; 143 | } 144 | 145 | // Prints a wide or narrow char c as a character literal without the 146 | // quotes, escaping it when necessary; returns how c was formatted. 147 | // The template argument UnsignedChar is the unsigned version of Char, 148 | // which is the type of c. 149 | template 150 | static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { 151 | switch (static_cast(c)) { 152 | case L'\0': 153 | *os << "\\0"; 154 | break; 155 | case L'\'': 156 | *os << "\\'"; 157 | break; 158 | case L'\\': 159 | *os << "\\\\"; 160 | break; 161 | case L'\a': 162 | *os << "\\a"; 163 | break; 164 | case L'\b': 165 | *os << "\\b"; 166 | break; 167 | case L'\f': 168 | *os << "\\f"; 169 | break; 170 | case L'\n': 171 | *os << "\\n"; 172 | break; 173 | case L'\r': 174 | *os << "\\r"; 175 | break; 176 | case L'\t': 177 | *os << "\\t"; 178 | break; 179 | case L'\v': 180 | *os << "\\v"; 181 | break; 182 | default: 183 | if (IsPrintableAscii(c)) { 184 | *os << static_cast(c); 185 | return kAsIs; 186 | } else { 187 | *os << String::Format("\\x%X", static_cast(c)); 188 | return kHexEscape; 189 | } 190 | } 191 | return kSpecialEscape; 192 | } 193 | 194 | // Prints a char c as if it's part of a string literal, escaping it when 195 | // necessary; returns how c was formatted. 196 | static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) { 197 | switch (c) { 198 | case L'\'': 199 | *os << "'"; 200 | return kAsIs; 201 | case L'"': 202 | *os << "\\\""; 203 | return kSpecialEscape; 204 | default: 205 | return PrintAsCharLiteralTo(c, os); 206 | } 207 | } 208 | 209 | // Prints a char c as if it's part of a string literal, escaping it when 210 | // necessary; returns how c was formatted. 211 | static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) { 212 | return PrintAsWideStringLiteralTo(static_cast(c), os); 213 | } 214 | 215 | // Prints a wide or narrow character c and its code. '\0' is printed 216 | // as "'\\0'", other unprintable characters are also properly escaped 217 | // using the standard C++ escape sequence. The template argument 218 | // UnsignedChar is the unsigned version of Char, which is the type of c. 219 | template 220 | void PrintCharAndCodeTo(Char c, ostream* os) { 221 | // First, print c as a literal in the most readable form we can find. 222 | *os << ((sizeof(c) > 1) ? "L'" : "'"); 223 | const CharFormat format = PrintAsCharLiteralTo(c, os); 224 | *os << "'"; 225 | 226 | // To aid user debugging, we also print c's code in decimal, unless 227 | // it's 0 (in which case c was printed as '\\0', making the code 228 | // obvious). 229 | if (c == 0) 230 | return; 231 | *os << " (" << String::Format("%d", c).c_str(); 232 | 233 | // For more convenience, we print c's code again in hexidecimal, 234 | // unless c was already printed in the form '\x##' or the code is in 235 | // [1, 9]. 236 | if (format == kHexEscape || (1 <= c && c <= 9)) { 237 | // Do nothing. 238 | } else { 239 | *os << String::Format(", 0x%X", 240 | static_cast(c)).c_str(); 241 | } 242 | *os << ")"; 243 | } 244 | 245 | void PrintTo(unsigned char c, ::std::ostream* os) { 246 | PrintCharAndCodeTo(c, os); 247 | } 248 | void PrintTo(signed char c, ::std::ostream* os) { 249 | PrintCharAndCodeTo(c, os); 250 | } 251 | 252 | // Prints a wchar_t as a symbol if it is printable or as its internal 253 | // code otherwise and also as its code. L'\0' is printed as "L'\\0'". 254 | void PrintTo(wchar_t wc, ostream* os) { 255 | PrintCharAndCodeTo(wc, os); 256 | } 257 | 258 | // Prints the given array of characters to the ostream. 259 | // The array starts at *begin, the length is len, it may include '\0' characters 260 | // and may not be null-terminated. 261 | static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) { 262 | *os << "\""; 263 | bool is_previous_hex = false; 264 | for (size_t index = 0; index < len; ++index) { 265 | const char cur = begin[index]; 266 | if (is_previous_hex && IsXDigit(cur)) { 267 | // Previous character is of '\x..' form and this character can be 268 | // interpreted as another hexadecimal digit in its number. Break string to 269 | // disambiguate. 270 | *os << "\" \""; 271 | } 272 | is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape; 273 | } 274 | *os << "\""; 275 | } 276 | 277 | // Prints a (const) char array of 'len' elements, starting at address 'begin'. 278 | void UniversalPrintArray(const char* begin, size_t len, ostream* os) { 279 | PrintCharsAsStringTo(begin, len, os); 280 | } 281 | 282 | // Prints the given array of wide characters to the ostream. 283 | // The array starts at *begin, the length is len, it may include L'\0' 284 | // characters and may not be null-terminated. 285 | static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len, 286 | ostream* os) { 287 | *os << "L\""; 288 | bool is_previous_hex = false; 289 | for (size_t index = 0; index < len; ++index) { 290 | const wchar_t cur = begin[index]; 291 | if (is_previous_hex && isascii(cur) && IsXDigit(static_cast(cur))) { 292 | // Previous character is of '\x..' form and this character can be 293 | // interpreted as another hexadecimal digit in its number. Break string to 294 | // disambiguate. 295 | *os << "\" L\""; 296 | } 297 | is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape; 298 | } 299 | *os << "\""; 300 | } 301 | 302 | // Prints the given C string to the ostream. 303 | void PrintTo(const char* s, ostream* os) { 304 | if (s == NULL) { 305 | *os << "NULL"; 306 | } else { 307 | *os << ImplicitCast_(s) << " pointing to "; 308 | PrintCharsAsStringTo(s, strlen(s), os); 309 | } 310 | } 311 | 312 | // MSVC compiler can be configured to define whar_t as a typedef 313 | // of unsigned short. Defining an overload for const wchar_t* in that case 314 | // would cause pointers to unsigned shorts be printed as wide strings, 315 | // possibly accessing more memory than intended and causing invalid 316 | // memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when 317 | // wchar_t is implemented as a native type. 318 | #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) 319 | // Prints the given wide C string to the ostream. 320 | void PrintTo(const wchar_t* s, ostream* os) { 321 | if (s == NULL) { 322 | *os << "NULL"; 323 | } else { 324 | *os << ImplicitCast_(s) << " pointing to "; 325 | PrintWideCharsAsStringTo(s, wcslen(s), os); 326 | } 327 | } 328 | #endif // wchar_t is native 329 | 330 | // Prints a ::string object. 331 | #if GTEST_HAS_GLOBAL_STRING 332 | void PrintStringTo(const ::string& s, ostream* os) { 333 | PrintCharsAsStringTo(s.data(), s.size(), os); 334 | } 335 | #endif // GTEST_HAS_GLOBAL_STRING 336 | 337 | void PrintStringTo(const ::std::string& s, ostream* os) { 338 | PrintCharsAsStringTo(s.data(), s.size(), os); 339 | } 340 | 341 | // Prints a ::wstring object. 342 | #if GTEST_HAS_GLOBAL_WSTRING 343 | void PrintWideStringTo(const ::wstring& s, ostream* os) { 344 | PrintWideCharsAsStringTo(s.data(), s.size(), os); 345 | } 346 | #endif // GTEST_HAS_GLOBAL_WSTRING 347 | 348 | #if GTEST_HAS_STD_WSTRING 349 | void PrintWideStringTo(const ::std::wstring& s, ostream* os) { 350 | PrintWideCharsAsStringTo(s.data(), s.size(), os); 351 | } 352 | #endif // GTEST_HAS_STD_WSTRING 353 | 354 | } // namespace internal 355 | 356 | } // namespace testing 357 | -------------------------------------------------------------------------------- /tracer_test/src/gtest-test-part.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // The Google C++ Testing Framework (Google Test) 33 | 34 | #include "gtest/gtest-test-part.h" 35 | 36 | // Indicates that this translation unit is part of Google Test's 37 | // implementation. It must come before gtest-internal-inl.h is 38 | // included, or there will be a compiler error. This trick is to 39 | // prevent a user from accidentally including gtest-internal-inl.h in 40 | // his code. 41 | #define GTEST_IMPLEMENTATION_ 1 42 | #include "src/gtest-internal-inl.h" 43 | #undef GTEST_IMPLEMENTATION_ 44 | 45 | namespace testing { 46 | 47 | using internal::GetUnitTestImpl; 48 | 49 | // Gets the summary of the failure message by omitting the stack trace 50 | // in it. 51 | internal::String TestPartResult::ExtractSummary(const char* message) { 52 | const char* const stack_trace = strstr(message, internal::kStackTraceMarker); 53 | return stack_trace == NULL ? internal::String(message) : 54 | internal::String(message, stack_trace - message); 55 | } 56 | 57 | // Prints a TestPartResult object. 58 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { 59 | return os 60 | << result.file_name() << ":" << result.line_number() << ": " 61 | << (result.type() == TestPartResult::kSuccess ? "Success" : 62 | result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : 63 | "Non-fatal failure") << ":\n" 64 | << result.message() << std::endl; 65 | } 66 | 67 | // Appends a TestPartResult to the array. 68 | void TestPartResultArray::Append(const TestPartResult& result) { 69 | array_.push_back(result); 70 | } 71 | 72 | // Returns the TestPartResult at the given index (0-based). 73 | const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { 74 | if (index < 0 || index >= size()) { 75 | printf("\nInvalid index (%d) into TestPartResultArray.\n", index); 76 | internal::posix::Abort(); 77 | } 78 | 79 | return array_[index]; 80 | } 81 | 82 | // Returns the number of TestPartResult objects in the array. 83 | int TestPartResultArray::size() const { 84 | return static_cast(array_.size()); 85 | } 86 | 87 | namespace internal { 88 | 89 | HasNewFatalFailureHelper::HasNewFatalFailureHelper() 90 | : has_new_fatal_failure_(false), 91 | original_reporter_(GetUnitTestImpl()-> 92 | GetTestPartResultReporterForCurrentThread()) { 93 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); 94 | } 95 | 96 | HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { 97 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( 98 | original_reporter_); 99 | } 100 | 101 | void HasNewFatalFailureHelper::ReportTestPartResult( 102 | const TestPartResult& result) { 103 | if (result.fatally_failed()) 104 | has_new_fatal_failure_ = true; 105 | original_reporter_->ReportTestPartResult(result); 106 | } 107 | 108 | } // namespace internal 109 | 110 | } // namespace testing 111 | -------------------------------------------------------------------------------- /tracer_test/src/gtest-typed-test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | #include "gtest/gtest-typed-test.h" 33 | #include "gtest/gtest.h" 34 | 35 | namespace testing { 36 | namespace internal { 37 | 38 | #if GTEST_HAS_TYPED_TEST_P 39 | 40 | // Skips to the first non-space char in str. Returns an empty string if str 41 | // contains only whitespace characters. 42 | static const char* SkipSpaces(const char* str) { 43 | while (IsSpace(*str)) 44 | str++; 45 | return str; 46 | } 47 | 48 | // Verifies that registered_tests match the test names in 49 | // defined_test_names_; returns registered_tests if successful, or 50 | // aborts the program otherwise. 51 | const char* TypedTestCasePState::VerifyRegisteredTestNames( 52 | const char* file, int line, const char* registered_tests) { 53 | typedef ::std::set::const_iterator DefinedTestIter; 54 | registered_ = true; 55 | 56 | // Skip initial whitespace in registered_tests since some 57 | // preprocessors prefix stringizied literals with whitespace. 58 | registered_tests = SkipSpaces(registered_tests); 59 | 60 | Message errors; 61 | ::std::set tests; 62 | for (const char* names = registered_tests; names != NULL; 63 | names = SkipComma(names)) { 64 | const String name = GetPrefixUntilComma(names); 65 | if (tests.count(name) != 0) { 66 | errors << "Test " << name << " is listed more than once.\n"; 67 | continue; 68 | } 69 | 70 | bool found = false; 71 | for (DefinedTestIter it = defined_test_names_.begin(); 72 | it != defined_test_names_.end(); 73 | ++it) { 74 | if (name == *it) { 75 | found = true; 76 | break; 77 | } 78 | } 79 | 80 | if (found) { 81 | tests.insert(name); 82 | } else { 83 | errors << "No test named " << name 84 | << " can be found in this test case.\n"; 85 | } 86 | } 87 | 88 | for (DefinedTestIter it = defined_test_names_.begin(); 89 | it != defined_test_names_.end(); 90 | ++it) { 91 | if (tests.count(*it) == 0) { 92 | errors << "You forgot to list test " << *it << ".\n"; 93 | } 94 | } 95 | 96 | const String& errors_str = errors.GetString(); 97 | if (errors_str != "") { 98 | fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), 99 | errors_str.c_str()); 100 | fflush(stderr); 101 | posix::Abort(); 102 | } 103 | 104 | return registered_tests; 105 | } 106 | 107 | #endif // GTEST_HAS_TYPED_TEST_P 108 | 109 | } // namespace internal 110 | } // namespace testing 111 | -------------------------------------------------------------------------------- /tracer_test/src/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | 34 | GTEST_API_ int main(int argc, char **argv) { 35 | std::cout << "Running main() from gtest_main.cc\n"; 36 | 37 | testing::InitGoogleTest(&argc, argv); 38 | auto ret = RUN_ALL_TESTS(); 39 | system("pause"); 40 | return ret; 41 | } 42 | -------------------------------------------------------------------------------- /tracer_test/trace_test.cpp: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "trace.hpp" 3 | 4 | namespace { 5 | 6 | int F1(int a) { 7 | return a * a; 8 | } 9 | 10 | int F2(int a) { 11 | return a; 12 | } 13 | 14 | int F2(int a, int b) { 15 | return a + b; 16 | } 17 | 18 | class C { 19 | std::string str_; 20 | public: 21 | C(const std::string &str) : 22 | str_(str) 23 | {} 24 | std::string Exchange(const std::string &str) { 25 | std::string ret(std::move(str_)); 26 | str_ = str; 27 | return ret; 28 | } 29 | }; 30 | 31 | } 32 | 33 | TEST(TraceTest, NormalFuncTest) { 34 | TRACER_TRACE(&F1) f1; 35 | f1.Before().connect([] (bool&, int &a) { 36 | EXPECT_EQ(10, a); 37 | }); 38 | auto real = f1.RealFunc(); 39 | f1.After().connect([real] (bool, int &ret, int&) { 40 | EXPECT_EQ(100, ret); 41 | ret = real(ret); 42 | }); 43 | EXPECT_EQ(10000, F1(10)); 44 | } 45 | 46 | TEST(TraceTest, MemberFuncTest) { 47 | TRACER_TRACE(&C::Exchange) exchange; 48 | C a("ObjA"), b("ObjB"); 49 | auto conn = exchange.Before().connect([&a, &b] (bool&, C *&self, const std::string &str) { 50 | EXPECT_EQ("something else", str); 51 | EXPECT_EQ(&a, self); 52 | self = &b; 53 | }); 54 | EXPECT_EQ("ObjB", a.Exchange("something else")); 55 | conn.disconnect(); 56 | EXPECT_EQ("something else", b.Exchange("")); 57 | } 58 | 59 | TEST(TraceTest, OverloadedFuncTest) { 60 | TRACER_TRACE(static_cast(&F2)) f2; 61 | f2.Before().connect([](bool&, int &a) { 62 | a = 0; 63 | }); 64 | EXPECT_EQ(0, F2(10)); 65 | EXPECT_EQ(10, F2(5, 5)); 66 | } -------------------------------------------------------------------------------- /tracer_test/tracer_test.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {233597F6-A348-4844-B3F4-904D0099CA44} 15 | tracer_test 16 | 17 | 18 | 19 | Application 20 | true 21 | v120 22 | MultiByte 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | D:\dx9\Lib;$(LibraryPath) 43 | 44 | 45 | 46 | Level3 47 | Disabled 48 | D:\dx9\Include;../google;../tracer;D:\boost\boost-trunk;%(AdditionalIncludeDirectories) 49 | _VARIADIC_MAX=10;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 50 | 4348 51 | 52 | 53 | true 54 | 55 | 56 | 57 | 58 | Level3 59 | MaxSpeed 60 | true 61 | true 62 | 63 | 64 | true 65 | true 66 | true 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | false 76 | 77 | 78 | 79 | 80 | 81 | 82 | {da952c05-1e1c-4cde-a35a-c7cb6b171b2b} 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /tracer_test/tracer_test.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 源文件 29 | 30 | 31 | 源文件 32 | 33 | 34 | 源文件 35 | 36 | 37 | 源文件 38 | 39 | 40 | --------------------------------------------------------------------------------