1 module it.c.compile.preprocessor; 2 3 4 import it; 5 6 7 @("simple macro") 8 @safe unittest { 9 shouldCompile( 10 C( 11 ` 12 #define FOO 5 13 ` 14 ), 15 D( 16 q{ 17 int[FOO] foos; 18 static assert(foos.length == 5, "Wrong length for foos"); 19 } 20 ) 21 ); 22 } 23 24 @("define macro, undefine, then define again") 25 @safe unittest { 26 shouldCompile( 27 C( 28 ` 29 #define FOO foo 30 #undef FOO 31 #define FOO bar 32 int FOO(int i); 33 ` 34 ), 35 D( 36 q{ 37 int i = bar(2); 38 } 39 ) 40 ); 41 } 42 43 44 @("include guards") 45 @safe unittest { 46 with(immutable IncludeSandbox()) { 47 writeFile("hdr.h", 48 `#ifndef HAHA 49 # define HAHA 50 int inc(int); 51 #endif`); 52 writeFile("foo.dpp", 53 `#include "hdr.h" 54 import bar; 55 int func(int i) { return inc(i) * 2; }`); 56 writeFile("bar.dpp", 57 `#include "hdr.h"; 58 int func(int i) { return inc(i) * 3; }`); 59 60 runPreprocessOnly("foo.dpp"); 61 runPreprocessOnly("bar.dpp"); 62 shouldCompile("foo.d"); 63 } 64 } 65 66 67 @("octal.whitespace") 68 @safe unittest { 69 shouldCompile( 70 C( 71 ` 72 #define FOO 00 73 ` 74 ), 75 D( 76 q{ 77 } 78 ) 79 ); 80 81 } 82 83 84 @("elaborate") 85 @safe unittest { 86 shouldCompile( 87 C( 88 ` 89 struct Foo {}; 90 #define STRUCT_HEAD \ 91 int count; \ 92 struct Foo *foo; 93 ` 94 ), 95 D( 96 q{ 97 static struct Derived { 98 STRUCT_HEAD 99 } 100 101 auto d = Derived(); 102 d.count = 42; 103 d.foo = null; 104 } 105 ) 106 ); 107 } 108 109 110 version(Posix) // FIXME 111 @("multiline") 112 @safe unittest { 113 shouldCompile( 114 C( 115 ` 116 // WARNING: don't attempt to tidy up the formatting here or the 117 // test is actually changed 118 #define void_to_int_ptr(x) ( \ 119 (int *) x \ 120 ) 121 ` 122 ), 123 D( 124 q{ 125 import std.stdio: writeln; 126 int a = 7; 127 void *p = &a; 128 auto intPtr = void_to_int_ptr(p); 129 } 130 ) 131 ); 132 } 133 134 @("func") 135 @safe unittest { 136 with(immutable IncludeSandbox()) { 137 writeFile("hdr.h", 138 `#define FOO(x) ((x) * 2) 139 #define BAR(x, y) ((x) + (y)) 140 #define BAZ(prefix, ...) text(prefix, __VA_ARGS__) 141 #define STR(x) #x 142 #define ARGH(x) STR(I like spaces x) 143 #define NOARGS() ((short) 42)`); 144 145 writeFile("foo.dpp", 146 [`#include "hdr.h"`, 147 `import std.conv : text;`]); 148 writeFile("bar.d", 149 q{ 150 import foo; 151 static assert(FOO(2) == 4); 152 static assert(FOO(3) == 6); 153 static assert(BAR(2, 3) == 5); 154 static assert(BAR(3, 4) == 7); 155 static assert(BAZ("prefix_", 42, "foo") == "prefix_42foo"); 156 static assert(BAZ("prefix_", 42, "foo", "bar") == "prefix_42foobar"); 157 static assert(NOARGS() == 42); 158 }); 159 160 runPreprocessOnly("--function-macros", "foo.dpp"); 161 shouldCompile("foo.d"); 162 shouldCompile("bar.d"); 163 } 164 } 165 166 @("cast.param") 167 @safe unittest { 168 shouldCompile( 169 C( 170 ` 171 #define MEMBER_SIZE(T, member) sizeof(((T*)0)-> member) 172 struct Struct { int i; }; 173 ` 174 ), 175 D( 176 q{ 177 static assert(MEMBER_SIZE(Struct, i) == 4); 178 } 179 ), 180 ); 181 } 182 183 @("cast.uchar") 184 @safe unittest { 185 shouldCompile( 186 C( 187 ` 188 #define CHAR_MASK(c) ((unsigned char)((c) & 0xff)) 189 ` 190 ), 191 D( 192 q{ 193 static assert(CHAR_MASK(0xab) == 0xab); 194 static assert(CHAR_MASK(0xf1) == 0xf1); 195 static assert(CHAR_MASK(0x1f) == 0x1f); 196 static assert(CHAR_MASK(0xff) == 0xff); 197 } 198 ), 199 ); 200 } 201 202 @("dowhile") 203 @safe unittest { 204 shouldCompile( 205 C( 206 ` 207 #define Py_BUILD_ASSERT(cond) do { \ 208 (void)Py_BUILD_ASSERT_EXPR(cond); \ 209 } while(0) 210 ` 211 ), 212 D( 213 q{ 214 } 215 ), 216 ["--function-macros"], 217 ); 218 219 } 220 221 @("vartype") 222 @safe unittest { 223 shouldCompile( 224 C( 225 ` 226 #define DOC_VAR(name) static const char name[] 227 ` 228 ), 229 D( 230 q{ 231 } 232 ), 233 ["--function-macros"], 234 ); 235 }