From 18c452a9587e654ad10ccd838f41626640cbb5b5 Mon Sep 17 00:00:00 2001 From: flapenguin Date: Thu, 15 Oct 2015 20:31:34 +0300 Subject: [PATCH] Fix line endings --- .gitignore | 67 +++---- .travis.yml | 4 +- LICENSE | 40 ++-- Makefile | 24 +-- README.md | 102 +++++------ include/pp_mage.h | 186 +++++++++---------- tests/containerof_test.c | 30 +-- tests/preprocessor_tests/boolean_logic.test | 40 ++-- tests/preprocessor_tests/conditionals.test | 22 +-- tests/preprocessor_tests/functionals.test | 18 +- tests/run_preprocessor_tests.sh | 192 ++++++++++---------- 11 files changed, 364 insertions(+), 361 deletions(-) diff --git a/.gitignore b/.gitignore index b483a7d..2188521 100644 --- a/.gitignore +++ b/.gitignore @@ -1,32 +1,35 @@ -# Object files -*.o -*.ko -*.obj -*.elf - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Debug files -*.dSYM/ \ No newline at end of file +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ + +# Sublime Text +*.sublime-* \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index fc0de41..7d7f6f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,3 @@ -language: c -compiler: [clang, gcc] +language: c +compiler: [clang, gcc] script: "make tests" \ No newline at end of file diff --git a/LICENSE b/LICENSE index ec31c77..b82230e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -The MIT License (MIT) - -Copyright (c) 2015 Andrey Roenko - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +The MIT License (MIT) + +Copyright (c) 2015 Andrey Roenko + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/Makefile b/Makefile index c4c9496..e8bb541 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ -export CC - -.PHONY: tests - -all: tests - -tests: - bash ./tests/run_preprocessor_tests.sh || (exit 1) - mkdir -p tests/build - - gcc tests/containerof_test.c -Iinclude -o tests/build/containerof_test - tests/build/containerof_test || (exit 1) +export CC + +.PHONY: tests + +all: tests + +tests: + bash ./tests/run_preprocessor_tests.sh || (exit 1) + mkdir -p tests/build + + gcc tests/containerof_test.c -Iinclude -o tests/build/containerof_test + tests/build/containerof_test || (exit 1) diff --git a/README.md b/README.md index 664638f..31c1a74 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,51 @@ -# PP_MAGE - preprocessor magic for your sources - -[![Build Status](https://travis-ci.org/flapenguin/pp_mage.svg)](https://travis-ci.org/flapenguin/pp_mage) - -## Overview -This **header-only** library for C and C++ provides number of usefull macros you can use to simplify your sources. - -This is collection of good usefull macros you probably want to have. - -## Building -No building is required, just add include directory to include path of your compiler. - -You can use `make` or `make tests` to run tests. - -## Documentation - -### Booleans -`PP_TRUE`, `PP_FALSE` - constants. - -`PP_NOT`, `PP_AND`, `PP_OR`, `PP_XOR` - logic functions. - -### Conditions -`PP_IF(Condition, Then)` - expands to `Then` if `Condition` is true, expands to empty otherwise. - -`PP_IFNOT(Condition, Then)` - expands to `Then` if `Condition` is false, expands to empty otherwise. - -`PP_IF_ELSE(Condition, Then, Else)` - expands to `Then` if `Condition` is true, expands to `Else` otherwise. - -### Functionals -`PP_NARG` and `PP_MAP` are limited by 16 arguments in current version. - -`PP_APPLY(Macro, arg1, arg2, ...)` - expands to `Macro(arg1, arg2, ...)`. - -`PP_NARG(arg1, ..., argN)` - expands to number `N`. - -`PP_MAP(Macro, arg1, arg2 ...)` - expands to `Macro(arg1) Macro(arg2) ...`. - -### Utilities - -`PP_CONCAT(Foo, Bar)` - classical indirection concatenation macro. - -`PP_CONTAINER_OF(Ptr, ParentType, Member)` - gets `ParentType*` by pointer `Ptr` to its `Member`. - -### Blocks -Next macros are usefull for reducing braces and do-whiles in huge macros. - -`PP_STMT_START` - expands to `do {`. - -`PP_STMT_END` - expands to `} while(0)`. - -`PP_STMT(...)` - expands to `do { ... } while(0)`. +# PP_MAGE - preprocessor magic for your sources + +[![Build Status](https://travis-ci.org/flapenguin/pp_mage.svg)](https://travis-ci.org/flapenguin/pp_mage) + +## Overview +This **header-only** library for C and C++ provides number of usefull macros you can use to simplify your sources. + +This is collection of good usefull macros you probably want to have. + +## Building +No building is required, just add include directory to include path of your compiler. + +You can use `make` or `make tests` to run tests. + +## Documentation + +### Booleans +`PP_TRUE`, `PP_FALSE` - constants. + +`PP_NOT`, `PP_AND`, `PP_OR`, `PP_XOR` - logic functions. + +### Conditions +`PP_IF(Condition, Then)` - expands to `Then` if `Condition` is true, expands to empty otherwise. + +`PP_IFNOT(Condition, Then)` - expands to `Then` if `Condition` is false, expands to empty otherwise. + +`PP_IF_ELSE(Condition, Then, Else)` - expands to `Then` if `Condition` is true, expands to `Else` otherwise. + +### Functionals +`PP_NARG` and `PP_MAP` are limited by 16 arguments in current version. + +`PP_APPLY(Macro, arg1, arg2, ...)` - expands to `Macro(arg1, arg2, ...)`. + +`PP_NARG(arg1, ..., argN)` - expands to number `N`. + +`PP_MAP(Macro, arg1, arg2 ...)` - expands to `Macro(arg1) Macro(arg2) ...`. + +### Utilities + +`PP_CONCAT(Foo, Bar)` - classical indirection concatenation macro. + +`PP_CONTAINER_OF(Ptr, ParentType, Member)` - gets `ParentType*` by pointer `Ptr` to its `Member`. + +### Blocks +Next macros are usefull for reducing braces and do-whiles in huge macros. + +`PP_STMT_START` - expands to `do {`. + +`PP_STMT_END` - expands to `} while(0)`. + +`PP_STMT(...)` - expands to `do { ... } while(0)`. diff --git a/include/pp_mage.h b/include/pp_mage.h index b3f389f..5a2164e 100644 --- a/include/pp_mage.h +++ b/include/pp_mage.h @@ -1,94 +1,94 @@ -#ifndef _PP_MAGE_ -#define _PP_MAGE_ - -#include - -// Boolean logic -#define PP_TRUE _PP_TRUE -#define PP_FALSE _PP_FALSE - -#define PP_NOT(X) PP_CONCAT(_PP_NOT, X) -#define PP_AND(X, Y) PP_IF_ELSE(X, Y, PP_FALSE) -#define PP_OR(X, Y) PP_IF_ELSE(X, PP_TRUE, Y) -#define PP_XOR(X, Y) PP_IF_ELSE(X, PP_NOT(Y), Y) - -// Conditionals -#define PP_IF(Condition, Then) PP_APPLY(PP_CONCAT(_PP_IF, Condition), Then) -#define PP_IF_NOT(Condition, Then) PP_IF(PP_NOT(Condition), Then) -#define PP_IF_ELSE(Condition, Then, Else) PP_IF(Condition, Then) PP_IF_NOT(Condition, Else) - -// Apply macro -#define PP_APPLY(Fn, ...) _PP_EXPAND( Fn(__VA_ARGS__)) -#define PP_ID(x) x - -// Apply macro for each arg -#define PP_MAP(Fn, ...) PP_APPLY(PP_CONCAT(_PP_MAP_, PP_NARG(__VA_ARGS__)), Fn, __VA_ARGS__) - -// Wrap statement -#define PP_STMT_START do { -#define PP_STMT_END } while(0) -#define PP_STMT(...) PP_STMT_START __VA_ARGS__; PP_STMT_END - -// General identifier concat -#define PP_CONCAT(a, b) _PP_CONCAT(a, b) - -// Get number of arguments -#define PP_NARG(...) _PP_EXPAND(_xPP_NARG_IMPL(dummy,##__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) - -// Collections -#define PP_CONTAINER_OF(Ptr, Type, Member) ( (Type*)((char*)(Ptr) - (char*)offsetof(Type, Member)) ) - -// ... Implementation details ... -#define _PP_NOT_PP_TRUE PP_FALSE -#define _PP_NOT_PP_FALSE PP_TRUE - -#define _PP_IF_PP_TRUE(X) X -#define _PP_IF_PP_FALSE(X) - -#define _PP_EXPAND(x) x -#define _PP_CONCAT(a, b) a ## b - -#define _xPP_NARG_IMPL(dummy,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) N - -#define _PP_MAP_1(Fn, _1)\ - Fn(_1 ) -#define _PP_MAP_2(Fn, _1, _2)\ - Fn(_1 ) Fn(_2 ) -#define _PP_MAP_3(Fn, _1, _2, _3)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) -#define _PP_MAP_4(Fn, _1, _2, _3, _4)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) -#define _PP_MAP_5(Fn, _1, _2, _3, _4, _5)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) -#define _PP_MAP_6(Fn, _1, _2, _3, _4, _5, _6)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) -#define _PP_MAP_7(Fn, _1, _2, _3, _4, _5, _6, _7)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) -#define _PP_MAP_8(Fn, _1, _2, _3, _4, _5, _6, _7, _8)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) -#define _PP_MAP_9(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ - Fn(_9 ) -#define _PP_MAP_10(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ - Fn(_9 ) Fn(_10) -#define _PP_MAP_11(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ - Fn(_9 ) Fn(_10) Fn(_11) -#define _PP_MAP_12(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ - Fn(_9 ) Fn(_10) Fn(_11) Fn(_12) -#define _PP_MAP_13(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ - Fn(_9 ) Fn(_10) Fn(_11) Fn(_12) Fn(_13) -#define _PP_MAP_14(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ - Fn(_9 ) Fn(_10) Fn(_11) Fn(_12) Fn(_13) Fn(_14) -#define _PP_MAP_15(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ - Fn(_9 ) Fn(_10) Fn(_11) Fn(_12) Fn(_13) Fn(_14) Fn(_15) -#define _PP_MAP_16(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16)\ - Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ - Fn(_9 ) Fn(_10) Fn(_11) Fn(_12) Fn(_13) Fn(_14) Fn(_15) Fn(_16) - +#ifndef _PP_MAGE_ +#define _PP_MAGE_ + +#include + +// Boolean logic +#define PP_TRUE _PP_TRUE +#define PP_FALSE _PP_FALSE + +#define PP_NOT(X) PP_CONCAT(_PP_NOT, X) +#define PP_AND(X, Y) PP_IF_ELSE(X, Y, PP_FALSE) +#define PP_OR(X, Y) PP_IF_ELSE(X, PP_TRUE, Y) +#define PP_XOR(X, Y) PP_IF_ELSE(X, PP_NOT(Y), Y) + +// Conditionals +#define PP_IF(Condition, Then) PP_APPLY(PP_CONCAT(_PP_IF, Condition), Then) +#define PP_IF_NOT(Condition, Then) PP_IF(PP_NOT(Condition), Then) +#define PP_IF_ELSE(Condition, Then, Else) PP_IF(Condition, Then) PP_IF_NOT(Condition, Else) + +// Apply macro +#define PP_APPLY(Fn, ...) _PP_EXPAND( Fn(__VA_ARGS__)) +#define PP_ID(x) x + +// Apply macro for each arg +#define PP_MAP(Fn, ...) PP_APPLY(PP_CONCAT(_PP_MAP_, PP_NARG(__VA_ARGS__)), Fn, __VA_ARGS__) + +// Wrap statement +#define PP_STMT_START do { +#define PP_STMT_END } while(0) +#define PP_STMT(...) PP_STMT_START __VA_ARGS__; PP_STMT_END + +// General identifier concat +#define PP_CONCAT(a, b) _PP_CONCAT(a, b) + +// Get number of arguments +#define PP_NARG(...) _PP_EXPAND(_xPP_NARG_IMPL(dummy,##__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) + +// Collections +#define PP_CONTAINER_OF(Ptr, Type, Member) ( (Type*)((char*)(Ptr) - (char*)offsetof(Type, Member)) ) + +// ... Implementation details ... +#define _PP_NOT_PP_TRUE PP_FALSE +#define _PP_NOT_PP_FALSE PP_TRUE + +#define _PP_IF_PP_TRUE(X) X +#define _PP_IF_PP_FALSE(X) + +#define _PP_EXPAND(x) x +#define _PP_CONCAT(a, b) a ## b + +#define _xPP_NARG_IMPL(dummy,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) N + +#define _PP_MAP_1(Fn, _1)\ + Fn(_1 ) +#define _PP_MAP_2(Fn, _1, _2)\ + Fn(_1 ) Fn(_2 ) +#define _PP_MAP_3(Fn, _1, _2, _3)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) +#define _PP_MAP_4(Fn, _1, _2, _3, _4)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) +#define _PP_MAP_5(Fn, _1, _2, _3, _4, _5)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) +#define _PP_MAP_6(Fn, _1, _2, _3, _4, _5, _6)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) +#define _PP_MAP_7(Fn, _1, _2, _3, _4, _5, _6, _7)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) +#define _PP_MAP_8(Fn, _1, _2, _3, _4, _5, _6, _7, _8)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) +#define _PP_MAP_9(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ + Fn(_9 ) +#define _PP_MAP_10(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ + Fn(_9 ) Fn(_10) +#define _PP_MAP_11(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ + Fn(_9 ) Fn(_10) Fn(_11) +#define _PP_MAP_12(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ + Fn(_9 ) Fn(_10) Fn(_11) Fn(_12) +#define _PP_MAP_13(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ + Fn(_9 ) Fn(_10) Fn(_11) Fn(_12) Fn(_13) +#define _PP_MAP_14(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ + Fn(_9 ) Fn(_10) Fn(_11) Fn(_12) Fn(_13) Fn(_14) +#define _PP_MAP_15(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ + Fn(_9 ) Fn(_10) Fn(_11) Fn(_12) Fn(_13) Fn(_14) Fn(_15) +#define _PP_MAP_16(Fn, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16)\ + Fn(_1 ) Fn(_2 ) Fn(_3 ) Fn(_4 ) Fn(_5 ) Fn(_6 ) Fn(_7 ) Fn(_8 ) \ + Fn(_9 ) Fn(_10) Fn(_11) Fn(_12) Fn(_13) Fn(_14) Fn(_15) Fn(_16) + #endif \ No newline at end of file diff --git a/tests/containerof_test.c b/tests/containerof_test.c index a3c2003..400ea6b 100644 --- a/tests/containerof_test.c +++ b/tests/containerof_test.c @@ -1,16 +1,16 @@ -#include -#include - -typedef struct foo_t { - int bar; - float baz; -} foo_t; - -int main() { - foo_t foo; - int* pbar = &foo.bar; - float* pbaz = &foo.baz; - - assert(PP_CONTAINER_OF(pbar, struct foo_t, bar) == &foo); - assert(PP_CONTAINER_OF(pbaz, foo_t, baz) == &foo); +#include +#include + +typedef struct foo_t { + int bar; + float baz; +} foo_t; + +int main() { + foo_t foo; + int* pbar = &foo.bar; + float* pbaz = &foo.baz; + + assert(PP_CONTAINER_OF(pbar, struct foo_t, bar) == &foo); + assert(PP_CONTAINER_OF(pbaz, foo_t, baz) == &foo); } \ No newline at end of file diff --git a/tests/preprocessor_tests/boolean_logic.test b/tests/preprocessor_tests/boolean_logic.test index 01b5ad5..67ac662 100644 --- a/tests/preprocessor_tests/boolean_logic.test +++ b/tests/preprocessor_tests/boolean_logic.test @@ -1,21 +1,21 @@ -[Not] -PP_NOT(PP_TRUE) == PP_FALSE -PP_NOT(PP_FALSE) == PP_TRUE - -[And] -PP_AND(PP_TRUE, PP_TRUE) == PP_TRUE -PP_AND(PP_TRUE, PP_FALSE) == PP_FALSE -PP_AND(PP_FALSE, PP_TRUE) == PP_FALSE -PP_AND(PP_FALSE, PP_FALSE) == PP_FALSE - -[Or] -PP_OR(PP_TRUE, PP_TRUE) == PP_TRUE -PP_OR(PP_TRUE, PP_FALSE) == PP_TRUE -PP_OR(PP_FALSE, PP_TRUE) == PP_TRUE -PP_OR(PP_FALSE, PP_FALSE) == PP_FALSE - -[Xor] -PP_XOR(PP_TRUE, PP_TRUE) == PP_FALSE -PP_XOR(PP_TRUE, PP_FALSE) == PP_TRUE -PP_XOR(PP_FALSE, PP_TRUE) == PP_TRUE +[Not] +PP_NOT(PP_TRUE) == PP_FALSE +PP_NOT(PP_FALSE) == PP_TRUE + +[And] +PP_AND(PP_TRUE, PP_TRUE) == PP_TRUE +PP_AND(PP_TRUE, PP_FALSE) == PP_FALSE +PP_AND(PP_FALSE, PP_TRUE) == PP_FALSE +PP_AND(PP_FALSE, PP_FALSE) == PP_FALSE + +[Or] +PP_OR(PP_TRUE, PP_TRUE) == PP_TRUE +PP_OR(PP_TRUE, PP_FALSE) == PP_TRUE +PP_OR(PP_FALSE, PP_TRUE) == PP_TRUE +PP_OR(PP_FALSE, PP_FALSE) == PP_FALSE + +[Xor] +PP_XOR(PP_TRUE, PP_TRUE) == PP_FALSE +PP_XOR(PP_TRUE, PP_FALSE) == PP_TRUE +PP_XOR(PP_FALSE, PP_TRUE) == PP_TRUE PP_XOR(PP_FALSE, PP_FALSE) == PP_FALSE \ No newline at end of file diff --git a/tests/preprocessor_tests/conditionals.test b/tests/preprocessor_tests/conditionals.test index d3e9b14..2550021 100644 --- a/tests/preprocessor_tests/conditionals.test +++ b/tests/preprocessor_tests/conditionals.test @@ -1,11 +1,11 @@ -[If] -PP_IF(PP_TRUE, then) == then -PP_IF(PP_FALSE, then) == - -[Not] -PP_IF_NOT(PP_TRUE, then) == -PP_IF_NOT(PP_FALSE, then) == then - -[If else] -PP_IF_ELSE(PP_TRUE, then, else) == then -PP_IF_ELSE(PP_FALSE, then, else) == else +[If] +PP_IF(PP_TRUE, then) == then +PP_IF(PP_FALSE, then) == + +[Not] +PP_IF_NOT(PP_TRUE, then) == +PP_IF_NOT(PP_FALSE, then) == then + +[If else] +PP_IF_ELSE(PP_TRUE, then, else) == then +PP_IF_ELSE(PP_FALSE, then, else) == else diff --git a/tests/preprocessor_tests/functionals.test b/tests/preprocessor_tests/functionals.test index 83b45ad..6de9a87 100644 --- a/tests/preprocessor_tests/functionals.test +++ b/tests/preprocessor_tests/functionals.test @@ -1,10 +1,10 @@ -#define ADD_BAR(T) T ## bar - -[Functional] -PP_CONCAT(foo, bar) == foobar -PP_ID(foo) == foo -PP_APPLY(ADD_BAR, foo) == foobar -PP_APPLY(PP_CONCAT, foo, bar) == foobar -PP_MAP(ADD_BAR, foo, baz, quux, baz) == foobar bazbar quuxbar bazbar -PP_NARG() == 0 +#define ADD_BAR(T) T ## bar + +[Functional] +PP_CONCAT(foo, bar) == foobar +PP_ID(foo) == foo +PP_APPLY(ADD_BAR, foo) == foobar +PP_APPLY(PP_CONCAT, foo, bar) == foobar +PP_MAP(ADD_BAR, foo, baz, quux, baz) == foobar bazbar quuxbar bazbar +PP_NARG() == 0 PP_NARG(1, 2, 3, 4) == 4 \ No newline at end of file diff --git a/tests/run_preprocessor_tests.sh b/tests/run_preprocessor_tests.sh index 5d8e5a7..5caa171 100644 --- a/tests/run_preprocessor_tests.sh +++ b/tests/run_preprocessor_tests.sh @@ -1,97 +1,97 @@ -#!/bin/bash - -MSYS="" -shopt -s nocasematch -if [[ "$(uname -o)" == "msys" ]]; then - MSYS=1 -fi -shopt -u nocasematch - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -if [[ $MSYS ]]; then - DIR=$(echo $DIR | sed 's_^\([a-zA-Z]\):_/\1_') -fi - -INC_DIR="${DIR}/../include" - -GREEN='\033[1;32m' -RED='\033[1;31m' -PURPLE='\033[0;35m' -NC='\033[0m' - -pattern=$1 -if [[ -z $pattern ]]; then - pattern="*.test" -fi -pattern="${DIR}/preprocessor_tests/${pattern}" - - -function echo_src { - echo "#include " - echo -n "$1" -} - -function trim_lines { - sed -e's/#.*$//' -e's/^[ \t]*//' -e'/^$/d' -} - -function run_test { - local src="$1" - - src=$(echo "$src" | awk ' - BEGIN { FS="[ \t]*==[ \t]*"; OFS=" @@@ "; } - NF == 1 && $1 ~ /^\[/ { print "\"" $1 "\""; next; } - NF == 1 { print $1; next; } - NF == 2 { print "\"" $1 "\"", $1, $2 } - ') - - local result=$(echo_src "$src" | $CC -E -I $INC_DIR - | trim_lines) - - echo "$result" | awk -v GREEN=$GREEN -v RED=$RED -v NC=$NC ' - function unstr(x) { gsub(/^"|"$/, "", x); return x; } - function stats() { - if (group) { - if (failed > 0) { - print "Succeeded: " succeed ". Failed: " failed "."; - } - print ""; - total_failed += failed; - succeed = 0; - failed = 0; - } - } - - BEGIN { - FS="[ \t]*@@@[ \t]*"; - succeed = 0; - failed = 0; - group = 0; - total_failed = 0; - } - $1 ~ /^"\[/ { stats(); group = unstr($1); print GREEN group NC; next; } - $2 == $3 && group { print unstr($1), GREEN "succeed" NC; succeed++; } - $2 != $3 && group { print unstr($1), RED "failed" NC, $2 " != " $3; failed++; } - END { stats(); exit(total_failed); } - ' - - return $? -} - -total_failed=0 -for test_name in $pattern; do - printf "${PURPLE}TEST SUITE${NC} ${test_name##*/}\n" - - run_test "$(cat $test_name)" - - total_failed=$((total_failed + $?)) -done - -if [[ $total_failed == 0 ]]; then - echo "SUCCEED" - exit 0 -fi - -if [[ $total_failed != 0 ]]; then - echo "FAILED ${total_failed} TESTS" - exit 1 +#!/bin/bash + +MSYS="" +shopt -s nocasematch +if [[ "$(uname -o)" == "msys" ]]; then + MSYS=1 +fi +shopt -u nocasematch + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +if [[ $MSYS ]]; then + DIR=$(echo $DIR | sed 's_^\([a-zA-Z]\):_/\1_') +fi + +INC_DIR="${DIR}/../include" + +GREEN='\033[1;32m' +RED='\033[1;31m' +PURPLE='\033[0;35m' +NC='\033[0m' + +pattern=$1 +if [[ -z $pattern ]]; then + pattern="*.test" +fi +pattern="${DIR}/preprocessor_tests/${pattern}" + + +function echo_src { + echo "#include " + echo -n "$1" +} + +function trim_lines { + sed -e's/#.*$//' -e's/^[ \t]*//' -e'/^$/d' +} + +function run_test { + local src="$1" + + src=$(echo "$src" | awk ' + BEGIN { FS="[ \t]*==[ \t]*"; OFS=" @@@ "; } + NF == 1 && $1 ~ /^\[/ { print "\"" $1 "\""; next; } + NF == 1 { print $1; next; } + NF == 2 { print "\"" $1 "\"", $1, $2 } + ') + + local result=$(echo_src "$src" | $CC -E -I $INC_DIR - | trim_lines) + + echo "$result" | awk -v GREEN=$GREEN -v RED=$RED -v NC=$NC ' + function unstr(x) { gsub(/^"|"$/, "", x); return x; } + function stats() { + if (group) { + if (failed > 0) { + print "Succeeded: " succeed ". Failed: " failed "."; + } + print ""; + total_failed += failed; + succeed = 0; + failed = 0; + } + } + + BEGIN { + FS="[ \t]*@@@[ \t]*"; + succeed = 0; + failed = 0; + group = 0; + total_failed = 0; + } + $1 ~ /^"\[/ { stats(); group = unstr($1); print GREEN group NC; next; } + $2 == $3 && group { print unstr($1), GREEN "succeed" NC; succeed++; } + $2 != $3 && group { print unstr($1), RED "failed" NC, $2 " != " $3; failed++; } + END { stats(); exit(total_failed); } + ' + + return $? +} + +total_failed=0 +for test_name in $pattern; do + printf "${PURPLE}TEST SUITE${NC} ${test_name##*/}\n" + + run_test "$(cat $test_name)" + + total_failed=$((total_failed + $?)) +done + +if [[ $total_failed == 0 ]]; then + echo "SUCCEED" + exit 0 +fi + +if [[ $total_failed != 0 ]]; then + echo "FAILED ${total_failed} TESTS" + exit 1 fi \ No newline at end of file