├── LICENSE ├── Makefile ├── README.md ├── charclass.d ├── cmdline.d ├── constexpr.d ├── context.d ├── defines_clang3_2.d ├── defines_clang3_4.d ├── defines_clangdev.d ├── defines_clangxx3_2.d ├── defines_clangxx3_4.d ├── defines_clangxxdev.d ├── defines_gcc4_7_1.d ├── defines_gcc4_8_1.d ├── defines_gxx4_7_1.d ├── defines_gxx4_8_1.d ├── directive.d ├── expanded.d ├── file.d ├── id.d ├── lexer.d ├── loc.d ├── macros.d ├── main.d ├── number.d ├── outdeps.d ├── ranges.d ├── run_tests.sh ├── skip.d ├── sources.d ├── stringlit.d ├── tests ├── comment_after_include.c ├── dollar_macro.S ├── import.c ├── include │ ├── foo.h │ ├── guard.h │ ├── include_doesnotexist.h │ ├── include_nonexisting.h │ └── once.h ├── include_guard.c ├── include_nonexisting.c ├── include_thrice.c ├── pragma_once.c └── space_after_include.cpp ├── textbuf.d ├── util.d └── warpdrive.d /LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Figure out which compiler to use (prefer gdc, fall back to dmd). 2 | ifeq (,$(DC)) 3 | DC:=$(shell which gdc 2>/dev/null) 4 | ifeq (,$(DC)) 5 | DC:=dmd 6 | endif 7 | endif 8 | 9 | ifeq (gdc,$(notdir $(DC))) 10 | DFLAGS=-c -O4 -frelease -fno-bounds-check -fbuiltin 11 | OFSYNTAX=-o 12 | else 13 | ifeq (dmd,$(notdir $(DC))) 14 | DFLAGS=-c -O -inline -release 15 | OFSYNTAX=-of 16 | else 17 | $(error Unsupported compiler: $(DC)) 18 | endif 19 | endif 20 | 21 | CC=cc 22 | CXX=c++ 23 | CFLAGS= 24 | CXXFLAGS= 25 | WARPDRIVE=warpdrive 26 | GENERATED_DEFINES=generated_defines.d 27 | 28 | # warp sources 29 | SRCS=cmdline.d constexpr.d context.d directive.d expanded.d file.d \ 30 | id.d lexer.d loc.d macros.d main.d number.d outdeps.d ranges.d skip.d \ 31 | sources.d stringlit.d textbuf.d charclass.d 32 | 33 | # Binaries generated 34 | BIN:=warp $(WARPDRIVE) 35 | 36 | # Rules 37 | 38 | all : $(BIN) 39 | 40 | clean : 41 | rm -rf $(BIN) $(addsuffix .o, $(BIN)) $(GENERATED_DEFINES) 42 | 43 | warp.o : $(SRCS) 44 | $(DC) $(DFLAGS) $(OFSYNTAX)$@ $(SRCS) 45 | 46 | warp : warp.o 47 | gcc -m64 -Bthird-party2/binutils/2.21.1/centos6-native/da39a3e/bin/gold -Bthird-party2/glibc/2.17/gcc-4.8.1-glibc-2.17-fb/99df8fc/lib -L/home/aalexandre/bin/../d/phobos/generated/linux/release/default -l:libphobos2.a -lpthread -lm -lrt -o $@ $^ 48 | 49 | $(WARPDRIVE) : warpdrive.d $(GENERATED_DEFINES) 50 | $(DC) $(DFLAGS) $(OFSYNTAX)$@ $^ 51 | 52 | $(GENERATED_DEFINES) : 53 | ./builtin_defines.sh '$(CC) $(CFLAGS)' '$(CXX) $(CXXFLAGS)' >$@.tmp 54 | mv $@.tmp $@ 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | - - - 2 | 3 | **_This project is not actively maintained. Proceed at your own risk!_** 4 | 5 | - - - 6 | 7 | `warp`: Facebook's C and C++ Preprocessor 8 | ----------------------------------------- 9 | 10 | `warp` is an open-source preprocessor for the C and C++ programming 11 | languages. We use it at Facebook as a faster replacement of `cpp`, 12 | GNU's preprocessor. 13 | 14 | The companion program `warpdrive` drives `warp` in conjunction with 15 | the predefined macros of a few of today's crop of compilers (gcc 16 | 4.7.1, gcc 4.8.1, clang 3.2, and clang 3.4). 17 | 18 | Currently `warp`'s build has only been tested with gcc 4.7.1 and gcc 4.8.1 on CentOS 6. More 19 | officially supported platforms to follow. 20 | 21 | Dependencies 22 | ------------ 23 | 24 | You need a D compiler installation, which can be downloaded from 25 | [here](http://dlang.org/download.html). For maximum speed we recommend 26 | using the gdc compiler. 27 | 28 | Building and using warp 29 | ----------------------- 30 | 31 | `warp` by itself is agnostic of the C or C++ dialect implemented by a 32 | particular compiler. It is common for compilers to implicitly define a 33 | number of macros that affect the precompilation process. To help with 34 | that, warp is accompanied by `warpdrive`, a simple driver program that 35 | invokes `warp` with the appropriate `#define`s for a few popular 36 | compilers. 37 | 38 | To build warp, use the simple Makefile that's part of the distribution: 39 | 40 | make -j 41 | 42 | This will produce `warp` (the core program) and also the drivers 43 | `warpdrive_gcc4_7_1`, `warpdrive_gcc4_8_1`, `warpdrive_clang3_2`, 44 | `warpdrive_clang3_4`, and `warpdrive_clangdev`, each packaged for the 45 | respective compiler and version. 46 | 47 | To invoke warp, simply use 48 | 49 | warpdrive filename 50 | 51 | In all likelihood you'll need to use `-I` for adding paths to included 52 | library files (warpdrive doesn't bake those in.) 53 | -------------------------------------------------------------------------------- /charclass.d: -------------------------------------------------------------------------------- 1 | /** 2 | * C preprocessor 3 | * Copyright: 2013-2014 by Digital Mars 4 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 5 | * Authors: Walter Bright 6 | */ 7 | 8 | module charclass; 9 | 10 | import std.ascii; 11 | 12 | import util; 13 | 14 | /***************************************** 15 | * Use an array lookup to determine what kind of character it is; 16 | * the array should remain hot in the cache. 17 | */ 18 | 19 | enum CClass 20 | { 21 | identifierStart = 1, 22 | identifierChar = 2, 23 | separator = 4, 24 | multiTok = 8, 25 | } 26 | 27 | immutable ubyte[256] cclassTable; 28 | 29 | /****************************************** 30 | * Characters that make up the start of an identifier. 31 | */ 32 | 33 | static this() 34 | { 35 | for (uint c = 0; c < 0x100; ++c) 36 | { 37 | if (isAlpha(c) || c == '_') 38 | cclassTable[c] |= CClass.identifierStart; 39 | 40 | if (isAlphaNum(c) || c == '_') 41 | cclassTable[c] |= CClass.identifierChar; 42 | 43 | if (c == ' ' || 44 | c == '\t' || 45 | c == '\n' || 46 | c == '\v' || 47 | c == '\f' || 48 | c == '\r' || 49 | c == '$' || 50 | c == '(' || 51 | c == ')' || 52 | c == ',' || 53 | c == ';' || 54 | c == '?' || 55 | c == '[' || 56 | c == ']' || 57 | c == '{' || 58 | c == '}' || 59 | c == '~') 60 | { 61 | cclassTable[c] |= CClass.separator; 62 | } 63 | 64 | if (c == '*' || 65 | c == '+' || 66 | c == '-' || 67 | c == '.' || 68 | c == '/' || 69 | c == ':' || 70 | c == '<' || 71 | c == '=' || 72 | c == '>' || 73 | c == '^' || 74 | c == '|') 75 | { 76 | cclassTable[c] |= CClass.multiTok; 77 | } 78 | } 79 | } 80 | 81 | bool isIdentifierStart(uchar c) pure nothrow 82 | { 83 | return cclassTable[c] & CClass.identifierStart; 84 | } 85 | 86 | unittest 87 | { 88 | /* Exhaustively test every char 89 | */ 90 | for (uint u = 0; u < 0x100; ++u) 91 | { 92 | assert(isIdentifierStart(cast(uchar)u) == (isAlpha(u) || u == '_')); 93 | } 94 | } 95 | 96 | 97 | /******************************************* 98 | * Characters that make up the tail of an identifier. 99 | */ 100 | 101 | ubyte isIdentifierChar(uchar c) pure nothrow 102 | { 103 | return cclassTable[c] & CClass.identifierChar; 104 | } 105 | 106 | unittest 107 | { 108 | /* Exhaustively test every char 109 | */ 110 | for (uint u = 0; u < 0x100; ++u) 111 | { 112 | assert((isIdentifierChar(cast(uchar)u) != 0) == (isAlphaNum(u) || u == '_')); 113 | } 114 | } 115 | 116 | 117 | /***************************************** 118 | * 'Break' characters unambiguously separate tokens 119 | */ 120 | 121 | ubyte isBreak(uchar c) pure nothrow 122 | { 123 | return cclassTable[c] & CClass.separator; 124 | } 125 | 126 | 127 | /************************************* 128 | * 'MultiTok' characters can be part of multiple character tokens 129 | */ 130 | 131 | ubyte isMultiTok(uchar c) pure nothrow 132 | { 133 | return cclassTable[c] & CClass.multiTok; 134 | } 135 | 136 | /* 137 | * Local Variables: 138 | * mode: d 139 | * c-basic-offset: 4 140 | * End: 141 | */ 142 | -------------------------------------------------------------------------------- /cmdline.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | module cmdline; 10 | 11 | import util; 12 | 13 | import std.stdio; 14 | import std.range; 15 | import std.path; 16 | import std.array; 17 | import std.algorithm; 18 | 19 | import core.stdc.stdlib; 20 | 21 | /********************* 22 | * Initialized with the command line arguments. 23 | */ 24 | struct Params 25 | { 26 | string[] sourceFilenames; 27 | string[] outFilenames; 28 | string depFilename; 29 | string[] defines; 30 | string[] includes; 31 | string[] sysincludes; 32 | bool verbose; 33 | bool stdout; 34 | } 35 | 36 | 37 | /****************************************** 38 | * Parse the command line. 39 | * Input: 40 | * args arguments from command line 41 | * Returns: 42 | * Params filled in 43 | */ 44 | 45 | Params parseCommandLine(string[] args) 46 | { 47 | import std.getopt; 48 | 49 | if (args.length == 1) 50 | { 51 | writeln( 52 | "C Preprocessor 53 | Copyright (c) 2013 by Digital Mars 54 | http://boost.org/LICENSE_1_0.txt 55 | Options: 56 | filename... source file name(s) 57 | -D macro[=value] define macro 58 | --dep filename generate dependencies to output file 59 | -I path path to #include files 60 | --isystem path path to system #include files 61 | -o filename preprocessed output file 62 | --stdout output to stdout 63 | -v verbose 64 | "); 65 | exit(EXIT_SUCCESS); 66 | } 67 | 68 | Params p; 69 | 70 | getopt(args, 71 | std.getopt.config.passThrough, 72 | std.getopt.config.caseSensitive, 73 | "include|I", &p.includes, 74 | "define|D", &p.defines, 75 | "isystem", &p.sysincludes, 76 | "dep", &p.depFilename, 77 | "output|o", &p.outFilenames, 78 | "stdout", &p.stdout, 79 | "v", &p.verbose); 80 | 81 | // Fix up -Dname=value stuff. This will be superseded by 82 | // D-Programming-Language/phobos#1779, but won't hurt even then. 83 | for (size_t i = 1; i < args.length; ) 84 | { 85 | if (!args[i].startsWith("-D")) 86 | { 87 | ++i; 88 | continue; 89 | } 90 | p.defines ~= args[i][2 .. $]; 91 | args = args.remove(i); 92 | } 93 | 94 | assert(args.length >= 1); 95 | p.sourceFilenames = args[1 .. $]; 96 | 97 | if (p.outFilenames.length == 0) 98 | { 99 | /* Output file names are not supplied, so build them by 100 | * stripping any .c or .cpp extension and appending .i 101 | */ 102 | foreach (filename; p.sourceFilenames) 103 | { 104 | string outname, ext = ".ii"; 105 | if (extension(filename) == ".c") 106 | { 107 | outname = baseName(filename, ".c"); 108 | ext = ".i"; 109 | } 110 | else if ([".cpp", "cxx", ".hpp"].canFind(extension(filename))) 111 | outname = baseName(filename, ".cpp"); 112 | else 113 | outname = baseName(filename); 114 | p.outFilenames ~= outname ~ ext; 115 | } 116 | } 117 | 118 | /* Check for errors 119 | */ 120 | if (p.sourceFilenames.length == p.outFilenames.length) 121 | { 122 | // Look for duplicate file names 123 | auto s = chain(p.sourceFilenames, p.outFilenames, (&p.depFilename)[0..1]). 124 | array. 125 | sort!((a,b) => filenameCmp(a,b) < 0). 126 | findAdjacent!((a,b) => filenameCmp(a,b) == 0); 127 | if (!s.empty) 128 | { 129 | err_fatal("duplicate file names %s", s.front); 130 | } 131 | } 132 | else 133 | { 134 | err_fatal("%s source files, but %s output files", p.sourceFilenames.length, p.outFilenames.length); 135 | } 136 | return p; 137 | } 138 | 139 | unittest 140 | { 141 | auto p = parseCommandLine([ 142 | "dmpp", 143 | "foo.c", 144 | "-D", "macro=value", 145 | "--dep", "out.dep", 146 | "-I", "path1", 147 | "-I", "path2", 148 | "--isystem", "sys1", 149 | "--isystem", "sys2", 150 | "-o", "out.i"]); 151 | 152 | assert(p.sourceFilenames == ["foo.c"]); 153 | assert(p.defines == ["macro=value"]); 154 | assert(p.depFilename == "out.dep"); 155 | assert(p.includes == ["path1", "path2"]); 156 | assert(p.sysincludes == ["sys1", "sys2"]); 157 | assert(p.outFilenames == ["out.i"]); 158 | } 159 | 160 | /*********************************** 161 | * Construct the total search path from the regular include paths and the 162 | * system include paths. 163 | * Input: 164 | * includePaths regular include paths 165 | * sysIncludePaths system include paths 166 | * Output: 167 | * paths combined result 168 | * sysIndex paths[sysIndex] is where the system paths start 169 | */ 170 | 171 | void combineSearchPaths(const string[] includePaths, const string[] sysIncludePaths, 172 | out string[] paths, out size_t sysIndex) 173 | { 174 | /* Each element of the paths may contain multiple paths separated by 175 | * pathSeparator, so straighten that out 176 | */ 177 | auto incpaths = includePaths.map!(a => splitter(a, pathSeparator)).join; 178 | auto syspaths = sysIncludePaths.map!(a => splitter(a, pathSeparator)).join; 179 | 180 | /* Concatenate incpaths[] and syspaths[] into paths[] 181 | * but remove from incpaths[] any that are also in syspaths[] 182 | */ 183 | paths = "." ~ incpaths.filter!((a) => !syspaths.canFind(a)).array; 184 | sysIndex = paths.length; 185 | paths ~= syspaths; 186 | 187 | } 188 | 189 | unittest 190 | { 191 | string[] paths; 192 | size_t sysIndex; 193 | 194 | combineSearchPaths(["a" ~ pathSeparator ~ "b","c","d"], ["e","c","f"], paths, sysIndex); 195 | //writefln("paths [%s], sysIndex = %s", paths, sysIndex); 196 | assert(sysIndex == 4); 197 | assert(paths == [".","a","b","d","e","c","f"]); 198 | } 199 | 200 | /* 201 | * Local Variables: 202 | * mode: d 203 | * c-basic-offset: 4 204 | * End: 205 | */ 206 | -------------------------------------------------------------------------------- /constexpr.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | module constexpr; 10 | 11 | import std.stdio; 12 | 13 | import util; 14 | import lexer; 15 | import id; 16 | 17 | /***************************** 18 | * Evaluate constant expressions for a boolean result. 19 | */ 20 | 21 | bool constantExpression(Lexer)(ref Lexer r) 22 | { 23 | auto i = Comma(r); 24 | return i.value != 0; 25 | } 26 | 27 | private: 28 | 29 | PPnumber Primary(Lexer)(ref Lexer r) 30 | { 31 | 32 | // This line only works with 2.064 and later 33 | //enum bool isContext = __traits(compiles, r.src.expanded); 34 | 35 | // Use for 2.063 and later 36 | enum bool isContext = is(typeof(r.src.expanded)); 37 | 38 | switch (r.front) 39 | { 40 | case TOK.identifier: 41 | if (r.idbuf[] == "defined") 42 | { 43 | bool sawParen; 44 | 45 | if (isContext) 46 | { 47 | r.popFrontNoExpand(); 48 | if (r.front == TOK.lparen) 49 | { 50 | sawParen = true; 51 | r.popFrontNoExpand(); 52 | } 53 | if (r.front != TOK.identifier) 54 | { 55 | err_fatal("identifier expected after 'defined'"); 56 | } 57 | else 58 | { 59 | PPnumber i; 60 | auto m = Id.search(cast(ustring)r.idbuf[]); 61 | if (m && m.flags & Id.IDmacro) 62 | { 63 | //writefln("defined(%s)", cast(string)m.name); 64 | i.value = 1; 65 | } 66 | r.popFrontNoExpand(); 67 | if (sawParen) 68 | { 69 | if (r.front != TOK.rparen) 70 | err_fatal("')' expected"); 71 | r.popFrontNoExpand(); 72 | } 73 | return i; 74 | } 75 | } 76 | else 77 | { 78 | r.popFront(); 79 | if (r.front == TOK.lparen) 80 | { 81 | sawParen = true; 82 | r.popFront(); 83 | } 84 | if (r.front != TOK.identifier) 85 | { 86 | err_fatal("identifier expected after 'defined'"); 87 | } 88 | else 89 | { 90 | PPnumber i; 91 | r.popFront(); 92 | if (sawParen) 93 | { 94 | if (r.front != TOK.rparen) 95 | err_fatal("')' expected"); 96 | r.popFront(); 97 | } 98 | return i; 99 | } 100 | } 101 | 102 | } 103 | break; 104 | 105 | case TOK.integer: 106 | { 107 | auto i = r.number; 108 | r.popFront(); 109 | return i; 110 | } 111 | 112 | default: 113 | err_fatal("primary expression expected, not %s", r.front); 114 | break; 115 | } 116 | r.popFront(); 117 | PPnumber n; 118 | return n; // i.e. return signed 0 119 | } 120 | 121 | unittest 122 | { 123 | { 124 | auto s = cast(immutable(ubyte)[])(" 100u \n"); 125 | auto lexer = createLexer(s); 126 | assert(!lexer.empty); 127 | auto n = lexer.Primary(); 128 | assert(n.value == 100); 129 | assert(n.isunsigned == true); 130 | } 131 | { 132 | auto s = cast(immutable(ubyte)[])(" abc \n"); 133 | auto lexer = createLexer(s); 134 | assert(!lexer.empty); 135 | auto n = lexer.Primary(); 136 | assert(n.value == 0); 137 | assert(n.isunsigned == false); 138 | } 139 | } 140 | 141 | PPnumber Unary(Lexer)(ref Lexer r) 142 | { 143 | switch (r.front) 144 | { 145 | case TOK.plus: 146 | r.popFront(); 147 | return Unary(r); 148 | 149 | case TOK.minus: 150 | { 151 | r.popFront(); 152 | auto i = Unary(r); 153 | i.value = -i.value; 154 | return i; 155 | } 156 | 157 | case TOK.not: 158 | { 159 | r.popFront(); 160 | auto i = Unary(r); 161 | i.value = !i.value; 162 | i.isunsigned = false; 163 | return i; 164 | } 165 | 166 | case TOK.tilde: 167 | { 168 | r.popFront(); 169 | auto i = Unary(r); 170 | i.value = ~i.value; 171 | return i; 172 | } 173 | 174 | case TOK.lparen: 175 | { 176 | r.popFront(); 177 | auto i = Comma(r); 178 | if (r.front != TOK.rparen) 179 | err_fatal(") expected"); 180 | r.popFront(); 181 | return i; 182 | } 183 | 184 | default: 185 | return Primary(r); 186 | } 187 | } 188 | 189 | unittest 190 | { 191 | { 192 | auto s = cast(immutable(ubyte)[])(" +-100u \n"); 193 | auto lexer = createLexer(s); 194 | assert(!lexer.empty); 195 | auto n = lexer.Unary(); 196 | assert(n.value == -100); 197 | assert(n.isunsigned == true); 198 | } 199 | { 200 | auto s = cast(immutable(ubyte)[])(" !100u \n"); 201 | auto lexer = createLexer(s); 202 | assert(!lexer.empty); 203 | auto n = lexer.Unary(); 204 | assert(n.value == 0); 205 | assert(n.isunsigned == false); 206 | } 207 | { 208 | auto s = cast(immutable(ubyte)[])(" ~0x234 \n"); 209 | auto lexer = createLexer(s); 210 | assert(!lexer.empty); 211 | auto n = lexer.Unary(); 212 | assert(n.value == ~0x234); 213 | assert(n.isunsigned == false); 214 | } 215 | } 216 | 217 | PPnumber Mul(Lexer)(ref Lexer r) 218 | { 219 | auto i = Unary(r); 220 | while (1) 221 | { 222 | switch (r.front) 223 | { 224 | case TOK.mul: 225 | r.popFront(); 226 | auto i2 = Unary(r); 227 | i.value = i.value * i2.value; 228 | i.isunsigned |= i2.isunsigned; 229 | continue; 230 | 231 | case TOK.div: 232 | r.popFront(); 233 | auto i2 = Unary(r); 234 | if (i2.value) 235 | { 236 | i.isunsigned |= i2.isunsigned; 237 | if (i.isunsigned) 238 | i.value /= cast(ppuint_t)i2.value; 239 | else 240 | i.value /= i2.value; 241 | } 242 | else 243 | err_fatal("divide by zero"); 244 | continue; 245 | 246 | case TOK.mod: 247 | r.popFront(); 248 | auto i2 = Unary(r); 249 | if (i2.value) 250 | { 251 | i.isunsigned |= i2.isunsigned; 252 | if (i.isunsigned) 253 | i.value %= cast(ppuint_t)i2.value; 254 | else 255 | i.value %= i2.value; 256 | } 257 | else 258 | err_fatal("divide by zero"); 259 | continue; 260 | 261 | default: 262 | break; 263 | } 264 | break; 265 | } 266 | return i; 267 | } 268 | 269 | unittest 270 | { 271 | { 272 | auto s = cast(immutable(ubyte)[])(" 2*100*100u \n"); 273 | auto lexer = createLexer(s); 274 | assert(!lexer.empty); 275 | auto n = lexer.Mul(); 276 | assert(n.value == 20000); 277 | assert(n.isunsigned == true); 278 | } 279 | { 280 | auto s = cast(immutable(ubyte)[])(" 200/-10/3u \n"); 281 | auto lexer = createLexer(s); 282 | assert(!lexer.empty); 283 | auto n = lexer.Mul(); 284 | assert(n.value == 200L/-10L/3uL); 285 | assert(n.isunsigned == true); 286 | } 287 | { 288 | auto s = cast(immutable(ubyte)[])(" 200%-10%3u \n"); 289 | auto lexer = createLexer(s); 290 | assert(!lexer.empty); 291 | auto n = lexer.Mul(); 292 | assert(n.value == 200L%-10L%3uL); 293 | assert(n.isunsigned == true); 294 | } 295 | } 296 | 297 | PPnumber Add(Lexer)(ref Lexer r) 298 | { 299 | auto i = Mul(r); 300 | while (1) 301 | { 302 | switch (r.front) 303 | { 304 | case TOK.plus: 305 | r.popFront(); 306 | auto i2 = Mul(r); 307 | i.value = i.value + i2.value; 308 | i.isunsigned |= i2.isunsigned; 309 | continue; 310 | 311 | case TOK.minus: 312 | r.popFront(); 313 | auto i2 = Mul(r); 314 | i.value = i.value - i2.value; 315 | i.isunsigned |= i2.isunsigned; 316 | continue; 317 | 318 | default: 319 | break; 320 | } 321 | break; 322 | } 323 | return i; 324 | } 325 | 326 | unittest 327 | { 328 | { 329 | auto s = cast(immutable(ubyte)[])(" 200+-10+3u \n"); 330 | auto lexer = createLexer(s); 331 | assert(!lexer.empty); 332 | auto n = lexer.Add(); 333 | assert(n.value == 200L+-10L+3uL); 334 | assert(n.isunsigned == true); 335 | } 336 | { 337 | auto s = cast(immutable(ubyte)[])(" 200- -10-3u \n"); 338 | auto lexer = createLexer(s); 339 | assert(!lexer.empty); 340 | auto n = lexer.Add(); 341 | assert(n.value == 200L- -10L-3uL); 342 | assert(n.isunsigned == true); 343 | } 344 | } 345 | 346 | 347 | PPnumber Shift(Lexer)(ref Lexer r) 348 | { 349 | auto i = Add(r); 350 | while (1) 351 | { 352 | switch (r.front) 353 | { 354 | case TOK.shl: 355 | r.popFront(); 356 | auto i2 = Add(r); 357 | i.value = i.value << i2.value; 358 | continue; 359 | 360 | case TOK.shr: 361 | r.popFront(); 362 | auto i2 = Add(r); 363 | if (i.isunsigned) 364 | i.value = cast(ppuint_t)i.value >> i2.value; 365 | else 366 | i.value = i.value >> i2.value; 367 | continue; 368 | 369 | default: 370 | break; 371 | } 372 | break; 373 | } 374 | return i; 375 | } 376 | 377 | unittest 378 | { 379 | { 380 | auto s = cast(immutable(ubyte)[])(" 200<< 10<<3u \n"); 381 | auto lexer = createLexer(s); 382 | assert(!lexer.empty); 383 | auto n = lexer.Shift(); 384 | assert(n.value == 200L<< 10L<<3uL); 385 | assert(n.isunsigned == false); 386 | } 387 | { 388 | auto s = cast(immutable(ubyte)[])(" 200>>10u>>3 \n"); 389 | auto lexer = createLexer(s); 390 | assert(!lexer.empty); 391 | auto n = lexer.Shift(); 392 | assert(n.value == 200L>>10Lu>>3L); 393 | assert(n.isunsigned == false); 394 | } 395 | { 396 | auto s = cast(immutable(ubyte)[])(" 200u>>10 \n"); 397 | auto lexer = createLexer(s); 398 | assert(!lexer.empty); 399 | auto n = lexer.Shift(); 400 | assert(n.value == 200Lu>>10L); 401 | assert(n.isunsigned == true); 402 | } 403 | } 404 | 405 | 406 | 407 | PPnumber Cmp(Lexer)(ref Lexer r) 408 | { 409 | auto i = Shift(r); 410 | while (1) 411 | { 412 | switch (r.front) 413 | { 414 | case TOK.le: 415 | r.popFront(); 416 | auto i2 = Shift(r); 417 | if (i.isunsigned || i2.isunsigned) 418 | i.value = i.value <= cast(ppuint_t)i2.value; 419 | else 420 | i.value = i.value <= i2.value; 421 | i.isunsigned = false; 422 | continue; 423 | 424 | case TOK.lt: 425 | r.popFront(); 426 | auto i2 = Shift(r); 427 | if (i.isunsigned || i2.isunsigned) 428 | i.value = i.value < cast(ppuint_t)i2.value; 429 | else 430 | i.value = i.value < i2.value; 431 | i.isunsigned = false; 432 | continue; 433 | 434 | case TOK.ge: 435 | r.popFront(); 436 | auto i2 = Shift(r); 437 | if (i.isunsigned || i2.isunsigned) 438 | i.value = i.value >= cast(ppuint_t)i2.value; 439 | else 440 | i.value = i.value >= i2.value; 441 | i.isunsigned = false; 442 | continue; 443 | 444 | case TOK.gt: 445 | r.popFront(); 446 | auto i2 = Shift(r); 447 | if (i.isunsigned || i2.isunsigned) 448 | i.value = i.value > cast(ppuint_t)i2.value; 449 | else 450 | i.value = i.value > i2.value; 451 | i.isunsigned = false; 452 | continue; 453 | 454 | default: 455 | break; 456 | } 457 | break; 458 | } 459 | return i; 460 | } 461 | 462 | unittest 463 | { 464 | { 465 | auto s = cast(immutable(ubyte)[])(" 200<=3 \n"); 466 | auto lexer = createLexer(s); 467 | assert(!lexer.empty); 468 | auto n = lexer.Cmp(); 469 | assert(n.value == (200L<=3L)); 470 | assert(n.isunsigned == false); 471 | } 472 | { 473 | auto s = cast(immutable(ubyte)[])(" -200u<=3 \n"); 474 | auto lexer = createLexer(s); 475 | assert(!lexer.empty); 476 | auto n = lexer.Cmp(); 477 | assert(n.value == (-200uL<=3L)); 478 | assert(n.isunsigned == false); 479 | } 480 | { 481 | auto s = cast(immutable(ubyte)[])(" 200<3 \n"); 482 | auto lexer = createLexer(s); 483 | assert(!lexer.empty); 484 | auto n = lexer.Cmp(); 485 | assert(n.value == (200L<3L)); 486 | assert(n.isunsigned == false); 487 | } 488 | { 489 | auto s = cast(immutable(ubyte)[])(" -200u<3 \n"); 490 | auto lexer = createLexer(s); 491 | assert(!lexer.empty); 492 | auto n = lexer.Cmp(); 493 | assert(n.value == (-200uL<3L)); 494 | assert(n.isunsigned == false); 495 | } 496 | { 497 | auto s = cast(immutable(ubyte)[])(" 200>=3 \n"); 498 | auto lexer = createLexer(s); 499 | assert(!lexer.empty); 500 | auto n = lexer.Cmp(); 501 | assert(n.value == (200L>=3L)); 502 | assert(n.isunsigned == false); 503 | } 504 | { 505 | auto s = cast(immutable(ubyte)[])(" -200u>=3 \n"); 506 | auto lexer = createLexer(s); 507 | assert(!lexer.empty); 508 | auto n = lexer.Cmp(); 509 | assert(n.value == (-200uL>=3L)); 510 | assert(n.isunsigned == false); 511 | } 512 | { 513 | auto s = cast(immutable(ubyte)[])(" 200>3 \n"); 514 | auto lexer = createLexer(s); 515 | assert(!lexer.empty); 516 | auto n = lexer.Cmp(); 517 | assert(n.value == (200L>3L)); 518 | assert(n.isunsigned == false); 519 | } 520 | { 521 | auto s = cast(immutable(ubyte)[])(" -200u>3 \n"); 522 | auto lexer = createLexer(s); 523 | assert(!lexer.empty); 524 | auto n = lexer.Cmp(); 525 | assert(n.value == (-200uL>3L)); 526 | assert(n.isunsigned == false); 527 | } 528 | } 529 | 530 | PPnumber Equal(Lexer)(ref Lexer r) 531 | { 532 | auto i = Cmp(r); 533 | while (1) 534 | { 535 | switch (r.front) 536 | { 537 | case TOK.equal: 538 | r.popFront(); 539 | auto i2 = Cmp(r); 540 | i.value = i.value == i2.value; 541 | i.isunsigned = false; 542 | continue; 543 | 544 | case TOK.notequal: 545 | r.popFront(); 546 | auto i2 = Cmp(r); 547 | i.value = i.value != i2.value; 548 | i.isunsigned = false; 549 | continue; 550 | 551 | default: 552 | break; 553 | } 554 | break; 555 | } 556 | return i; 557 | } 558 | 559 | unittest 560 | { 561 | { 562 | auto s = cast(immutable(ubyte)[])(" 200==3 \n"); 563 | auto lexer = createLexer(s); 564 | assert(!lexer.empty); 565 | auto n = lexer.Equal(); 566 | assert(n.value == (200L==3L)); 567 | assert(n.isunsigned == false); 568 | } 569 | { 570 | auto s = cast(immutable(ubyte)[])(" -200u!=3 \n"); 571 | auto lexer = createLexer(s); 572 | assert(!lexer.empty); 573 | auto n = lexer.Equal(); 574 | assert(n.value == (-200uL!=3L)); 575 | assert(n.isunsigned == false); 576 | } 577 | } 578 | 579 | PPnumber And(Lexer)(ref Lexer r) 580 | { 581 | auto i = Equal(r); 582 | while (r.front == TOK.and) 583 | { 584 | r.popFront(); 585 | auto i2 = Equal(r); 586 | i.value &= i2.value; 587 | i.isunsigned |= i2.isunsigned; 588 | } 589 | return i; 590 | } 591 | 592 | unittest 593 | { 594 | { 595 | auto s = cast(immutable(ubyte)[])(" 200 & 3u \n"); 596 | auto lexer = createLexer(s); 597 | assert(!lexer.empty); 598 | auto n = lexer.And(); 599 | assert(n.value == (200L & 3uL)); 600 | assert(n.isunsigned == true); 601 | } 602 | } 603 | 604 | PPnumber Xor(Lexer)(ref Lexer r) 605 | { 606 | auto i = And(r); 607 | while (r.front == TOK.xor) 608 | { 609 | r.popFront(); 610 | auto i2 = And(r); 611 | i.value ^= i2.value; 612 | i.isunsigned |= i2.isunsigned; 613 | } 614 | return i; 615 | } 616 | 617 | unittest 618 | { 619 | { 620 | auto s = cast(immutable(ubyte)[])(" 200 ^ 3 \n"); 621 | auto lexer = createLexer(s); 622 | assert(!lexer.empty); 623 | auto n = lexer.Xor(); 624 | assert(n.value == (200L ^ 3L)); 625 | assert(n.isunsigned == false); 626 | } 627 | } 628 | 629 | 630 | PPnumber Or(Lexer)(ref Lexer r) 631 | { 632 | auto i = Xor(r); 633 | while (r.front == TOK.or) 634 | { 635 | r.popFront(); 636 | auto i2 = Xor(r); 637 | i.value |= i2.value; 638 | i.isunsigned |= i2.isunsigned; 639 | } 640 | return i; 641 | } 642 | 643 | unittest 644 | { 645 | { 646 | auto s = cast(immutable(ubyte)[])(" 200 | 3u | 8 \n"); 647 | auto lexer = createLexer(s); 648 | assert(!lexer.empty); 649 | auto n = lexer.Or(); 650 | assert(n.value == (200L | 3uL | 8L)); 651 | assert(n.isunsigned == true); 652 | } 653 | } 654 | 655 | 656 | PPnumber AndAnd(Lexer)(ref Lexer r) 657 | { 658 | auto i = Or(r); 659 | while (r.front == TOK.andand) 660 | { 661 | r.popFront(); 662 | auto i2 = Or(r); 663 | i.value = i.value && i2.value; 664 | i.isunsigned = false; 665 | } 666 | return i; 667 | } 668 | 669 | unittest 670 | { 671 | { 672 | auto s = cast(immutable(ubyte)[])(" 200 && 3u && 8 \n"); 673 | auto lexer = createLexer(s); 674 | assert(!lexer.empty); 675 | auto n = lexer.AndAnd(); 676 | assert(n.value == (200L && 3uL && 8L)); 677 | assert(n.isunsigned == false); 678 | } 679 | } 680 | 681 | 682 | PPnumber OrOr(Lexer)(ref Lexer r) 683 | { 684 | auto i = AndAnd(r); 685 | while (r.front == TOK.oror) 686 | { 687 | r.popFront(); 688 | auto i2 = AndAnd(r); 689 | i.value = i.value || i2.value; 690 | i.isunsigned = false; 691 | } 692 | return i; 693 | } 694 | 695 | unittest 696 | { 697 | { 698 | auto s = cast(immutable(ubyte)[])(" 200 || 3u || 8 \n"); 699 | auto lexer = createLexer(s); 700 | assert(!lexer.empty); 701 | auto n = lexer.OrOr(); 702 | assert(n.value == (200L || 3uL || 8L)); 703 | assert(n.isunsigned == false); 704 | } 705 | } 706 | 707 | 708 | PPnumber Cond(Lexer)(ref Lexer r) 709 | { 710 | auto i = OrOr(r); 711 | if (r.front == TOK.question) 712 | { 713 | r.popFront(); 714 | auto i1 = Comma(r); 715 | if (r.front != TOK.colon) 716 | err_fatal(": expected"); 717 | r.popFront(); 718 | auto i2 = Cond(r); 719 | i.value = i.value ? i1.value : i2.value; 720 | i.isunsigned = i1.isunsigned | i2.isunsigned; 721 | return i; 722 | } 723 | return i; 724 | } 725 | 726 | unittest 727 | { 728 | { 729 | auto s = cast(immutable(ubyte)[])(" 1 ? 2,3 : 4u \n"); 730 | auto lexer = createLexer(s); 731 | assert(!lexer.empty); 732 | auto n = lexer.Cond(); 733 | assert(n.value == (1L ? 2L,3L : 4Lu)); 734 | assert(n.isunsigned == true); 735 | } 736 | } 737 | 738 | 739 | 740 | PPnumber Comma(Lexer)(ref Lexer r) 741 | { 742 | auto i = Cond(r); 743 | while (r.front == TOK.comma) 744 | { 745 | r.popFront(); 746 | i = Cond(r); 747 | } 748 | return i; 749 | } 750 | 751 | 752 | unittest 753 | { 754 | { 755 | auto s = cast(immutable(ubyte)[])(" 1 + 3 - 4 \n"); 756 | auto lexer = createLexer(s); 757 | assert(!lexer.empty); 758 | auto n = lexer.constantExpression(); 759 | assert(n == !!(1L + 3L -4L)); 760 | } 761 | } 762 | 763 | 764 | 765 | 766 | /* 767 | * Local Variables: 768 | * mode: d 769 | * c-basic-offset: 4 770 | * End: 771 | */ 772 | -------------------------------------------------------------------------------- /context.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | module context; 10 | 11 | import core.stdc.stdio; 12 | import core.stdc.stdlib; 13 | import core.stdc.string; 14 | 15 | import std.algorithm; 16 | import std.array; 17 | import std.path; 18 | import std.range; 19 | import std.stdio; 20 | import std.traits; 21 | 22 | import cmdline; 23 | import directive; 24 | import expanded; 25 | import id; 26 | import lexer; 27 | import loc; 28 | import macros; 29 | import util; 30 | import outdeps; 31 | import textbuf; 32 | import sources; 33 | 34 | /********************************* 35 | * Keep the state of the preprocessor in this struct. 36 | * Input: 37 | * R output range for preprocessor output 38 | */ 39 | 40 | //debug=ContextStats; 41 | 42 | struct Context(R) 43 | { 44 | SourceStack stack; 45 | Expanded!R expanded; // for expanded (preprocessed) output 46 | 47 | const Params params; // command line parameters 48 | 49 | const string[] paths; // #include paths 50 | const size_t sysIndex; // paths[sysIndex] is start of system #includes 51 | 52 | private bool errors; // true if any errors occurred 53 | private __gshared uint counter; // for __COUNTER__ 54 | 55 | bool doDeps; // true if doing dependency file generation 56 | string[] deps; // dependency file contents 57 | 58 | private Source* psourceFile; 59 | 60 | debug (ContextStats) 61 | { 62 | int sourcei; 63 | int sourceimax; 64 | } 65 | 66 | // Used in the implementation of overrideIncludeTrace; 67 | LocList* overriddenIncludeTrace; 68 | 69 | // Used in the implementation of overrideLoc(). 70 | Loc overriddenLoc; 71 | 72 | Loc lastloc; 73 | bool uselastloc; 74 | 75 | __gshared Context* _ctx; // shameful use of global variable 76 | //Context* prev; // previous one in stack of these 77 | 78 | // Stack of #if/#else/#endif nesting 79 | ubyte[64] tmpbuf = void; 80 | Textbuf!(ubyte,"ifs") ifstack; 81 | 82 | 83 | /****** 84 | * Construct global context from the command line parameters 85 | */ 86 | this(ref const Params params) 87 | { 88 | this.params = params; 89 | this.doDeps = params.depFilename.length != 0; 90 | 91 | string[] pathsx; 92 | size_t sysIndexx; 93 | combineSearchPaths(params.includes, 94 | params.sysincludes, 95 | pathsx, 96 | sysIndexx); 97 | paths = pathsx; // workaround for Bugzilla 11743 98 | sysIndex = sysIndexx; // workaround for Bugzilla 11743 99 | ifstack = Textbuf!(ubyte,"ifs")(tmpbuf); 100 | ifstack.initialize(); 101 | expanded.initialize(&this); 102 | setContext(); 103 | } 104 | 105 | /************************************** 106 | * Returns a LocList representing the #include directives leading up 107 | * to the inclusion of the current source code. The first element of 108 | * the list corresponds to the most deeply nested include directive. 109 | * The return value of this function may be null, which represents 110 | * the empty list. 111 | */ 112 | LocList* includeTrace() 113 | { 114 | if (overriddenIncludeTrace != overriddenIncludeTrace.init) { 115 | return overriddenIncludeTrace; 116 | } 117 | auto csf = currentSourceFile(); 118 | if (csf) return csf.includeTrace; 119 | return null; 120 | } 121 | 122 | /************************************** 123 | * When called with a non-null value, causes includeTrace() to return 124 | * that value instead of its normal return value. 125 | */ 126 | void overrideIncludeTrace(LocList* trace) 127 | { 128 | overriddenIncludeTrace = trace; 129 | } 130 | 131 | /************************************** 132 | * When called with a value other than Loc.init, causes loc() to return 133 | * that value instead of its normal return value. 134 | */ 135 | void overrideLoc(Loc loc) 136 | { 137 | overriddenLoc = loc; 138 | } 139 | 140 | /************************************** 141 | * Create a new Context on a stack of them. 142 | */ 143 | Context* pushContext() 144 | { 145 | auto st = SourceStack.allocate(); 146 | auto root = st.psourceRoot; 147 | *st = stack; 148 | stack = stack.init; 149 | stack.psourceRoot = root; 150 | stack.prev = st; 151 | return &this; 152 | } 153 | 154 | Context* popContext() 155 | { 156 | auto root = stack.psourceRoot; 157 | auto p = stack.prev; 158 | stack = *stack.prev; 159 | p.psourceRoot = root; 160 | p.deallocate(); 161 | return &this; 162 | } 163 | 164 | /*************************** 165 | * Reset to use again. 166 | */ 167 | void reset() 168 | { 169 | Id.reset(); 170 | SrcFile.reset(); 171 | 172 | counter = 0; 173 | ifstack.initialize(); 174 | stack.xc = ' '; 175 | lastloc = lastloc.init; 176 | uselastloc = false; 177 | stack.psource = null; 178 | } 179 | 180 | static Context* getContext() 181 | { 182 | return _ctx; 183 | } 184 | 185 | void setContext() 186 | { 187 | _ctx = &this; 188 | } 189 | 190 | /********** 191 | * Create local context 192 | */ 193 | void localStart(SrcFile* sf, R* outrange) 194 | { 195 | // Define predefined macros 196 | Id.defineMacro(cast(ustring)"__BASE_FILE__", null, cast(ustring)sf.filename, Id.IDpredefined); 197 | Id.initPredefined(); 198 | foreach (def; params.defines) 199 | macrosDefine(cast(ustring)def); 200 | 201 | // Set up preprocessed output 202 | expanded.start(outrange); 203 | 204 | // Initialize source text 205 | pushFile(sf, Sys.none, -1, null); 206 | 207 | version (unittest) 208 | { 209 | // Don't make unittest results unnecessarily complicated 210 | } 211 | else 212 | { 213 | if (auto s = currentSourceFile()) 214 | { 215 | // Output a prolog the way gcc does (in particular 216 | // contains directory information that may be helping gdb 217 | // locate sources). 218 | import std.file, std.format; 219 | outrange.formattedWrite( 220 | //"# 1 \"%1$s\"\n" Written by pushFile 221 | "# 1 \"%2$s//\"\n" 222 | "# 1 \"\"\n" 223 | "# 1 \"%1$s\"\n", 224 | s.loc.srcFile.filename, getcwd); 225 | } 226 | } 227 | } 228 | 229 | void pushFile(SrcFile* sf, Sys system, int pathIndex, LocList* includeTrace) 230 | { 231 | //write("pushFile ", pathIndex); 232 | auto s = push(); 233 | s.includeTrace = includeTrace; 234 | psourceFile = s; 235 | s.addFile(sf, system, pathIndex); 236 | 237 | // insert a line directive for start-of-file 238 | // linemarker decrements lineNumber when writing, so set to 2 239 | Loc tmploc = s.loc; 240 | tmploc.lineNumber = 2; 241 | tmploc.linemarker(expanded.foutr); 242 | 243 | if (lastloc.srcFile) 244 | uselastloc = true; 245 | assert(s.ptext); 246 | } 247 | 248 | /********** 249 | * Preprocess a file 250 | */ 251 | void preprocess() 252 | { 253 | auto lexer = createLexer(&this); 254 | while (1) 255 | { 256 | // Either at start of a new line, or the end of the file 257 | assert(!lexer.empty); 258 | auto tok = lexer.front; 259 | if (tok == TOK.eol) 260 | lexer.popFront(); 261 | else if (tok == TOK.hash) 262 | { 263 | // A '#' starting off a line says preprocessing directive 264 | if (lexer.parseDirective()) 265 | { 266 | auto csf = currentSourceFile(); 267 | if (csf) 268 | { 269 | csf.seenTokens = true; 270 | } 271 | } 272 | } 273 | else if (tok == TOK.eof) 274 | break; 275 | else 276 | { 277 | auto csf = currentSourceFile(); 278 | if (csf) 279 | { 280 | csf.seenTokens = true; 281 | } 282 | 283 | do 284 | { 285 | lexer.popFront(); 286 | } while (lexer.front != TOK.eol); 287 | lexer.popFront(); 288 | } 289 | } 290 | } 291 | 292 | /********** 293 | * Finish local context 294 | */ 295 | void localFinish() 296 | { 297 | expanded.finish(); 298 | 299 | debug (ContextStats) 300 | { 301 | writefln("max Source depth = %d", sourceimax); 302 | } 303 | } 304 | 305 | /********** 306 | * Finish global context 307 | */ 308 | void globalFinish() 309 | { 310 | if (doDeps && !errors) 311 | { 312 | dependencyFileWrite(params.depFilename, deps); 313 | } 314 | } 315 | 316 | @property bool empty() 317 | { 318 | return stack.xc == stack.xc.init; 319 | } 320 | 321 | @property uchar front() 322 | { 323 | return stack.xc; 324 | } 325 | 326 | void popFront() 327 | { 328 | auto s = stack.psource; 329 | if (s.ptext.length) 330 | { 331 | auto c = s.ptext[0]; 332 | stack.xc = c; 333 | s.ptext = s.ptext[1 .. $]; 334 | expanded.put(c); 335 | } 336 | else 337 | popFront2(); 338 | } 339 | 340 | void popFront2() 341 | { 342 | while (1) 343 | { 344 | auto s = stack.psource; 345 | if (s.ptext.length == 0) 346 | { 347 | if (s.isFile && !s.input.empty) 348 | { 349 | s.readLine(); 350 | continue; 351 | } 352 | ++s.loc.lineNumber; 353 | s = pop(); 354 | if (s) 355 | continue; 356 | stack.xc = stack.xc.init; 357 | break; 358 | } 359 | else 360 | { 361 | stack.xc = s.ptext[0]; 362 | s.ptext = s.ptext[1 .. $]; 363 | } 364 | expanded.put(stack.xc); 365 | break; 366 | } 367 | } 368 | 369 | uchar[] lookAhead() 370 | { 371 | return stack.psource.ptext[]; 372 | } 373 | 374 | void popFrontN(size_t n) 375 | { 376 | auto s = stack.psource; 377 | s.ptext = s.ptext[n .. $]; 378 | } 379 | 380 | uchar[] restOfLine() 381 | { 382 | auto s = stack.psource; 383 | auto result = s.ptext[]; 384 | s.ptext = s.ptext[result.length .. result.length]; 385 | stack.xc = '\n'; 386 | return result; 387 | } 388 | 389 | void unget() 390 | { 391 | auto s = stack.psource; 392 | if (s) 393 | push(stack.xc); 394 | } 395 | 396 | void push(uchar c) 397 | { 398 | auto s = push(); 399 | s.smallString[0] = c; 400 | s.ptext = s.smallString[]; 401 | } 402 | 403 | void push(const(uchar)[] str) 404 | { 405 | if (str.length == 1) 406 | push(str[0]); 407 | else 408 | { 409 | auto s = push(); 410 | s.lineBuffer.initialize(); 411 | s.lineBuffer.put(str); 412 | s.ptext = s.lineBuffer[0 .. str.length]; 413 | } 414 | } 415 | 416 | Source* currentSourceFile() 417 | { 418 | return psourceFile; 419 | } 420 | 421 | Loc loc() 422 | { 423 | if (overriddenLoc != overriddenLoc.init) 424 | return overriddenLoc; 425 | auto csf = currentSourceFile(); 426 | if (csf) 427 | return csf.loc; 428 | if (lastloc.srcFile) 429 | return lastloc; 430 | Loc loc; 431 | return loc; 432 | } 433 | 434 | Source* push() 435 | { 436 | auto s = stack.psource; 437 | if (s) 438 | { 439 | s = s.next; 440 | if (!s) 441 | { 442 | // Ran out of space, allocate another chunk 443 | auto sources2 = new Source[16]; 444 | Source.initialize(sources2, stack.psource, &stack.psource.next); 445 | s = stack.psource.next; 446 | assert(s); 447 | } 448 | } 449 | else 450 | { 451 | if (!stack.psourceRoot) 452 | { 453 | auto sources2 = new Source[16]; 454 | Source.initialize(sources2, stack.psource, &stack.psource); 455 | stack.psourceRoot = sources2.ptr; 456 | } 457 | s = stack.psourceRoot; 458 | } 459 | s.isFile = false; 460 | s.isExpanded = false; 461 | s.seenTokens = false; 462 | stack.psource = s; 463 | 464 | debug (ContextStats) 465 | { 466 | ++sourcei; 467 | if (sourcei > sourceimax) 468 | sourceimax = sourcei; 469 | } 470 | 471 | return s; 472 | } 473 | 474 | Source* pop() 475 | { 476 | auto s = stack.psource; 477 | if (s.isFile) 478 | { 479 | // Back up and find previous file; null if none 480 | if (psourceFile == s) 481 | { 482 | for (auto ps = s; 1;) 483 | { 484 | ps = ps.prev; 485 | if (!ps || ps.isFile) 486 | { 487 | psourceFile = ps; 488 | break; 489 | } 490 | } 491 | } 492 | lastloc = s.loc; 493 | uselastloc = true; 494 | if (s.includeGuard && !s.seenTokens) 495 | { 496 | // Saw #endif and no tokens 497 | s.loc.srcFile.includeGuard = s.includeGuard; 498 | } 499 | } 500 | stack.psource = stack.psource.prev; 501 | debug (ContextStats) 502 | { 503 | --sourcei; 504 | } 505 | return stack.psource; 506 | } 507 | 508 | int nestLevel() 509 | { 510 | int level = -1; 511 | auto csf = currentSourceFile(); 512 | while (csf) 513 | { 514 | if (csf.isFile) 515 | ++level; 516 | csf = csf.prev; 517 | } 518 | return level; 519 | } 520 | 521 | bool isExpanded() { return stack.psource.isExpanded; } 522 | 523 | void setExpanded() { stack.psource.isExpanded = true; } 524 | 525 | /*************************** 526 | * Push predefined macro text into input. 527 | */ 528 | void pushPredefined(Id* m) 529 | { 530 | Loc loc; 531 | if (auto s = currentSourceFile()) 532 | loc = s.loc; 533 | else 534 | loc = lastloc; 535 | if (!loc.srcFile) 536 | return; 537 | 538 | uint n; 539 | 540 | switch (m.flags & (Id.IDlinnum | Id.IDfile | Id.IDcounter)) 541 | { 542 | case Id.IDlinnum: 543 | n = loc.lineNumber; 544 | break; 545 | 546 | case Id.IDfile: 547 | { 548 | auto s = push(); 549 | s.lineBuffer.initialize(); 550 | s.lineBuffer.put('"'); 551 | s.lineBuffer.put(cast(ustring)loc.fileName); 552 | s.lineBuffer.put('"'); 553 | s.ptext = s.lineBuffer[]; 554 | return; 555 | } 556 | 557 | case Id.IDcounter: 558 | n = counter++; 559 | break; 560 | 561 | default: 562 | assert(0); 563 | } 564 | uchar[counter.sizeof * 3 + 1] buf; 565 | auto len = sprintf(cast(char*)buf.ptr, "%u", n); 566 | assert(len > 0); 567 | push(cast(ustring)buf[0 .. len]); 568 | } 569 | 570 | /******************************************* 571 | * Search for file along paths[] 572 | * Input: 573 | * s file to search for (in a temp buffer) 574 | * sysstring if 575 | * system system status of the the file doing the #include 576 | * currentFile file name of file doing the #include 577 | * pathIndex index of file doing the #include 578 | * Output: 579 | * pathIndex index of where file was found 580 | * system new value for found file 581 | */ 582 | SrcFile* searchForFile(bool includeNext, bool sysstring, ref Sys system, 583 | const(char)[] s, 584 | ref int pathIndex, string currentFile) 585 | { 586 | //writefln("searchForFile(includeNext = %s, system = %s, s = '%s')", includeNext, system, s); 587 | //writefln("paths = [%s]", paths); 588 | 589 | string currentPath = null; 590 | if (!sysstring && !includeNext) 591 | currentPath = dirName(currentFile); 592 | 593 | if (includeNext) 594 | ++pathIndex; 595 | else 596 | { 597 | if (system || sysstring) 598 | pathIndex = 1; // skip current working directory, which is always first 599 | else 600 | pathIndex = 0; 601 | } 602 | 603 | auto sf = fileSearch(s, paths, pathIndex, pathIndex, currentPath); 604 | if (!sf) 605 | return null; 606 | 607 | //writefln("pathIndex = %d sysIndex = %d length = %d", pathIndex, sysIndex, paths.length); 608 | if (pathIndex >= sysIndex && pathIndex < paths.length) 609 | system |= Sys.syspath; // |= because bit is transitive 610 | 611 | /* Do not add to dependencies files that are found in system header directories, 612 | * or are transitively included from such a header. 613 | * "" or < > status has no bearing on dep generation. 614 | */ 615 | 616 | if (!sf.cachedRead && doDeps && !(system & Sys.syspath)) 617 | deps ~= sf.filename; 618 | 619 | return sf; 620 | } 621 | } 622 | 623 | 624 | /************************************************* 625 | * Determine if range r is an instance of Context 626 | */ 627 | 628 | template isContext(R) 629 | { 630 | enum bool isContext = __traits(hasMember, R, "stack"); 631 | } 632 | 633 | /************************************************* 634 | * Stack of Source's 635 | */ 636 | 637 | struct SourceStack 638 | { 639 | Source* psource; 640 | uchar xc = ' '; 641 | SourceStack* prev; 642 | Source* psourceRoot; 643 | 644 | __gshared SourceStack* _freelist; 645 | 646 | static SourceStack* allocate() 647 | { 648 | auto st = _freelist; 649 | if (st) 650 | { 651 | _freelist = st.prev; 652 | } 653 | else 654 | { 655 | st = cast(SourceStack*)malloc(SourceStack.sizeof); 656 | assert(st); 657 | *st = SourceStack.init; 658 | } 659 | return st; 660 | } 661 | 662 | void deallocate() 663 | { 664 | prev = _freelist; 665 | _freelist = &this; 666 | } 667 | 668 | @property bool empty() 669 | { 670 | return xc == xc.init; 671 | } 672 | 673 | @property uchar front() 674 | { 675 | return xc; 676 | } 677 | 678 | void popFront() 679 | { 680 | auto s = psource; 681 | if (s.ptext.length) 682 | { 683 | xc = s.ptext[0]; 684 | s.ptext = s.ptext[1 .. $]; 685 | } 686 | else 687 | popFront2(); 688 | } 689 | 690 | void popFront2() 691 | { 692 | while (1) 693 | { 694 | auto s = psource; 695 | if (s.ptext.length) 696 | { 697 | xc = s.ptext[0]; 698 | s.ptext = s.ptext[1 .. $]; 699 | } 700 | else 701 | { 702 | if (s.isFile && !s.input.empty) 703 | { 704 | s.readLine(); 705 | continue; 706 | } 707 | ++s.loc.lineNumber; 708 | s = pop(); 709 | if (s) 710 | continue; 711 | xc = xc.init; 712 | break; 713 | } 714 | break; 715 | } 716 | } 717 | 718 | Source* pop() 719 | { 720 | assert(!psource.isFile); 721 | psource = psource.prev; 722 | return psource; 723 | } 724 | } 725 | 726 | /****************************************** 727 | * Source text. 728 | */ 729 | 730 | struct Source 731 | { 732 | Textbuf!(uchar,"src") lineBuffer = void; 733 | 734 | LocList* includeTrace; 735 | 736 | uchar[] ptext; 737 | 738 | uchar[1] smallString; // for 1 character buffers 739 | bool isFile; // if it is a file 740 | bool isExpanded; // true if already macro expanded 741 | bool seenTokens; // true if seen tokens 742 | 743 | // Double linked list of stack of Source's 744 | Source* prev; 745 | Source* next; 746 | 747 | // These are if isFile is true 748 | Loc loc; // current location 749 | ustring input; // remaining file contents 750 | ustring includeGuard; 751 | int pathIndex; // index into paths[] of where this file came from (-1 if not) 752 | int ifstacki; // index into ifstack[] 753 | 754 | uchar[256] tmpbuf = void; 755 | 756 | /***** 757 | * Instead of constructing them individually, do them as a group, 758 | * necessary to sew together the linked list. 759 | */ 760 | static void initialize(Source[] sources, Source* prev, Source** pNext) 761 | { 762 | foreach (ref src; sources) 763 | { 764 | src.prev = prev; 765 | prev = &src; 766 | 767 | if (pNext) 768 | *pNext = &src; 769 | pNext = &src.next; 770 | src.next = null; 771 | 772 | src.lineBuffer = Textbuf!(uchar,"src")(src.tmpbuf); 773 | } 774 | } 775 | 776 | void addFile(SrcFile* sf, Sys system, int pathIndex) 777 | { 778 | // set new file, set haven't seen tokens yet 779 | loc.srcFile = sf; 780 | loc.fileName = sf.filename; 781 | loc.lineNumber = 0; 782 | loc.system = system; 783 | input = sf.contents; 784 | isFile = true; 785 | includeGuard = null; 786 | this.pathIndex = pathIndex; 787 | this.isExpanded = false; 788 | this.seenTokens = false; 789 | readLine(); 790 | } 791 | 792 | /*************************** 793 | * Read next line from input[] and store in lineBuffer[]. 794 | * Do \ line splicing. 795 | */ 796 | void readLine() 797 | { 798 | //writefln("Source.readLine() %d", loc.lineNumber); 799 | if (!input.empty) 800 | { 801 | ++loc.lineNumber; 802 | 803 | immutable(uchar)* p; 804 | for (p = input.ptr; *p != '\n'; ++p) 805 | { 806 | if (*cast(byte*)p < 0 && (*p == ESC.space || *p == ESC.brk)) 807 | goto L1; 808 | } 809 | 810 | if (p[-1] == '\\' || // SPAD ensures we can look behind 811 | p[-1] == '\r' && p[-2] == '\\') 812 | { 813 | L1: 814 | readLineEsc(); 815 | } 816 | else 817 | { 818 | auto len = p - input.ptr + 1; 819 | ptext = cast(uchar[])input[0 .. len]; 820 | input = input[len .. $]; 821 | } 822 | } 823 | } 824 | 825 | /********************** 826 | * Same as readLine(), but ESC.space and ESC.brk need to be 827 | * encoded as 0xFX. This should be fine as raw binary data is 828 | * only meaningful inside string or character literals, where 00 829 | * is already encoded. 830 | */ 831 | void readLineEsc() 832 | { 833 | lineBuffer.initialize(); 834 | while (!input.empty) 835 | { 836 | while (1) 837 | { 838 | uchar c = input[0]; 839 | input = input[1 .. $]; 840 | switch (c) 841 | { 842 | case '\n': 843 | lineBuffer.put(c); 844 | break; 845 | 846 | case ESC.space: 847 | case ESC.brk: 848 | lineBuffer.put(cast(ustring)"\\37"); 849 | c = (c & 7) + '0'; 850 | goto default; 851 | 852 | default: 853 | lineBuffer.put(c); 854 | continue; 855 | } 856 | break; 857 | } 858 | auto len = lineBuffer.length; 859 | uchar c = void; 860 | if (len >= 2 && 861 | ((c = lineBuffer[len - 2]) == '\\' || 862 | (c == '\r' && len >= 3 && lineBuffer[len - 3] == '\\'))) 863 | { 864 | if (c == '\r') 865 | lineBuffer.pop(); 866 | lineBuffer.pop(); 867 | lineBuffer.pop(); 868 | ++loc.lineNumber; 869 | } 870 | else 871 | break; 872 | } 873 | ptext = lineBuffer[]; 874 | 875 | assert(lineBuffer.length && lineBuffer[lineBuffer.length - 1] == '\n'); 876 | //writefln("\t%d", loc.lineNumber); 877 | } 878 | } 879 | 880 | /************************************** unit tests *************************/ 881 | 882 | version (unittest) 883 | { 884 | void testPreprocess(const Params params, string src, string result) 885 | { 886 | 887 | uchar[100] tmpbuf = void; 888 | auto outbuf = Textbuf!uchar(tmpbuf); 889 | 890 | auto context = Context!(Textbuf!uchar)(params); 891 | 892 | // Create a fake source file with contents 893 | auto sf = SrcFile.lookup("test.c"); 894 | sf.contents = cast(ustring)src; 895 | 896 | context.localStart(sf, &outbuf); 897 | 898 | context.preprocess(); 899 | 900 | context.expanded.finish(); 901 | if (outbuf[] != result) 902 | writefln("output = |%s|", cast(string)(outbuf[])); 903 | assert(outbuf[] == result); 904 | } 905 | } 906 | 907 | version (all) 908 | { 909 | unittest 910 | { 911 | const Params params; 912 | testPreprocess(params, 913 | "asdf\r 914 | asd\\\r 915 | ff\r 916 | ", 917 | 918 | `# 1 "test.c" 919 | # 2 "test.c" 920 | asdf 921 | # 3 "test.c" 922 | asdff 923 | `); 924 | } 925 | 926 | unittest 927 | { 928 | writeln("u2"); 929 | Params params; 930 | params.defines ~= "abc=def"; 931 | testPreprocess(params, "+abc+\n", 932 | "# 1 \"test.c\"\n# 1 \"test.c\"\n+def+\n"); 933 | } 934 | } 935 | 936 | unittest 937 | { 938 | writeln("u3"); 939 | Params params; 940 | params.defines ~= "abc2(a)=def=a=*"; 941 | testPreprocess(params, "+abc2(3)+\n", 942 | "# 1 \"test.c\"\n# 1 \"test.c\"\n+def=3=* +\n"); 943 | // exit(0); 944 | } 945 | 946 | /* 947 | * Local Variables: 948 | * mode: d 949 | * c-basic-offset: 4 950 | * End: 951 | */ 952 | -------------------------------------------------------------------------------- /defines_clang3_2.d: -------------------------------------------------------------------------------- 1 | immutable defines = [ 2 | `-D_LP64=1`, 3 | `-D__ATOMIC_ACQUIRE=2`, 4 | `-D__ATOMIC_ACQ_REL=4`, 5 | `-D__ATOMIC_CONSUME=1`, 6 | `-D__ATOMIC_RELAXED=0`, 7 | `-D__ATOMIC_RELEASE=3`, 8 | `-D__ATOMIC_SEQ_CST=5`, 9 | `-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__`, 10 | `-D__CHAR16_TYPE__=unsigned short`, 11 | `-D__CHAR32_TYPE__=unsigned int`, 12 | `-D__CHAR_BIT__=8`, 13 | `-D__CONSTANT_CFSTRINGS__=1`, 14 | `-D__DBL_DENORM_MIN__=4.9406564584124654e-324`, 15 | `-D__DBL_DIG__=15`, 16 | `-D__DBL_EPSILON__=2.2204460492503131e-16`, 17 | `-D__DBL_HAS_DENORM__=1`, 18 | `-D__DBL_HAS_INFINITY__=1`, 19 | `-D__DBL_HAS_QUIET_NAN__=1`, 20 | `-D__DBL_MANT_DIG__=53`, 21 | `-D__DBL_MAX_10_EXP__=308`, 22 | `-D__DBL_MAX_EXP__=1024`, 23 | `-D__DBL_MAX__=1.7976931348623157e+308`, 24 | `-D__DBL_MIN_10_EXP__=(-307)`, 25 | `-D__DBL_MIN_EXP__=(-1021)`, 26 | `-D__DBL_MIN__=2.2250738585072014e-308`, 27 | `-D__DECIMAL_DIG__=21`, 28 | `-D__ELF__=1`, 29 | `-D__FINITE_MATH_ONLY__=0`, 30 | `-D__FLT_DENORM_MIN__=1.40129846e-45F`, 31 | `-D__FLT_DIG__=6`, 32 | `-D__FLT_EPSILON__=1.19209290e-7F`, 33 | `-D__FLT_EVAL_METHOD__=0`, 34 | `-D__FLT_HAS_DENORM__=1`, 35 | `-D__FLT_HAS_INFINITY__=1`, 36 | `-D__FLT_HAS_QUIET_NAN__=1`, 37 | `-D__FLT_MANT_DIG__=24`, 38 | `-D__FLT_MAX_10_EXP__=38`, 39 | `-D__FLT_MAX_EXP__=128`, 40 | `-D__FLT_MAX__=3.40282347e+38F`, 41 | `-D__FLT_MIN_10_EXP__=(-37)`, 42 | `-D__FLT_MIN_EXP__=(-125)`, 43 | `-D__FLT_MIN__=1.17549435e-38F`, 44 | `-D__FLT_RADIX__=2`, 45 | `-D__GCC_ATOMIC_BOOL_LOCK_FREE=2`, 46 | `-D__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2`, 47 | `-D__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2`, 48 | `-D__GCC_ATOMIC_CHAR_LOCK_FREE=2`, 49 | `-D__GCC_ATOMIC_INT_LOCK_FREE=2`, 50 | `-D__GCC_ATOMIC_LLONG_LOCK_FREE=2`, 51 | `-D__GCC_ATOMIC_LONG_LOCK_FREE=2`, 52 | `-D__GCC_ATOMIC_POINTER_LOCK_FREE=2`, 53 | `-D__GCC_ATOMIC_SHORT_LOCK_FREE=2`, 54 | `-D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1`, 55 | `-D__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2`, 56 | `-D__GNUC_MINOR__=2`, 57 | `-D__GNUC_PATCHLEVEL__=1`, 58 | `-D__GNUC_STDC_INLINE__=1`, 59 | `-D__GNUC__=4`, 60 | `-D__GXX_ABI_VERSION=1002`, 61 | `-D__GXX_RTTI=1`, 62 | `-D__INT16_TYPE__=short`, 63 | `-D__INT32_TYPE__=int`, 64 | `-D__INT64_C_SUFFIX__=L`, 65 | `-D__INT64_TYPE__=long int`, 66 | `-D__INT8_TYPE__=char`, 67 | `-D__INTMAX_MAX__=9223372036854775807L`, 68 | `-D__INTMAX_TYPE__=long int`, 69 | `-D__INTMAX_WIDTH__=64`, 70 | `-D__INTPTR_TYPE__=long int`, 71 | `-D__INTPTR_WIDTH__=64`, 72 | `-D__INT_MAX__=2147483647`, 73 | `-D__LDBL_DENORM_MIN__=3.64519953188247460253e-4951L`, 74 | `-D__LDBL_DIG__=18`, 75 | `-D__LDBL_EPSILON__=1.08420217248550443401e-19L`, 76 | `-D__LDBL_HAS_DENORM__=1`, 77 | `-D__LDBL_HAS_INFINITY__=1`, 78 | `-D__LDBL_HAS_QUIET_NAN__=1`, 79 | `-D__LDBL_MANT_DIG__=64`, 80 | `-D__LDBL_MAX_10_EXP__=4932`, 81 | `-D__LDBL_MAX_EXP__=16384`, 82 | `-D__LDBL_MAX__=1.18973149535723176502e+4932L`, 83 | `-D__LDBL_MIN_10_EXP__=(-4931)`, 84 | `-D__LDBL_MIN_EXP__=(-16381)`, 85 | `-D__LDBL_MIN__=3.36210314311209350626e-4932L`, 86 | `-D__LITTLE_ENDIAN__=1`, 87 | `-D__LONG_LONG_MAX__=9223372036854775807LL`, 88 | `-D__LONG_MAX__=9223372036854775807L`, 89 | `-D__LP64__=1`, 90 | `-D__MMX__=1`, 91 | `-D__NO_INLINE__=1`, 92 | `-D__NO_MATH_INLINES=1`, 93 | `-D__ORDER_BIG_ENDIAN__=4321`, 94 | `-D__ORDER_LITTLE_ENDIAN__=1234`, 95 | `-D__ORDER_PDP_ENDIAN__=3412`, 96 | `-D__POINTER_WIDTH__=64`, 97 | `-D__PRAGMA_REDEFINE_EXTNAME=1`, 98 | `-D__PTRDIFF_TYPE__=long int`, 99 | `-D__PTRDIFF_WIDTH__=64`, 100 | `-D__REGISTER_PREFIX__=`, 101 | `-D__SCHAR_MAX__=127`, 102 | `-D__SHRT_MAX__=32767`, 103 | `-D__SIG_ATOMIC_WIDTH__=32`, 104 | `-D__SIZEOF_DOUBLE__=8`, 105 | `-D__SIZEOF_FLOAT__=4`, 106 | `-D__SIZEOF_INT__=4`, 107 | `-D__SIZEOF_LONG_DOUBLE__=16`, 108 | `-D__SIZEOF_LONG_LONG__=8`, 109 | `-D__SIZEOF_LONG__=8`, 110 | `-D__SIZEOF_POINTER__=8`, 111 | `-D__SIZEOF_PTRDIFF_T__=8`, 112 | `-D__SIZEOF_SHORT__=2`, 113 | `-D__SIZEOF_SIZE_T__=8`, 114 | `-D__SIZEOF_WCHAR_T__=4`, 115 | `-D__SIZEOF_WINT_T__=4`, 116 | `-D__SIZE_TYPE__=long unsigned int`, 117 | `-D__SIZE_WIDTH__=64`, 118 | `-D__SSE2_MATH__=1`, 119 | `-D__SSE2__=1`, 120 | `-D__SSE_MATH__=1`, 121 | `-D__SSE__=1`, 122 | `-D__STDC_HOSTED__=1`, 123 | `-D__STDC_VERSION__=201112L`, 124 | `-D__STDC__=1`, 125 | `-D__UINTMAX_TYPE__=long unsigned int`, 126 | `-D__USER_LABEL_PREFIX__=`, 127 | `-D__VERSION__="4.2.1 Compatible Clang 3.2 (tags/RELEASE_32/final)"`, 128 | `-D__WCHAR_MAX__=2147483647`, 129 | `-D__WCHAR_TYPE__=int`, 130 | `-D__WCHAR_WIDTH__=32`, 131 | `-D__WINT_TYPE__=unsigned int`, 132 | `-D__WINT_UNSIGNED__=1`, 133 | `-D__WINT_WIDTH__=32`, 134 | `-D__amd64=1`, 135 | `-D__amd64__=1`, 136 | `-D__clang__=1`, 137 | `-D__clang_major__=3`, 138 | `-D__clang_minor__=2`, 139 | `-D__clang_patchlevel__=0`, 140 | `-D__clang_version__="3.2 (tags/RELEASE_32/final)"`, 141 | `-D__gnu_linux__=1`, 142 | `-D__k8=1`, 143 | `-D__k8__=1`, 144 | `-D__linux=1`, 145 | `-D__linux__=1`, 146 | `-D__llvm__=1`, 147 | `-D__tune_k8__=1`, 148 | `-D__unix=1`, 149 | `-D__unix__=1`, 150 | `-D__x86_64=1`, 151 | `-D__x86_64__=1`, 152 | `-Dlinux=1`, 153 | `-Dunix=1`, 154 | ]; 155 | -------------------------------------------------------------------------------- /defines_clang3_4.d: -------------------------------------------------------------------------------- 1 | immutable defines = [ 2 | `-D_LP64=1`, 3 | `-D__ATOMIC_ACQUIRE=2`, 4 | `-D__ATOMIC_ACQ_REL=4`, 5 | `-D__ATOMIC_CONSUME=1`, 6 | `-D__ATOMIC_RELAXED=0`, 7 | `-D__ATOMIC_RELEASE=3`, 8 | `-D__ATOMIC_SEQ_CST=5`, 9 | `-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__`, 10 | `-D__CHAR16_TYPE__=unsigned short`, 11 | `-D__CHAR32_TYPE__=unsigned int`, 12 | `-D__CHAR_BIT__=8`, 13 | `-D__CONSTANT_CFSTRINGS__=1`, 14 | `-D__DBL_DENORM_MIN__=4.9406564584124654e-324`, 15 | `-D__DBL_DIG__=15`, 16 | `-D__DBL_EPSILON__=2.2204460492503131e-16`, 17 | `-D__DBL_HAS_DENORM__=1`, 18 | `-D__DBL_HAS_INFINITY__=1`, 19 | `-D__DBL_HAS_QUIET_NAN__=1`, 20 | `-D__DBL_MANT_DIG__=53`, 21 | `-D__DBL_MAX_10_EXP__=308`, 22 | `-D__DBL_MAX_EXP__=1024`, 23 | `-D__DBL_MAX__=1.7976931348623157e+308`, 24 | `-D__DBL_MIN_10_EXP__=(-307)`, 25 | `-D__DBL_MIN_EXP__=(-1021)`, 26 | `-D__DBL_MIN__=2.2250738585072014e-308`, 27 | `-D__DECIMAL_DIG__=21`, 28 | `-D__ELF__=1`, 29 | `-D__FINITE_MATH_ONLY__=0`, 30 | `-D__FLT_DENORM_MIN__=1.40129846e-45F`, 31 | `-D__FLT_DIG__=6`, 32 | `-D__FLT_EPSILON__=1.19209290e-7F`, 33 | `-D__FLT_EVAL_METHOD__=0`, 34 | `-D__FLT_HAS_DENORM__=1`, 35 | `-D__FLT_HAS_INFINITY__=1`, 36 | `-D__FLT_HAS_QUIET_NAN__=1`, 37 | `-D__FLT_MANT_DIG__=24`, 38 | `-D__FLT_MAX_10_EXP__=38`, 39 | `-D__FLT_MAX_EXP__=128`, 40 | `-D__FLT_MAX__=3.40282347e+38F`, 41 | `-D__FLT_MIN_10_EXP__=(-37)`, 42 | `-D__FLT_MIN_EXP__=(-125)`, 43 | `-D__FLT_MIN__=1.17549435e-38F`, 44 | `-D__FLT_RADIX__=2`, 45 | `-D__GCC_ATOMIC_BOOL_LOCK_FREE=2`, 46 | `-D__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2`, 47 | `-D__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2`, 48 | `-D__GCC_ATOMIC_CHAR_LOCK_FREE=2`, 49 | `-D__GCC_ATOMIC_INT_LOCK_FREE=2`, 50 | `-D__GCC_ATOMIC_LLONG_LOCK_FREE=2`, 51 | `-D__GCC_ATOMIC_LONG_LOCK_FREE=2`, 52 | `-D__GCC_ATOMIC_POINTER_LOCK_FREE=2`, 53 | `-D__GCC_ATOMIC_SHORT_LOCK_FREE=2`, 54 | `-D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1`, 55 | `-D__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2`, 56 | `-D__GNUC_MINOR__=2`, 57 | `-D__GNUC_PATCHLEVEL__=1`, 58 | `-D__GNUC_STDC_INLINE__=1`, 59 | `-D__GNUC__=4`, 60 | `-D__GXX_ABI_VERSION=1002`, 61 | `-D__GXX_RTTI=1`, 62 | `-D__INT16_TYPE__=short`, 63 | `-D__INT32_TYPE__=int`, 64 | `-D__INT64_C_SUFFIX__=L`, 65 | `-D__INT64_TYPE__=long int`, 66 | `-D__INT8_TYPE__=char`, 67 | `-D__INTMAX_MAX__=9223372036854775807L`, 68 | `-D__INTMAX_TYPE__=long int`, 69 | `-D__INTMAX_WIDTH__=64`, 70 | `-D__INTPTR_TYPE__=long int`, 71 | `-D__INTPTR_WIDTH__=64`, 72 | `-D__INT_MAX__=2147483647`, 73 | `-D__LDBL_DENORM_MIN__=3.64519953188247460253e-4951L`, 74 | `-D__LDBL_DIG__=18`, 75 | `-D__LDBL_EPSILON__=1.08420217248550443401e-19L`, 76 | `-D__LDBL_HAS_DENORM__=1`, 77 | `-D__LDBL_HAS_INFINITY__=1`, 78 | `-D__LDBL_HAS_QUIET_NAN__=1`, 79 | `-D__LDBL_MANT_DIG__=64`, 80 | `-D__LDBL_MAX_10_EXP__=4932`, 81 | `-D__LDBL_MAX_EXP__=16384`, 82 | `-D__LDBL_MAX__=1.18973149535723176502e+4932L`, 83 | `-D__LDBL_MIN_10_EXP__=(-4931)`, 84 | `-D__LDBL_MIN_EXP__=(-16381)`, 85 | `-D__LDBL_MIN__=3.36210314311209350626e-4932L`, 86 | `-D__LITTLE_ENDIAN__=1`, 87 | `-D__LONG_LONG_MAX__=9223372036854775807LL`, 88 | `-D__LONG_MAX__=9223372036854775807L`, 89 | `-D__LP64__=1`, 90 | `-D__MMX__=1`, 91 | `-D__NO_INLINE__=1`, 92 | `-D__NO_MATH_INLINES=1`, 93 | `-D__ORDER_BIG_ENDIAN__=4321`, 94 | `-D__ORDER_LITTLE_ENDIAN__=1234`, 95 | `-D__ORDER_PDP_ENDIAN__=3412`, 96 | `-D__POINTER_WIDTH__=64`, 97 | `-D__PRAGMA_REDEFINE_EXTNAME=1`, 98 | `-D__PTRDIFF_TYPE__=long int`, 99 | `-D__PTRDIFF_WIDTH__=64`, 100 | `-D__REGISTER_PREFIX__=`, 101 | `-D__SCHAR_MAX__=127`, 102 | `-D__SHRT_MAX__=32767`, 103 | `-D__SIG_ATOMIC_WIDTH__=32`, 104 | `-D__SIZEOF_DOUBLE__=8`, 105 | `-D__SIZEOF_FLOAT__=4`, 106 | `-D__SIZEOF_INT__=4`, 107 | `-D__SIZEOF_LONG_DOUBLE__=16`, 108 | `-D__SIZEOF_LONG_LONG__=8`, 109 | `-D__SIZEOF_LONG__=8`, 110 | `-D__SIZEOF_POINTER__=8`, 111 | `-D__SIZEOF_PTRDIFF_T__=8`, 112 | `-D__SIZEOF_SHORT__=2`, 113 | `-D__SIZEOF_SIZE_T__=8`, 114 | `-D__SIZEOF_WCHAR_T__=4`, 115 | `-D__SIZEOF_WINT_T__=4`, 116 | `-D__SIZE_TYPE__=long unsigned int`, 117 | `-D__SIZE_WIDTH__=64`, 118 | `-D__SSE2_MATH__=1`, 119 | `-D__SSE2__=1`, 120 | `-D__SSE_MATH__=1`, 121 | `-D__SSE__=1`, 122 | `-D__STDC_HOSTED__=1`, 123 | `-D__STDC_VERSION__=201112L`, 124 | `-D__STDC__=1`, 125 | `-D__UINTMAX_TYPE__=long unsigned int`, 126 | `-D__USER_LABEL_PREFIX__=`, 127 | `-D__VERSION__="4.2.1 Compatible Clang 3.2 (tags/RELEASE_32/final)"`, 128 | `-D__WCHAR_MAX__=2147483647`, 129 | `-D__WCHAR_TYPE__=int`, 130 | `-D__WCHAR_WIDTH__=32`, 131 | `-D__WINT_TYPE__=unsigned int`, 132 | `-D__WINT_UNSIGNED__=1`, 133 | `-D__WINT_WIDTH__=32`, 134 | `-D__amd64=1`, 135 | `-D__amd64__=1`, 136 | `-D__clang__=1`, 137 | `-D__clang_major__=3`, 138 | `-D__clang_minor__=2`, 139 | `-D__clang_patchlevel__=0`, 140 | `-D__clang_version__="3.2 (tags/RELEASE_32/final)"`, 141 | `-D__gnu_linux__=1`, 142 | `-D__k8=1`, 143 | `-D__k8__=1`, 144 | `-D__linux=1`, 145 | `-D__linux__=1`, 146 | `-D__llvm__=1`, 147 | `-D__tune_k8__=1`, 148 | `-D__unix=1`, 149 | `-D__unix__=1`, 150 | `-D__x86_64=1`, 151 | `-D__x86_64__=1`, 152 | `-Dlinux=1`, 153 | `-Dunix=1`, 154 | ]; 155 | -------------------------------------------------------------------------------- /defines_clangdev.d: -------------------------------------------------------------------------------- 1 | immutable defines = [ 2 | `-D_LP64=1`, 3 | `-D__ATOMIC_ACQUIRE=2`, 4 | `-D__ATOMIC_ACQ_REL=4`, 5 | `-D__ATOMIC_CONSUME=1`, 6 | `-D__ATOMIC_RELAXED=0`, 7 | `-D__ATOMIC_RELEASE=3`, 8 | `-D__ATOMIC_SEQ_CST=5`, 9 | `-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__`, 10 | `-D__CHAR16_TYPE__=unsigned short`, 11 | `-D__CHAR32_TYPE__=unsigned int`, 12 | `-D__CHAR_BIT__=8`, 13 | `-D__CONSTANT_CFSTRINGS__=1`, 14 | `-D__DBL_DENORM_MIN__=4.9406564584124654e-324`, 15 | `-D__DBL_DIG__=15`, 16 | `-D__DBL_EPSILON__=2.2204460492503131e-16`, 17 | `-D__DBL_HAS_DENORM__=1`, 18 | `-D__DBL_HAS_INFINITY__=1`, 19 | `-D__DBL_HAS_QUIET_NAN__=1`, 20 | `-D__DBL_MANT_DIG__=53`, 21 | `-D__DBL_MAX_10_EXP__=308`, 22 | `-D__DBL_MAX_EXP__=1024`, 23 | `-D__DBL_MAX__=1.7976931348623157e+308`, 24 | `-D__DBL_MIN_10_EXP__=(-307)`, 25 | `-D__DBL_MIN_EXP__=(-1021)`, 26 | `-D__DBL_MIN__=2.2250738585072014e-308`, 27 | `-D__DECIMAL_DIG__=21`, 28 | `-D__ELF__=1`, 29 | `-D__FINITE_MATH_ONLY__=0`, 30 | `-D__FLT_DENORM_MIN__=1.40129846e-45F`, 31 | `-D__FLT_DIG__=6`, 32 | `-D__FLT_EPSILON__=1.19209290e-7F`, 33 | `-D__FLT_EVAL_METHOD__=0`, 34 | `-D__FLT_HAS_DENORM__=1`, 35 | `-D__FLT_HAS_INFINITY__=1`, 36 | `-D__FLT_HAS_QUIET_NAN__=1`, 37 | `-D__FLT_MANT_DIG__=24`, 38 | `-D__FLT_MAX_10_EXP__=38`, 39 | `-D__FLT_MAX_EXP__=128`, 40 | `-D__FLT_MAX__=3.40282347e+38F`, 41 | `-D__FLT_MIN_10_EXP__=(-37)`, 42 | `-D__FLT_MIN_EXP__=(-125)`, 43 | `-D__FLT_MIN__=1.17549435e-38F`, 44 | `-D__FLT_RADIX__=2`, 45 | `-D__GCC_ATOMIC_BOOL_LOCK_FREE=2`, 46 | `-D__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2`, 47 | `-D__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2`, 48 | `-D__GCC_ATOMIC_CHAR_LOCK_FREE=2`, 49 | `-D__GCC_ATOMIC_INT_LOCK_FREE=2`, 50 | `-D__GCC_ATOMIC_LLONG_LOCK_FREE=2`, 51 | `-D__GCC_ATOMIC_LONG_LOCK_FREE=2`, 52 | `-D__GCC_ATOMIC_POINTER_LOCK_FREE=2`, 53 | `-D__GCC_ATOMIC_SHORT_LOCK_FREE=2`, 54 | `-D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1`, 55 | `-D__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2`, 56 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1=1`, 57 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2=1`, 58 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4=1`, 59 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8=1`, 60 | `-D__GNUC_MINOR__=2`, 61 | `-D__GNUC_PATCHLEVEL__=1`, 62 | `-D__GNUC_STDC_INLINE__=1`, 63 | `-D__GNUC__=4`, 64 | `-D__GXX_ABI_VERSION=1002`, 65 | `-D__GXX_RTTI=1`, 66 | `-D__INT16_TYPE__=short`, 67 | `-D__INT32_TYPE__=int`, 68 | `-D__INT64_C_SUFFIX__=L`, 69 | `-D__INT64_TYPE__=long int`, 70 | `-D__INT8_TYPE__=char`, 71 | `-D__INTMAX_MAX__=9223372036854775807L`, 72 | `-D__INTMAX_TYPE__=long int`, 73 | `-D__INTMAX_WIDTH__=64`, 74 | `-D__INTPTR_TYPE__=long int`, 75 | `-D__INTPTR_WIDTH__=64`, 76 | `-D__INT_MAX__=2147483647`, 77 | `-D__LDBL_DENORM_MIN__=3.64519953188247460253e-4951L`, 78 | `-D__LDBL_DIG__=18`, 79 | `-D__LDBL_EPSILON__=1.08420217248550443401e-19L`, 80 | `-D__LDBL_HAS_DENORM__=1`, 81 | `-D__LDBL_HAS_INFINITY__=1`, 82 | `-D__LDBL_HAS_QUIET_NAN__=1`, 83 | `-D__LDBL_MANT_DIG__=64`, 84 | `-D__LDBL_MAX_10_EXP__=4932`, 85 | `-D__LDBL_MAX_EXP__=16384`, 86 | `-D__LDBL_MAX__=1.18973149535723176502e+4932L`, 87 | `-D__LDBL_MIN_10_EXP__=(-4931)`, 88 | `-D__LDBL_MIN_EXP__=(-16381)`, 89 | `-D__LDBL_MIN__=3.36210314311209350626e-4932L`, 90 | `-D__LITTLE_ENDIAN__=1`, 91 | `-D__LONG_LONG_MAX__=9223372036854775807LL`, 92 | `-D__LONG_MAX__=9223372036854775807L`, 93 | `-D__LP64__=1`, 94 | `-D__MMX__=1`, 95 | `-D__NO_INLINE__=1`, 96 | `-D__NO_MATH_INLINES=1`, 97 | `-D__ORDER_BIG_ENDIAN__=4321`, 98 | `-D__ORDER_LITTLE_ENDIAN__=1234`, 99 | `-D__ORDER_PDP_ENDIAN__=3412`, 100 | `-D__POINTER_WIDTH__=64`, 101 | `-D__PRAGMA_REDEFINE_EXTNAME=1`, 102 | `-D__PTRDIFF_TYPE__=long int`, 103 | `-D__PTRDIFF_WIDTH__=64`, 104 | `-D__REGISTER_PREFIX__=`, 105 | `-D__SCHAR_MAX__=127`, 106 | `-D__SHRT_MAX__=32767`, 107 | `-D__SIG_ATOMIC_WIDTH__=32`, 108 | `-D__SIZEOF_DOUBLE__=8`, 109 | `-D__SIZEOF_FLOAT__=4`, 110 | `-D__SIZEOF_INT128__=16`, 111 | `-D__SIZEOF_INT__=4`, 112 | `-D__SIZEOF_LONG_DOUBLE__=16`, 113 | `-D__SIZEOF_LONG_LONG__=8`, 114 | `-D__SIZEOF_LONG__=8`, 115 | `-D__SIZEOF_POINTER__=8`, 116 | `-D__SIZEOF_PTRDIFF_T__=8`, 117 | `-D__SIZEOF_SHORT__=2`, 118 | `-D__SIZEOF_SIZE_T__=8`, 119 | `-D__SIZEOF_WCHAR_T__=4`, 120 | `-D__SIZEOF_WINT_T__=4`, 121 | `-D__SIZE_MAX__=18446744073709551615UL`, 122 | `-D__SIZE_TYPE__=long unsigned int`, 123 | `-D__SIZE_WIDTH__=64`, 124 | `-D__SSE2_MATH__=1`, 125 | `-D__SSE2__=1`, 126 | `-D__SSE_MATH__=1`, 127 | `-D__SSE__=1`, 128 | `-D__STDC_HOSTED__=1`, 129 | `-D__STDC_UTF_16__=1`, 130 | `-D__STDC_UTF_32__=1`, 131 | `-D__STDC_VERSION__=201112L`, 132 | `-D__STDC__=1`, 133 | `-D__UINTMAX_TYPE__=long unsigned int`, 134 | `-D__USER_LABEL_PREFIX__=`, 135 | `-D__VERSION__="4.2.1 Compatible Clang 3.4 "`, 136 | `-D__WCHAR_MAX__=2147483647`, 137 | `-D__WCHAR_TYPE__=int`, 138 | `-D__WCHAR_WIDTH__=32`, 139 | `-D__WINT_TYPE__=unsigned int`, 140 | `-D__WINT_UNSIGNED__=1`, 141 | `-D__WINT_WIDTH__=32`, 142 | `-D__amd64=1`, 143 | `-D__amd64__=1`, 144 | `-D__clang__=1`, 145 | `-D__clang_major__=3`, 146 | `-D__clang_minor__=4`, 147 | `-D__clang_patchlevel__=0`, 148 | `-D__clang_version__="3.4 "`, 149 | `-D__gnu_linux__=1`, 150 | `-D__k8=1`, 151 | `-D__k8__=1`, 152 | `-D__linux=1`, 153 | `-D__linux__=1`, 154 | `-D__llvm__=1`, 155 | `-D__tune_k8__=1`, 156 | `-D__unix=1`, 157 | `-D__unix__=1`, 158 | `-D__x86_64=1`, 159 | `-D__x86_64__=1`, 160 | `-Dlinux=1`, 161 | `-Dunix=1`, 162 | ]; 163 | -------------------------------------------------------------------------------- /defines_clangxx3_2.d: -------------------------------------------------------------------------------- 1 | immutable xxdefines = [ 2 | `-D_GNU_SOURCE=1`, 3 | `-D_LP64=1`, 4 | `-D__ATOMIC_ACQUIRE=2`, 5 | `-D__ATOMIC_ACQ_REL=4`, 6 | `-D__ATOMIC_CONSUME=1`, 7 | `-D__ATOMIC_RELAXED=0`, 8 | `-D__ATOMIC_RELEASE=3`, 9 | `-D__ATOMIC_SEQ_CST=5`, 10 | `-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__`, 11 | `-D__CHAR16_TYPE__=unsigned short`, 12 | `-D__CHAR32_TYPE__=unsigned int`, 13 | `-D__CHAR_BIT__=8`, 14 | `-D__CONSTANT_CFSTRINGS__=1`, 15 | `-D__DBL_DENORM_MIN__=4.9406564584124654e-324`, 16 | `-D__DBL_DIG__=15`, 17 | `-D__DBL_EPSILON__=2.2204460492503131e-16`, 18 | `-D__DBL_HAS_DENORM__=1`, 19 | `-D__DBL_HAS_INFINITY__=1`, 20 | `-D__DBL_HAS_QUIET_NAN__=1`, 21 | `-D__DBL_MANT_DIG__=53`, 22 | `-D__DBL_MAX_10_EXP__=308`, 23 | `-D__DBL_MAX_EXP__=1024`, 24 | `-D__DBL_MAX__=1.7976931348623157e+308`, 25 | `-D__DBL_MIN_10_EXP__=(-307)`, 26 | `-D__DBL_MIN_EXP__=(-1021)`, 27 | `-D__DBL_MIN__=2.2250738585072014e-308`, 28 | `-D__DECIMAL_DIG__=21`, 29 | `-D__ELF__=1`, 30 | `-D__EXCEPTIONS=1`, 31 | `-D__FINITE_MATH_ONLY__=0`, 32 | `-D__FLT_DENORM_MIN__=1.40129846e-45F`, 33 | `-D__FLT_DIG__=6`, 34 | `-D__FLT_EPSILON__=1.19209290e-7F`, 35 | `-D__FLT_EVAL_METHOD__=0`, 36 | `-D__FLT_HAS_DENORM__=1`, 37 | `-D__FLT_HAS_INFINITY__=1`, 38 | `-D__FLT_HAS_QUIET_NAN__=1`, 39 | `-D__FLT_MANT_DIG__=24`, 40 | `-D__FLT_MAX_10_EXP__=38`, 41 | `-D__FLT_MAX_EXP__=128`, 42 | `-D__FLT_MAX__=3.40282347e+38F`, 43 | `-D__FLT_MIN_10_EXP__=(-37)`, 44 | `-D__FLT_MIN_EXP__=(-125)`, 45 | `-D__FLT_MIN__=1.17549435e-38F`, 46 | `-D__FLT_RADIX__=2`, 47 | `-D__GCC_ATOMIC_BOOL_LOCK_FREE=2`, 48 | `-D__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2`, 49 | `-D__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2`, 50 | `-D__GCC_ATOMIC_CHAR_LOCK_FREE=2`, 51 | `-D__GCC_ATOMIC_INT_LOCK_FREE=2`, 52 | `-D__GCC_ATOMIC_LLONG_LOCK_FREE=2`, 53 | `-D__GCC_ATOMIC_LONG_LOCK_FREE=2`, 54 | `-D__GCC_ATOMIC_POINTER_LOCK_FREE=2`, 55 | `-D__GCC_ATOMIC_SHORT_LOCK_FREE=2`, 56 | `-D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1`, 57 | `-D__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2`, 58 | `-D__GNUC_GNU_INLINE__=1`, 59 | `-D__GNUC_MINOR__=2`, 60 | `-D__GNUC_PATCHLEVEL__=1`, 61 | `-D__GNUC__=4`, 62 | `-D__GNUG__=4`, 63 | `-D__GXX_ABI_VERSION=1002`, 64 | `-D__GXX_EXPERIMENTAL_CXX0X__=1`, 65 | `-D__GXX_RTTI=1`, 66 | `-D__GXX_WEAK__=1`, 67 | `-D__INT16_TYPE__=short`, 68 | `-D__INT32_TYPE__=int`, 69 | `-D__INT64_C_SUFFIX__=L`, 70 | `-D__INT64_TYPE__=long int`, 71 | `-D__INT8_TYPE__=char`, 72 | `-D__INTMAX_MAX__=9223372036854775807L`, 73 | `-D__INTMAX_TYPE__=long int`, 74 | `-D__INTMAX_WIDTH__=64`, 75 | `-D__INTPTR_TYPE__=long int`, 76 | `-D__INTPTR_WIDTH__=64`, 77 | `-D__INT_MAX__=2147483647`, 78 | `-D__LDBL_DENORM_MIN__=3.64519953188247460253e-4951L`, 79 | `-D__LDBL_DIG__=18`, 80 | `-D__LDBL_EPSILON__=1.08420217248550443401e-19L`, 81 | `-D__LDBL_HAS_DENORM__=1`, 82 | `-D__LDBL_HAS_INFINITY__=1`, 83 | `-D__LDBL_HAS_QUIET_NAN__=1`, 84 | `-D__LDBL_MANT_DIG__=64`, 85 | `-D__LDBL_MAX_10_EXP__=4932`, 86 | `-D__LDBL_MAX_EXP__=16384`, 87 | `-D__LDBL_MAX__=1.18973149535723176502e+4932L`, 88 | `-D__LDBL_MIN_10_EXP__=(-4931)`, 89 | `-D__LDBL_MIN_EXP__=(-16381)`, 90 | `-D__LDBL_MIN__=3.36210314311209350626e-4932L`, 91 | `-D__LITTLE_ENDIAN__=1`, 92 | `-D__LONG_LONG_MAX__=9223372036854775807LL`, 93 | `-D__LONG_MAX__=9223372036854775807L`, 94 | `-D__LP64__=1`, 95 | `-D__MMX__=1`, 96 | `-D__NO_INLINE__=1`, 97 | `-D__NO_MATH_INLINES=1`, 98 | `-D__ORDER_BIG_ENDIAN__=4321`, 99 | `-D__ORDER_LITTLE_ENDIAN__=1234`, 100 | `-D__ORDER_PDP_ENDIAN__=3412`, 101 | `-D__POINTER_WIDTH__=64`, 102 | `-D__PRAGMA_REDEFINE_EXTNAME=1`, 103 | `-D__PTRDIFF_TYPE__=long int`, 104 | `-D__PTRDIFF_WIDTH__=64`, 105 | `-D__REGISTER_PREFIX__=`, 106 | `-D__SCHAR_MAX__=127`, 107 | `-D__SHRT_MAX__=32767`, 108 | `-D__SIG_ATOMIC_WIDTH__=32`, 109 | `-D__SIZEOF_DOUBLE__=8`, 110 | `-D__SIZEOF_FLOAT__=4`, 111 | `-D__SIZEOF_INT__=4`, 112 | `-D__SIZEOF_LONG_DOUBLE__=16`, 113 | `-D__SIZEOF_LONG_LONG__=8`, 114 | `-D__SIZEOF_LONG__=8`, 115 | `-D__SIZEOF_POINTER__=8`, 116 | `-D__SIZEOF_PTRDIFF_T__=8`, 117 | `-D__SIZEOF_SHORT__=2`, 118 | `-D__SIZEOF_SIZE_T__=8`, 119 | `-D__SIZEOF_WCHAR_T__=4`, 120 | `-D__SIZEOF_WINT_T__=4`, 121 | `-D__SIZE_TYPE__=long unsigned int`, 122 | `-D__SIZE_WIDTH__=64`, 123 | `-D__SSE2_MATH__=1`, 124 | `-D__SSE2__=1`, 125 | `-D__SSE_MATH__=1`, 126 | `-D__SSE__=1`, 127 | `-D__STDC_HOSTED__=1`, 128 | `-D__STDC__=1`, 129 | `-D__UINTMAX_TYPE__=long unsigned int`, 130 | `-D__USER_LABEL_PREFIX__=`, 131 | `-D__VERSION__="4.2.1 Compatible Clang 3.2 (tags/RELEASE_32/final)"`, 132 | `-D__WCHAR_MAX__=2147483647`, 133 | `-D__WCHAR_TYPE__=int`, 134 | `-D__WCHAR_WIDTH__=32`, 135 | `-D__WINT_TYPE__=unsigned int`, 136 | `-D__WINT_UNSIGNED__=1`, 137 | `-D__WINT_WIDTH__=32`, 138 | `-D__amd64=1`, 139 | `-D__amd64__=1`, 140 | `-D__clang__=1`, 141 | `-D__clang_major__=3`, 142 | `-D__clang_minor__=2`, 143 | `-D__clang_patchlevel__=0`, 144 | `-D__clang_version__="3.2 (tags/RELEASE_32/final)"`, 145 | `-D__cplusplus=201103L`, 146 | `-D__gnu_linux__=1`, 147 | `-D__k8=1`, 148 | `-D__k8__=1`, 149 | `-D__linux=1`, 150 | `-D__linux__=1`, 151 | `-D__llvm__=1`, 152 | `-D__private_extern__=extern`, 153 | `-D__tune_k8__=1`, 154 | `-D__unix=1`, 155 | `-D__unix__=1`, 156 | `-D__x86_64=1`, 157 | `-D__x86_64__=1`, 158 | `-Dlinux=1`, 159 | `-Dunix=1`, 160 | ]; 161 | -------------------------------------------------------------------------------- /defines_clangxx3_4.d: -------------------------------------------------------------------------------- 1 | immutable xxdefines = [ 2 | `-D_GNU_SOURCE=1`, 3 | `-D_LP64=1`, 4 | `-D__ATOMIC_ACQUIRE=2`, 5 | `-D__ATOMIC_ACQ_REL=4`, 6 | `-D__ATOMIC_CONSUME=1`, 7 | `-D__ATOMIC_RELAXED=0`, 8 | `-D__ATOMIC_RELEASE=3`, 9 | `-D__ATOMIC_SEQ_CST=5`, 10 | `-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__`, 11 | `-D__CHAR16_TYPE__=unsigned short`, 12 | `-D__CHAR32_TYPE__=unsigned int`, 13 | `-D__CHAR_BIT__=8`, 14 | `-D__CONSTANT_CFSTRINGS__=1`, 15 | `-D__DBL_DENORM_MIN__=4.9406564584124654e-324`, 16 | `-D__DBL_DIG__=15`, 17 | `-D__DBL_EPSILON__=2.2204460492503131e-16`, 18 | `-D__DBL_HAS_DENORM__=1`, 19 | `-D__DBL_HAS_INFINITY__=1`, 20 | `-D__DBL_HAS_QUIET_NAN__=1`, 21 | `-D__DBL_MANT_DIG__=53`, 22 | `-D__DBL_MAX_10_EXP__=308`, 23 | `-D__DBL_MAX_EXP__=1024`, 24 | `-D__DBL_MAX__=1.7976931348623157e+308`, 25 | `-D__DBL_MIN_10_EXP__=(-307)`, 26 | `-D__DBL_MIN_EXP__=(-1021)`, 27 | `-D__DBL_MIN__=2.2250738585072014e-308`, 28 | `-D__DECIMAL_DIG__=21`, 29 | `-D__ELF__=1`, 30 | `-D__EXCEPTIONS=1`, 31 | `-D__FINITE_MATH_ONLY__=0`, 32 | `-D__FLT_DENORM_MIN__=1.40129846e-45F`, 33 | `-D__FLT_DIG__=6`, 34 | `-D__FLT_EPSILON__=1.19209290e-7F`, 35 | `-D__FLT_EVAL_METHOD__=0`, 36 | `-D__FLT_HAS_DENORM__=1`, 37 | `-D__FLT_HAS_INFINITY__=1`, 38 | `-D__FLT_HAS_QUIET_NAN__=1`, 39 | `-D__FLT_MANT_DIG__=24`, 40 | `-D__FLT_MAX_10_EXP__=38`, 41 | `-D__FLT_MAX_EXP__=128`, 42 | `-D__FLT_MAX__=3.40282347e+38F`, 43 | `-D__FLT_MIN_10_EXP__=(-37)`, 44 | `-D__FLT_MIN_EXP__=(-125)`, 45 | `-D__FLT_MIN__=1.17549435e-38F`, 46 | `-D__FLT_RADIX__=2`, 47 | `-D__GCC_ATOMIC_BOOL_LOCK_FREE=2`, 48 | `-D__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2`, 49 | `-D__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2`, 50 | `-D__GCC_ATOMIC_CHAR_LOCK_FREE=2`, 51 | `-D__GCC_ATOMIC_INT_LOCK_FREE=2`, 52 | `-D__GCC_ATOMIC_LLONG_LOCK_FREE=2`, 53 | `-D__GCC_ATOMIC_LONG_LOCK_FREE=2`, 54 | `-D__GCC_ATOMIC_POINTER_LOCK_FREE=2`, 55 | `-D__GCC_ATOMIC_SHORT_LOCK_FREE=2`, 56 | `-D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1`, 57 | `-D__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2`, 58 | `-D__GNUC_GNU_INLINE__=1`, 59 | `-D__GNUC_MINOR__=2`, 60 | `-D__GNUC_PATCHLEVEL__=1`, 61 | `-D__GNUC__=4`, 62 | `-D__GNUG__=4`, 63 | `-D__GXX_ABI_VERSION=1002`, 64 | `-D__GXX_EXPERIMENTAL_CXX0X__=1`, 65 | `-D__GXX_RTTI=1`, 66 | `-D__GXX_WEAK__=1`, 67 | `-D__INT16_TYPE__=short`, 68 | `-D__INT32_TYPE__=int`, 69 | `-D__INT64_C_SUFFIX__=L`, 70 | `-D__INT64_TYPE__=long int`, 71 | `-D__INT8_TYPE__=char`, 72 | `-D__INTMAX_MAX__=9223372036854775807L`, 73 | `-D__INTMAX_TYPE__=long int`, 74 | `-D__INTMAX_WIDTH__=64`, 75 | `-D__INTPTR_TYPE__=long int`, 76 | `-D__INTPTR_WIDTH__=64`, 77 | `-D__INT_MAX__=2147483647`, 78 | `-D__LDBL_DENORM_MIN__=3.64519953188247460253e-4951L`, 79 | `-D__LDBL_DIG__=18`, 80 | `-D__LDBL_EPSILON__=1.08420217248550443401e-19L`, 81 | `-D__LDBL_HAS_DENORM__=1`, 82 | `-D__LDBL_HAS_INFINITY__=1`, 83 | `-D__LDBL_HAS_QUIET_NAN__=1`, 84 | `-D__LDBL_MANT_DIG__=64`, 85 | `-D__LDBL_MAX_10_EXP__=4932`, 86 | `-D__LDBL_MAX_EXP__=16384`, 87 | `-D__LDBL_MAX__=1.18973149535723176502e+4932L`, 88 | `-D__LDBL_MIN_10_EXP__=(-4931)`, 89 | `-D__LDBL_MIN_EXP__=(-16381)`, 90 | `-D__LDBL_MIN__=3.36210314311209350626e-4932L`, 91 | `-D__LITTLE_ENDIAN__=1`, 92 | `-D__LONG_LONG_MAX__=9223372036854775807LL`, 93 | `-D__LONG_MAX__=9223372036854775807L`, 94 | `-D__LP64__=1`, 95 | `-D__MMX__=1`, 96 | `-D__NO_INLINE__=1`, 97 | `-D__NO_MATH_INLINES=1`, 98 | `-D__ORDER_BIG_ENDIAN__=4321`, 99 | `-D__ORDER_LITTLE_ENDIAN__=1234`, 100 | `-D__ORDER_PDP_ENDIAN__=3412`, 101 | `-D__POINTER_WIDTH__=64`, 102 | `-D__PRAGMA_REDEFINE_EXTNAME=1`, 103 | `-D__PTRDIFF_TYPE__=long int`, 104 | `-D__PTRDIFF_WIDTH__=64`, 105 | `-D__REGISTER_PREFIX__=`, 106 | `-D__SCHAR_MAX__=127`, 107 | `-D__SHRT_MAX__=32767`, 108 | `-D__SIG_ATOMIC_WIDTH__=32`, 109 | `-D__SIZEOF_DOUBLE__=8`, 110 | `-D__SIZEOF_FLOAT__=4`, 111 | `-D__SIZEOF_INT__=4`, 112 | `-D__SIZEOF_LONG_DOUBLE__=16`, 113 | `-D__SIZEOF_LONG_LONG__=8`, 114 | `-D__SIZEOF_LONG__=8`, 115 | `-D__SIZEOF_POINTER__=8`, 116 | `-D__SIZEOF_PTRDIFF_T__=8`, 117 | `-D__SIZEOF_SHORT__=2`, 118 | `-D__SIZEOF_SIZE_T__=8`, 119 | `-D__SIZEOF_WCHAR_T__=4`, 120 | `-D__SIZEOF_WINT_T__=4`, 121 | `-D__SIZE_TYPE__=long unsigned int`, 122 | `-D__SIZE_WIDTH__=64`, 123 | `-D__SSE2_MATH__=1`, 124 | `-D__SSE2__=1`, 125 | `-D__SSE_MATH__=1`, 126 | `-D__SSE__=1`, 127 | `-D__STDC_HOSTED__=1`, 128 | `-D__STDC__=1`, 129 | `-D__UINTMAX_TYPE__=long unsigned int`, 130 | `-D__USER_LABEL_PREFIX__=`, 131 | `-D__VERSION__="4.2.1 Compatible Clang 3.2 (tags/RELEASE_32/final)"`, 132 | `-D__WCHAR_MAX__=2147483647`, 133 | `-D__WCHAR_TYPE__=int`, 134 | `-D__WCHAR_WIDTH__=32`, 135 | `-D__WINT_TYPE__=unsigned int`, 136 | `-D__WINT_UNSIGNED__=1`, 137 | `-D__WINT_WIDTH__=32`, 138 | `-D__amd64=1`, 139 | `-D__amd64__=1`, 140 | `-D__clang__=1`, 141 | `-D__clang_major__=3`, 142 | `-D__clang_minor__=2`, 143 | `-D__clang_patchlevel__=0`, 144 | `-D__clang_version__="3.2 (tags/RELEASE_32/final)"`, 145 | `-D__cplusplus=201103L`, 146 | `-D__gnu_linux__=1`, 147 | `-D__k8=1`, 148 | `-D__k8__=1`, 149 | `-D__linux=1`, 150 | `-D__linux__=1`, 151 | `-D__llvm__=1`, 152 | `-D__private_extern__=extern`, 153 | `-D__tune_k8__=1`, 154 | `-D__unix=1`, 155 | `-D__unix__=1`, 156 | `-D__x86_64=1`, 157 | `-D__x86_64__=1`, 158 | `-Dlinux=1`, 159 | `-Dunix=1`, 160 | ]; 161 | -------------------------------------------------------------------------------- /defines_clangxxdev.d: -------------------------------------------------------------------------------- 1 | immutable xxdefines = [ 2 | `-D_GNU_SOURCE=1`, 3 | `-D_LP64=1`, 4 | `-D__ATOMIC_ACQUIRE=2`, 5 | `-D__ATOMIC_ACQ_REL=4`, 6 | `-D__ATOMIC_CONSUME=1`, 7 | `-D__ATOMIC_RELAXED=0`, 8 | `-D__ATOMIC_RELEASE=3`, 9 | `-D__ATOMIC_SEQ_CST=5`, 10 | `-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__`, 11 | `-D__CHAR16_TYPE__=unsigned short`, 12 | `-D__CHAR32_TYPE__=unsigned int`, 13 | `-D__CHAR_BIT__=8`, 14 | `-D__CONSTANT_CFSTRINGS__=1`, 15 | `-D__DBL_DENORM_MIN__=4.9406564584124654e-324`, 16 | `-D__DBL_DIG__=15`, 17 | `-D__DBL_EPSILON__=2.2204460492503131e-16`, 18 | `-D__DBL_HAS_DENORM__=1`, 19 | `-D__DBL_HAS_INFINITY__=1`, 20 | `-D__DBL_HAS_QUIET_NAN__=1`, 21 | `-D__DBL_MANT_DIG__=53`, 22 | `-D__DBL_MAX_10_EXP__=308`, 23 | `-D__DBL_MAX_EXP__=1024`, 24 | `-D__DBL_MAX__=1.7976931348623157e+308`, 25 | `-D__DBL_MIN_10_EXP__=(-307)`, 26 | `-D__DBL_MIN_EXP__=(-1021)`, 27 | `-D__DBL_MIN__=2.2250738585072014e-308`, 28 | `-D__DECIMAL_DIG__=21`, 29 | `-D__ELF__=1`, 30 | `-D__EXCEPTIONS=1`, 31 | `-D__FINITE_MATH_ONLY__=0`, 32 | `-D__FLT_DENORM_MIN__=1.40129846e-45F`, 33 | `-D__FLT_DIG__=6`, 34 | `-D__FLT_EPSILON__=1.19209290e-7F`, 35 | `-D__FLT_EVAL_METHOD__=0`, 36 | `-D__FLT_HAS_DENORM__=1`, 37 | `-D__FLT_HAS_INFINITY__=1`, 38 | `-D__FLT_HAS_QUIET_NAN__=1`, 39 | `-D__FLT_MANT_DIG__=24`, 40 | `-D__FLT_MAX_10_EXP__=38`, 41 | `-D__FLT_MAX_EXP__=128`, 42 | `-D__FLT_MAX__=3.40282347e+38F`, 43 | `-D__FLT_MIN_10_EXP__=(-37)`, 44 | `-D__FLT_MIN_EXP__=(-125)`, 45 | `-D__FLT_MIN__=1.17549435e-38F`, 46 | `-D__FLT_RADIX__=2`, 47 | `-D__GCC_ATOMIC_BOOL_LOCK_FREE=2`, 48 | `-D__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2`, 49 | `-D__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2`, 50 | `-D__GCC_ATOMIC_CHAR_LOCK_FREE=2`, 51 | `-D__GCC_ATOMIC_INT_LOCK_FREE=2`, 52 | `-D__GCC_ATOMIC_LLONG_LOCK_FREE=2`, 53 | `-D__GCC_ATOMIC_LONG_LOCK_FREE=2`, 54 | `-D__GCC_ATOMIC_POINTER_LOCK_FREE=2`, 55 | `-D__GCC_ATOMIC_SHORT_LOCK_FREE=2`, 56 | `-D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1`, 57 | `-D__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2`, 58 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1=1`, 59 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2=1`, 60 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4=1`, 61 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8=1`, 62 | `-D__GNUC_GNU_INLINE__=1`, 63 | `-D__GNUC_MINOR__=2`, 64 | `-D__GNUC_PATCHLEVEL__=1`, 65 | `-D__GNUC__=4`, 66 | `-D__GNUG__=4`, 67 | `-D__GXX_ABI_VERSION=1002`, 68 | `-D__GXX_EXPERIMENTAL_CXX0X__=1`, 69 | `-D__GXX_RTTI=1`, 70 | `-D__GXX_WEAK__=1`, 71 | `-D__INT16_TYPE__=short`, 72 | `-D__INT32_TYPE__=int`, 73 | `-D__INT64_C_SUFFIX__=L`, 74 | `-D__INT64_TYPE__=long int`, 75 | `-D__INT8_TYPE__=char`, 76 | `-D__INTMAX_MAX__=9223372036854775807L`, 77 | `-D__INTMAX_TYPE__=long int`, 78 | `-D__INTMAX_WIDTH__=64`, 79 | `-D__INTPTR_TYPE__=long int`, 80 | `-D__INTPTR_WIDTH__=64`, 81 | `-D__INT_MAX__=2147483647`, 82 | `-D__LDBL_DENORM_MIN__=3.64519953188247460253e-4951L`, 83 | `-D__LDBL_DIG__=18`, 84 | `-D__LDBL_EPSILON__=1.08420217248550443401e-19L`, 85 | `-D__LDBL_HAS_DENORM__=1`, 86 | `-D__LDBL_HAS_INFINITY__=1`, 87 | `-D__LDBL_HAS_QUIET_NAN__=1`, 88 | `-D__LDBL_MANT_DIG__=64`, 89 | `-D__LDBL_MAX_10_EXP__=4932`, 90 | `-D__LDBL_MAX_EXP__=16384`, 91 | `-D__LDBL_MAX__=1.18973149535723176502e+4932L`, 92 | `-D__LDBL_MIN_10_EXP__=(-4931)`, 93 | `-D__LDBL_MIN_EXP__=(-16381)`, 94 | `-D__LDBL_MIN__=3.36210314311209350626e-4932L`, 95 | `-D__LITTLE_ENDIAN__=1`, 96 | `-D__LONG_LONG_MAX__=9223372036854775807LL`, 97 | `-D__LONG_MAX__=9223372036854775807L`, 98 | `-D__LP64__=1`, 99 | `-D__MMX__=1`, 100 | `-D__NO_INLINE__=1`, 101 | `-D__NO_MATH_INLINES=1`, 102 | `-D__ORDER_BIG_ENDIAN__=4321`, 103 | `-D__ORDER_LITTLE_ENDIAN__=1234`, 104 | `-D__ORDER_PDP_ENDIAN__=3412`, 105 | `-D__POINTER_WIDTH__=64`, 106 | `-D__PRAGMA_REDEFINE_EXTNAME=1`, 107 | `-D__PTRDIFF_TYPE__=long int`, 108 | `-D__PTRDIFF_WIDTH__=64`, 109 | `-D__REGISTER_PREFIX__=`, 110 | `-D__SCHAR_MAX__=127`, 111 | `-D__SHRT_MAX__=32767`, 112 | `-D__SIG_ATOMIC_WIDTH__=32`, 113 | `-D__SIZEOF_DOUBLE__=8`, 114 | `-D__SIZEOF_FLOAT__=4`, 115 | `-D__SIZEOF_INT128__=16`, 116 | `-D__SIZEOF_INT__=4`, 117 | `-D__SIZEOF_LONG_DOUBLE__=16`, 118 | `-D__SIZEOF_LONG_LONG__=8`, 119 | `-D__SIZEOF_LONG__=8`, 120 | `-D__SIZEOF_POINTER__=8`, 121 | `-D__SIZEOF_PTRDIFF_T__=8`, 122 | `-D__SIZEOF_SHORT__=2`, 123 | `-D__SIZEOF_SIZE_T__=8`, 124 | `-D__SIZEOF_WCHAR_T__=4`, 125 | `-D__SIZEOF_WINT_T__=4`, 126 | `-D__SIZE_MAX__=18446744073709551615UL`, 127 | `-D__SIZE_TYPE__=long unsigned int`, 128 | `-D__SIZE_WIDTH__=64`, 129 | `-D__SSE2_MATH__=1`, 130 | `-D__SSE2__=1`, 131 | `-D__SSE_MATH__=1`, 132 | `-D__SSE__=1`, 133 | `-D__STDC_HOSTED__=1`, 134 | `-D__STDC_UTF_16__=1`, 135 | `-D__STDC_UTF_32__=1`, 136 | `-D__STDC__=1`, 137 | `-D__UINTMAX_TYPE__=long unsigned int`, 138 | `-D__USER_LABEL_PREFIX__=`, 139 | `-D__VERSION__="4.2.1 Compatible Clang 3.4 "`, 140 | `-D__WCHAR_MAX__=2147483647`, 141 | `-D__WCHAR_TYPE__=int`, 142 | `-D__WCHAR_WIDTH__=32`, 143 | `-D__WINT_TYPE__=unsigned int`, 144 | `-D__WINT_UNSIGNED__=1`, 145 | `-D__WINT_WIDTH__=32`, 146 | `-D__amd64=1`, 147 | `-D__amd64__=1`, 148 | `-D__clang__=1`, 149 | `-D__clang_major__=3`, 150 | `-D__clang_minor__=4`, 151 | `-D__clang_patchlevel__=0`, 152 | `-D__clang_version__="3.4 "`, 153 | `-D__cplusplus=201103L`, 154 | `-D__gnu_linux__=1`, 155 | `-D__k8=1`, 156 | `-D__k8__=1`, 157 | `-D__linux=1`, 158 | `-D__linux__=1`, 159 | `-D__llvm__=1`, 160 | `-D__private_extern__=extern`, 161 | `-D__tune_k8__=1`, 162 | `-D__unix=1`, 163 | `-D__unix__=1`, 164 | `-D__x86_64=1`, 165 | `-D__x86_64__=1`, 166 | `-Dlinux=1`, 167 | `-Dunix=1`, 168 | ]; 169 | -------------------------------------------------------------------------------- /defines_gcc4_7_1.d: -------------------------------------------------------------------------------- 1 | immutable defines = [ 2 | `-D__DBL_MIN_EXP__=(-1021)`, 3 | `-D__UINT_LEAST16_MAX__=65535`, 4 | `-D__ATOMIC_ACQUIRE=2`, 5 | `-D__FLT_MIN__=1.17549435082228750797e-38F`, 6 | `-D__UINT_LEAST8_TYPE__=unsigned char`, 7 | `-D__INTMAX_C(c)=c ## L`, 8 | `-D__CHAR_BIT__=8`, 9 | `-D__UINT8_MAX__=255`, 10 | `-D__WINT_MAX__=4294967295U`, 11 | `-D__ORDER_LITTLE_ENDIAN__=1234`, 12 | `-D__SIZE_MAX__=18446744073709551615UL`, 13 | `-D__WCHAR_MAX__=2147483647`, 14 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1=1`, 15 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2=1`, 16 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4=1`, 17 | `-D__DBL_DENORM_MIN__=((double)4.94065645841246544177e-324L)`, 18 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8=1`, 19 | `-D__GCC_ATOMIC_CHAR_LOCK_FREE=2`, 20 | `-D__FLT_EVAL_METHOD__=0`, 21 | `-D__unix__=1`, 22 | `-D__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2`, 23 | `-D__x86_64=1`, 24 | `-D__UINT_FAST64_MAX__=18446744073709551615UL`, 25 | `-D__SIG_ATOMIC_TYPE__=int`, 26 | `-D__DBL_MIN_10_EXP__=(-307)`, 27 | `-D__FINITE_MATH_ONLY__=0`, 28 | `-D__GNUC_PATCHLEVEL__=1`, 29 | `-D__UINT_FAST8_MAX__=255`, 30 | `-D__DEC64_MAX_EXP__=385`, 31 | `-D__INT8_C(c)=c`, 32 | `-D__UINT_LEAST64_MAX__=18446744073709551615UL`, 33 | `-D__SHRT_MAX__=32767`, 34 | `-D__LDBL_MAX__=1.18973149535723176502e+4932L`, 35 | `-D__UINT_LEAST8_MAX__=255`, 36 | `-D__GCC_ATOMIC_BOOL_LOCK_FREE=2`, 37 | `-D__UINTMAX_TYPE__=long unsigned int`, 38 | `-D__linux=1`, 39 | `-D__DEC32_EPSILON__=1E-6DF`, 40 | `-D__unix=1`, 41 | `-D__UINT32_MAX__=4294967295U`, 42 | `-D__LDBL_MAX_EXP__=16384`, 43 | `-D__WINT_MIN__=0U`, 44 | `-D__linux__=1`, 45 | `-D__SCHAR_MAX__=127`, 46 | `-D__WCHAR_MIN__=(-__WCHAR_MAX__ - 1)`, 47 | `-D__INT64_C(c)=c ## L`, 48 | `-D__DBL_DIG__=15`, 49 | `-D__GCC_ATOMIC_POINTER_LOCK_FREE=2`, 50 | `-D__SIZEOF_INT__=4`, 51 | `-D__SIZEOF_POINTER__=8`, 52 | `-D__USER_LABEL_PREFIX__=`, 53 | `-D__STDC_HOSTED__=1`, 54 | `-D__LDBL_HAS_INFINITY__=1`, 55 | `-D__FLT_EPSILON__=1.19209289550781250000e-7F`, 56 | `-D__LDBL_MIN__=3.36210314311209350626e-4932L`, 57 | `-D__STDC_UTF_16__=1`, 58 | `-D__DEC32_MAX__=9.999999E96DF`, 59 | `-D__INT32_MAX__=2147483647`, 60 | `-D__SIZEOF_LONG__=8`, 61 | `-D__UINT16_C(c)=c`, 62 | `-D__DECIMAL_DIG__=21`, 63 | `-D__gnu_linux__=1`, 64 | `-D__LDBL_HAS_QUIET_NAN__=1`, 65 | `-D__GNUC__=4`, 66 | `-D__MMX__=1`, 67 | `-D__FLT_HAS_DENORM__=1`, 68 | `-D__SIZEOF_LONG_DOUBLE__=16`, 69 | `-D__BIGGEST_ALIGNMENT__=16`, 70 | `-D__DBL_MAX__=((double)1.79769313486231570815e+308L)`, 71 | `-D__INT_FAST32_MAX__=9223372036854775807L`, 72 | `-D__DBL_HAS_INFINITY__=1`, 73 | `-D__DEC32_MIN_EXP__=(-94)`, 74 | `-D__INT_FAST16_TYPE__=long int`, 75 | `-D__LDBL_HAS_DENORM__=1`, 76 | `-D__DEC128_MAX__=9.999999999999999999999999999999999E6144DL`, 77 | `-D__INT_LEAST32_MAX__=2147483647`, 78 | `-D__DEC32_MIN__=1E-95DF`, 79 | `-D__DBL_MAX_EXP__=1024`, 80 | `-D__DEC128_EPSILON__=1E-33DL`, 81 | `-D__SSE2_MATH__=1`, 82 | `-D__PTRDIFF_MAX__=9223372036854775807L`, 83 | `-D__amd64=1`, 84 | `-D__LONG_LONG_MAX__=9223372036854775807LL`, 85 | `-D__SIZEOF_SIZE_T__=8`, 86 | `-D__SIZEOF_WINT_T__=4`, 87 | `-D__GCC_HAVE_DWARF2_CFI_ASM=1`, 88 | `-D__GXX_ABI_VERSION=1002`, 89 | `-D__FLT_MIN_EXP__=(-125)`, 90 | `-D__INT_FAST64_TYPE__=long int`, 91 | `-D__DBL_MIN__=((double)2.22507385850720138309e-308L)`, 92 | `-D__LP64__=1`, 93 | `-D__DECIMAL_BID_FORMAT__=1`, 94 | `-D__DEC128_MIN__=1E-6143DL`, 95 | `-D__REGISTER_PREFIX__=`, 96 | `-D__UINT16_MAX__=65535`, 97 | `-D__DBL_HAS_DENORM__=1`, 98 | `-D__UINT8_TYPE__=unsigned char`, 99 | `-D__NO_INLINE__=1`, 100 | `-D__FLT_MANT_DIG__=24`, 101 | `-D__VERSION__="4.7.1"`, 102 | `-D__UINT64_C(c)=c ## UL`, 103 | `-D__GCC_ATOMIC_INT_LOCK_FREE=2`, 104 | `-D__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__`, 105 | `-D__INT32_C(c)=c`, 106 | `-D__DEC64_EPSILON__=1E-15DD`, 107 | `-D__ORDER_PDP_ENDIAN__=3412`, 108 | `-D__DEC128_MIN_EXP__=(-6142)`, 109 | `-D__INT_FAST32_TYPE__=long int`, 110 | `-D__UINT_LEAST16_TYPE__=short unsigned int`, 111 | `-Dunix=1`, 112 | `-D__INT16_MAX__=32767`, 113 | `-D__SIZE_TYPE__=long unsigned int`, 114 | `-D__UINT64_MAX__=18446744073709551615UL`, 115 | `-D__INT8_TYPE__=signed char`, 116 | `-D__ELF__=1`, 117 | `-D__FLT_RADIX__=2`, 118 | `-D__INT_LEAST16_TYPE__=short int`, 119 | `-D__LDBL_EPSILON__=1.08420217248550443401e-19L`, 120 | `-D__UINTMAX_C(c)=c ## UL`, 121 | `-D__SSE_MATH__=1`, 122 | `-D__k8=1`, 123 | `-D__SIG_ATOMIC_MAX__=2147483647`, 124 | `-D__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2`, 125 | `-D__SIZEOF_PTRDIFF_T__=8`, 126 | `-D__x86_64__=1`, 127 | `-D__DEC32_SUBNORMAL_MIN__=0.000001E-95DF`, 128 | `-D__INT_FAST16_MAX__=9223372036854775807L`, 129 | `-D__UINT_FAST32_MAX__=18446744073709551615UL`, 130 | `-D__UINT_LEAST64_TYPE__=long unsigned int`, 131 | `-D__FLT_HAS_QUIET_NAN__=1`, 132 | `-D__FLT_MAX_10_EXP__=38`, 133 | `-D__LONG_MAX__=9223372036854775807L`, 134 | `-D__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL`, 135 | `-D__FLT_HAS_INFINITY__=1`, 136 | `-D__UINT_FAST16_TYPE__=long unsigned int`, 137 | `-D__DEC64_MAX__=9.999999999999999E384DD`, 138 | `-D__CHAR16_TYPE__=short unsigned int`, 139 | `-D__PRAGMA_REDEFINE_EXTNAME=1`, 140 | `-D__INT_LEAST16_MAX__=32767`, 141 | `-D__DEC64_MANT_DIG__=16`, 142 | `-D__INT64_MAX__=9223372036854775807L`, 143 | `-D__UINT_LEAST32_MAX__=4294967295U`, 144 | `-D__GCC_ATOMIC_LONG_LOCK_FREE=2`, 145 | `-D__INT_LEAST64_TYPE__=long int`, 146 | `-D__INT16_TYPE__=short int`, 147 | `-D__INT_LEAST8_TYPE__=signed char`, 148 | `-D__STDC_VERSION__=201112L`, 149 | `-D__DEC32_MAX_EXP__=97`, 150 | `-D__INT_FAST8_MAX__=127`, 151 | `-D__INTPTR_MAX__=9223372036854775807L`, 152 | `-Dlinux=1`, 153 | `-D__SSE2__=1`, 154 | `-D__LDBL_MANT_DIG__=64`, 155 | `-D__DBL_HAS_QUIET_NAN__=1`, 156 | `-D__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)`, 157 | `-D__k8__=1`, 158 | `-D__INTPTR_TYPE__=long int`, 159 | `-D__UINT16_TYPE__=short unsigned int`, 160 | `-D__WCHAR_TYPE__=int`, 161 | `-D__SIZEOF_FLOAT__=4`, 162 | `-D__UINTPTR_MAX__=18446744073709551615UL`, 163 | `-D__DEC64_MIN_EXP__=(-382)`, 164 | `-D__INT_FAST64_MAX__=9223372036854775807L`, 165 | `-D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1`, 166 | `-D__FLT_DIG__=6`, 167 | `-D__UINT_FAST64_TYPE__=long unsigned int`, 168 | `-D__INT_MAX__=2147483647`, 169 | `-D__amd64__=1`, 170 | `-D__INT64_TYPE__=long int`, 171 | `-D__FLT_MAX_EXP__=128`, 172 | `-D__ORDER_BIG_ENDIAN__=4321`, 173 | `-D__DBL_MANT_DIG__=53`, 174 | `-D__INT_LEAST64_MAX__=9223372036854775807L`, 175 | `-D__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2`, 176 | `-D__DEC64_MIN__=1E-383DD`, 177 | `-D__WINT_TYPE__=unsigned int`, 178 | `-D__UINT_LEAST32_TYPE__=unsigned int`, 179 | `-D__SIZEOF_SHORT__=2`, 180 | `-D__SSE__=1`, 181 | `-D__LDBL_MIN_EXP__=(-16381)`, 182 | `-D__INT_LEAST8_MAX__=127`, 183 | `-D__SIZEOF_INT128__=16`, 184 | `-D__LDBL_MAX_10_EXP__=4932`, 185 | `-D__ATOMIC_RELAXED=0`, 186 | `-D__DBL_EPSILON__=((double)2.22044604925031308085e-16L)`, 187 | `-D_LP64=1`, 188 | `-D__UINT8_C(c)=c`, 189 | `-D__INT_LEAST32_TYPE__=int`, 190 | `-D__SIZEOF_WCHAR_T__=4`, 191 | `-D__UINT64_TYPE__=long unsigned int`, 192 | `-D__INT_FAST8_TYPE__=signed char`, 193 | `-D__GNUC_STDC_INLINE__=1`, 194 | `-D__DBL_DECIMAL_DIG__=17`, 195 | `-D__STDC_UTF_32__=1`, 196 | `-D__DEC_EVAL_METHOD__=2`, 197 | `-D__UINT32_C(c)=c ## U`, 198 | `-D__INTMAX_MAX__=9223372036854775807L`, 199 | `-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__`, 200 | `-D__FLT_DENORM_MIN__=1.40129846432481707092e-45F`, 201 | `-D__INT8_MAX__=127`, 202 | `-D__UINT_FAST32_TYPE__=long unsigned int`, 203 | `-D__CHAR32_TYPE__=unsigned int`, 204 | `-D__FLT_MAX__=3.40282346638528859812e+38F`, 205 | `-D__INT32_TYPE__=int`, 206 | `-D__SIZEOF_DOUBLE__=8`, 207 | `-D__FLT_MIN_10_EXP__=(-37)`, 208 | `-D__INTMAX_TYPE__=long int`, 209 | `-D__DEC128_MAX_EXP__=6145`, 210 | `-D__ATOMIC_CONSUME=1`, 211 | `-D__GNUC_MINOR__=7`, 212 | `-D__UINTMAX_MAX__=18446744073709551615UL`, 213 | `-D__DEC32_MANT_DIG__=7`, 214 | `-D__DBL_MAX_10_EXP__=308`, 215 | `-D__LDBL_DENORM_MIN__=3.64519953188247460253e-4951L`, 216 | `-D__INT16_C(c)=c`, 217 | `-D__STDC__=1`, 218 | `-D__PTRDIFF_TYPE__=long int`, 219 | `-D__ATOMIC_SEQ_CST=5`, 220 | `-D__UINT32_TYPE__=unsigned int`, 221 | `-D__UINTPTR_TYPE__=long unsigned int`, 222 | `-D__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD`, 223 | `-D__DEC128_MANT_DIG__=34`, 224 | `-D__LDBL_MIN_10_EXP__=(-4931)`, 225 | `-D__SIZEOF_LONG_LONG__=8`, 226 | `-D__GCC_ATOMIC_LLONG_LOCK_FREE=2`, 227 | `-D__LDBL_DIG__=18`, 228 | `-D__FLT_DECIMAL_DIG__=9`, 229 | `-D__UINT_FAST16_MAX__=18446744073709551615UL`, 230 | `-D__GCC_ATOMIC_SHORT_LOCK_FREE=2`, 231 | `-D__UINT_FAST8_TYPE__=unsigned char`, 232 | `-D__ATOMIC_ACQ_REL=4`, 233 | `-D__ATOMIC_RELEASE=3`, 234 | ]; 235 | -------------------------------------------------------------------------------- /defines_gcc4_8_1.d: -------------------------------------------------------------------------------- 1 | immutable defines = [ 2 | `-D__DBL_MIN_EXP__=(-1021)`, 3 | `-D__UINT_LEAST16_MAX__=65535`, 4 | `-D__ATOMIC_ACQUIRE=2`, 5 | `-D__FLT_MIN__=1.17549435082228750797e-38F`, 6 | `-D__UINT_LEAST8_TYPE__=unsigned char`, 7 | `-D__INTMAX_C(c)=c ## L`, 8 | `-D__CHAR_BIT__=8`, 9 | `-D__UINT8_MAX__=255`, 10 | `-D__WINT_MAX__=4294967295U`, 11 | `-D__ORDER_LITTLE_ENDIAN__=1234`, 12 | `-D__SIZE_MAX__=18446744073709551615UL`, 13 | `-D__WCHAR_MAX__=2147483647`, 14 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1=1`, 15 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2=1`, 16 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4=1`, 17 | `-D__DBL_DENORM_MIN__=((double)4.94065645841246544177e-324L)`, 18 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8=1`, 19 | `-D__GCC_ATOMIC_CHAR_LOCK_FREE=2`, 20 | `-D__FLT_EVAL_METHOD__=0`, 21 | `-D__unix__=1`, 22 | `-D__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2`, 23 | `-D__x86_64=1`, 24 | `-D__UINT_FAST64_MAX__=18446744073709551615UL`, 25 | `-D__SIG_ATOMIC_TYPE__=int`, 26 | `-D__DBL_MIN_10_EXP__=(-307)`, 27 | `-D__FINITE_MATH_ONLY__=0`, 28 | `-D__GNUC_PATCHLEVEL__=1`, 29 | `-D__UINT_FAST8_MAX__=255`, 30 | `-D__DEC64_MAX_EXP__=385`, 31 | `-D__INT8_C(c)=c`, 32 | `-D__UINT_LEAST64_MAX__=18446744073709551615UL`, 33 | `-D__SHRT_MAX__=32767`, 34 | `-D__LDBL_MAX__=1.18973149535723176502e+4932L`, 35 | `-D__UINT_LEAST8_MAX__=255`, 36 | `-D__GCC_ATOMIC_BOOL_LOCK_FREE=2`, 37 | `-D__UINTMAX_TYPE__=long unsigned int`, 38 | `-D__linux=1`, 39 | `-D__DEC32_EPSILON__=1E-6DF`, 40 | `-D__unix=1`, 41 | `-D__UINT32_MAX__=4294967295U`, 42 | `-D__LDBL_MAX_EXP__=16384`, 43 | `-D__WINT_MIN__=0U`, 44 | `-D__linux__=1`, 45 | `-D__SCHAR_MAX__=127`, 46 | `-D__WCHAR_MIN__=(-__WCHAR_MAX__ - 1)`, 47 | `-D__INT64_C(c)=c ## L`, 48 | `-D__DBL_DIG__=15`, 49 | `-D__GCC_ATOMIC_POINTER_LOCK_FREE=2`, 50 | `-D__SIZEOF_INT__=4`, 51 | `-D__SIZEOF_POINTER__=8`, 52 | `-D__USER_LABEL_PREFIX__=`, 53 | `-D__STDC_HOSTED__=1`, 54 | `-D__LDBL_HAS_INFINITY__=1`, 55 | `-D__FLT_EPSILON__=1.19209289550781250000e-7F`, 56 | `-D__LDBL_MIN__=3.36210314311209350626e-4932L`, 57 | `-D__STDC_UTF_16__=1`, 58 | `-D__DEC32_MAX__=9.999999E96DF`, 59 | `-D__INT32_MAX__=2147483647`, 60 | `-D__SIZEOF_LONG__=8`, 61 | `-D__UINT16_C(c)=c`, 62 | `-D__DECIMAL_DIG__=21`, 63 | `-D__gnu_linux__=1`, 64 | `-D__LDBL_HAS_QUIET_NAN__=1`, 65 | `-D__GNUC__=4`, 66 | `-D__MMX__=1`, 67 | `-D__FLT_HAS_DENORM__=1`, 68 | `-D__SIZEOF_LONG_DOUBLE__=16`, 69 | `-D__BIGGEST_ALIGNMENT__=16`, 70 | `-D__DBL_MAX__=((double)1.79769313486231570815e+308L)`, 71 | `-D__INT_FAST32_MAX__=9223372036854775807L`, 72 | `-D__DBL_HAS_INFINITY__=1`, 73 | `-D__DEC32_MIN_EXP__=(-94)`, 74 | `-D__INT_FAST16_TYPE__=long int`, 75 | `-D__LDBL_HAS_DENORM__=1`, 76 | `-D__DEC128_MAX__=9.999999999999999999999999999999999E6144DL`, 77 | `-D__INT_LEAST32_MAX__=2147483647`, 78 | `-D__DEC32_MIN__=1E-95DF`, 79 | `-D__DBL_MAX_EXP__=1024`, 80 | `-D__DEC128_EPSILON__=1E-33DL`, 81 | `-D__SSE2_MATH__=1`, 82 | `-D__ATOMIC_HLE_RELEASE=131072`, 83 | `-D__PTRDIFF_MAX__=9223372036854775807L`, 84 | `-D__amd64=1`, 85 | `-D__ATOMIC_HLE_ACQUIRE=65536`, 86 | `-D__LONG_LONG_MAX__=9223372036854775807LL`, 87 | `-D__SIZEOF_SIZE_T__=8`, 88 | `-D__SIZEOF_WINT_T__=4`, 89 | `-D__GXX_ABI_VERSION=1002`, 90 | `-D__FLT_MIN_EXP__=(-125)`, 91 | `-D__INT_FAST64_TYPE__=long int`, 92 | `-D__DBL_MIN__=((double)2.22507385850720138309e-308L)`, 93 | `-D__LP64__=1`, 94 | `-D__DECIMAL_BID_FORMAT__=1`, 95 | `-D__DEC128_MIN__=1E-6143DL`, 96 | `-D__REGISTER_PREFIX__=`, 97 | `-D__UINT16_MAX__=65535`, 98 | `-D__DBL_HAS_DENORM__=1`, 99 | `-D__UINT8_TYPE__=unsigned char`, 100 | `-D__NO_INLINE__=1`, 101 | `-D__FLT_MANT_DIG__=24`, 102 | `-D__VERSION__="4.8.1"`, 103 | `-D__UINT64_C(c)=c ## UL`, 104 | `-D__GCC_ATOMIC_INT_LOCK_FREE=2`, 105 | `-D__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__`, 106 | `-D__INT32_C(c)=c`, 107 | `-D__DEC64_EPSILON__=1E-15DD`, 108 | `-D__ORDER_PDP_ENDIAN__=3412`, 109 | `-D__DEC128_MIN_EXP__=(-6142)`, 110 | `-D__INT_FAST32_TYPE__=long int`, 111 | `-D__UINT_LEAST16_TYPE__=short unsigned int`, 112 | `-Dunix=1`, 113 | `-D__INT16_MAX__=32767`, 114 | `-D__SIZE_TYPE__=long unsigned int`, 115 | `-D__UINT64_MAX__=18446744073709551615UL`, 116 | `-D__INT8_TYPE__=signed char`, 117 | `-D__ELF__=1`, 118 | `-D__FLT_RADIX__=2`, 119 | `-D__INT_LEAST16_TYPE__=short int`, 120 | `-D__LDBL_EPSILON__=1.08420217248550443401e-19L`, 121 | `-D__UINTMAX_C(c)=c ## UL`, 122 | `-D__SSE_MATH__=1`, 123 | `-D__k8=1`, 124 | `-D__SIG_ATOMIC_MAX__=2147483647`, 125 | `-D__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2`, 126 | `-D__SIZEOF_PTRDIFF_T__=8`, 127 | `-D__x86_64__=1`, 128 | `-D__DEC32_SUBNORMAL_MIN__=0.000001E-95DF`, 129 | `-D__INT_FAST16_MAX__=9223372036854775807L`, 130 | `-D__UINT_FAST32_MAX__=18446744073709551615UL`, 131 | `-D__UINT_LEAST64_TYPE__=long unsigned int`, 132 | `-D__FLT_HAS_QUIET_NAN__=1`, 133 | `-D__FLT_MAX_10_EXP__=38`, 134 | `-D__LONG_MAX__=9223372036854775807L`, 135 | `-D__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL`, 136 | `-D__FLT_HAS_INFINITY__=1`, 137 | `-D__UINT_FAST16_TYPE__=long unsigned int`, 138 | `-D__DEC64_MAX__=9.999999999999999E384DD`, 139 | `-D__CHAR16_TYPE__=short unsigned int`, 140 | `-D__PRAGMA_REDEFINE_EXTNAME=1`, 141 | `-D__INT_LEAST16_MAX__=32767`, 142 | `-D__DEC64_MANT_DIG__=16`, 143 | `-D__INT64_MAX__=9223372036854775807L`, 144 | `-D__UINT_LEAST32_MAX__=4294967295U`, 145 | `-D__GCC_ATOMIC_LONG_LOCK_FREE=2`, 146 | `-D__INT_LEAST64_TYPE__=long int`, 147 | `-D__INT16_TYPE__=short int`, 148 | `-D__INT_LEAST8_TYPE__=signed char`, 149 | `-D__STDC_VERSION__=201112L`, 150 | `-D__DEC32_MAX_EXP__=97`, 151 | `-D__INT_FAST8_MAX__=127`, 152 | `-D__INTPTR_MAX__=9223372036854775807L`, 153 | `-Dlinux=1`, 154 | `-D__SSE2__=1`, 155 | `-D__LDBL_MANT_DIG__=64`, 156 | `-D__DBL_HAS_QUIET_NAN__=1`, 157 | `-D__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)`, 158 | `-D__code_model_small__=1`, 159 | `-D__k8__=1`, 160 | `-D__INTPTR_TYPE__=long int`, 161 | `-D__UINT16_TYPE__=short unsigned int`, 162 | `-D__WCHAR_TYPE__=int`, 163 | `-D__SIZEOF_FLOAT__=4`, 164 | `-D__UINTPTR_MAX__=18446744073709551615UL`, 165 | `-D__DEC64_MIN_EXP__=(-382)`, 166 | `-D__INT_FAST64_MAX__=9223372036854775807L`, 167 | `-D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1`, 168 | `-D__FLT_DIG__=6`, 169 | `-D__UINT_FAST64_TYPE__=long unsigned int`, 170 | `-D__INT_MAX__=2147483647`, 171 | `-D__amd64__=1`, 172 | `-D__INT64_TYPE__=long int`, 173 | `-D__FLT_MAX_EXP__=128`, 174 | `-D__ORDER_BIG_ENDIAN__=4321`, 175 | `-D__DBL_MANT_DIG__=53`, 176 | `-D__INT_LEAST64_MAX__=9223372036854775807L`, 177 | `-D__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2`, 178 | `-D__DEC64_MIN__=1E-383DD`, 179 | `-D__WINT_TYPE__=unsigned int`, 180 | `-D__UINT_LEAST32_TYPE__=unsigned int`, 181 | `-D__SIZEOF_SHORT__=2`, 182 | `-D__SSE__=1`, 183 | `-D__LDBL_MIN_EXP__=(-16381)`, 184 | `-D__INT_LEAST8_MAX__=127`, 185 | `-D__SIZEOF_INT128__=16`, 186 | `-D__LDBL_MAX_10_EXP__=4932`, 187 | `-D__ATOMIC_RELAXED=0`, 188 | `-D__DBL_EPSILON__=((double)2.22044604925031308085e-16L)`, 189 | `-D_LP64=1`, 190 | `-D__UINT8_C(c)=c`, 191 | `-D__INT_LEAST32_TYPE__=int`, 192 | `-D__SIZEOF_WCHAR_T__=4`, 193 | `-D__UINT64_TYPE__=long unsigned int`, 194 | `-D__INT_FAST8_TYPE__=signed char`, 195 | `-D__GNUC_STDC_INLINE__=1`, 196 | `-D__DBL_DECIMAL_DIG__=17`, 197 | `-D__STDC_UTF_32__=1`, 198 | `-D__FXSR__=1`, 199 | `-D__DEC_EVAL_METHOD__=2`, 200 | `-D__UINT32_C(c)=c ## U`, 201 | `-D__INTMAX_MAX__=9223372036854775807L`, 202 | `-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__`, 203 | `-D__FLT_DENORM_MIN__=1.40129846432481707092e-45F`, 204 | `-D__INT8_MAX__=127`, 205 | `-D__UINT_FAST32_TYPE__=long unsigned int`, 206 | `-D__CHAR32_TYPE__=unsigned int`, 207 | `-D__FLT_MAX__=3.40282346638528859812e+38F`, 208 | `-D__INT32_TYPE__=int`, 209 | `-D__SIZEOF_DOUBLE__=8`, 210 | `-D__FLT_MIN_10_EXP__=(-37)`, 211 | `-D__INTMAX_TYPE__=long int`, 212 | `-D__DEC128_MAX_EXP__=6145`, 213 | `-D__ATOMIC_CONSUME=1`, 214 | `-D__GNUC_MINOR__=8`, 215 | `-D__UINTMAX_MAX__=18446744073709551615UL`, 216 | `-D__DEC32_MANT_DIG__=7`, 217 | `-D__DBL_MAX_10_EXP__=308`, 218 | `-D__LDBL_DENORM_MIN__=3.64519953188247460253e-4951L`, 219 | `-D__INT16_C(c)=c`, 220 | `-D__STDC__=1`, 221 | `-D__PTRDIFF_TYPE__=long int`, 222 | `-D__ATOMIC_SEQ_CST=5`, 223 | `-D__UINT32_TYPE__=unsigned int`, 224 | `-D__UINTPTR_TYPE__=long unsigned int`, 225 | `-D__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD`, 226 | `-D__DEC128_MANT_DIG__=34`, 227 | `-D__LDBL_MIN_10_EXP__=(-4931)`, 228 | `-D__SIZEOF_LONG_LONG__=8`, 229 | `-D__GCC_ATOMIC_LLONG_LOCK_FREE=2`, 230 | `-D__LDBL_DIG__=18`, 231 | `-D__FLT_DECIMAL_DIG__=9`, 232 | `-D__UINT_FAST16_MAX__=18446744073709551615UL`, 233 | `-D__GCC_ATOMIC_SHORT_LOCK_FREE=2`, 234 | `-D__UINT_FAST8_TYPE__=unsigned char`, 235 | `-D__ATOMIC_ACQ_REL=4`, 236 | `-D__ATOMIC_RELEASE=3`, 237 | ]; 238 | -------------------------------------------------------------------------------- /defines_gxx4_7_1.d: -------------------------------------------------------------------------------- 1 | immutable xxdefines = [ 2 | `-D__DBL_MIN_EXP__=(-1021)`, 3 | `-D__UINT_LEAST16_MAX__=65535`, 4 | `-D__ATOMIC_ACQUIRE=2`, 5 | `-D__FLT_MIN__=1.17549435082228750797e-38F`, 6 | `-D__UINT_LEAST8_TYPE__=unsigned char`, 7 | `-D__INTMAX_C(c)=c ## L`, 8 | `-D__CHAR_BIT__=8`, 9 | `-D__UINT8_MAX__=255`, 10 | `-D__WINT_MAX__=4294967295U`, 11 | `-D__ORDER_LITTLE_ENDIAN__=1234`, 12 | `-D__SIZE_MAX__=18446744073709551615UL`, 13 | `-D__WCHAR_MAX__=2147483647`, 14 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1=1`, 15 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2=1`, 16 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4=1`, 17 | `-D__DBL_DENORM_MIN__=double(4.94065645841246544177e-324L)`, 18 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8=1`, 19 | `-D__GCC_ATOMIC_CHAR_LOCK_FREE=2`, 20 | `-D__FLT_EVAL_METHOD__=0`, 21 | `-D__unix__=1`, 22 | `-D__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2`, 23 | `-D__x86_64=1`, 24 | `-D__UINT_FAST64_MAX__=18446744073709551615UL`, 25 | `-D__SIG_ATOMIC_TYPE__=int`, 26 | `-D__DBL_MIN_10_EXP__=(-307)`, 27 | `-D__FINITE_MATH_ONLY__=0`, 28 | `-D__GNUC_PATCHLEVEL__=1`, 29 | `-D__UINT_FAST8_MAX__=255`, 30 | `-D__DEC64_MAX_EXP__=385`, 31 | `-D__INT8_C(c)=c`, 32 | `-D__UINT_LEAST64_MAX__=18446744073709551615UL`, 33 | `-D__SHRT_MAX__=32767`, 34 | `-D__LDBL_MAX__=1.18973149535723176502e+4932L`, 35 | `-D__UINT_LEAST8_MAX__=255`, 36 | `-D__GCC_ATOMIC_BOOL_LOCK_FREE=2`, 37 | `-D__UINTMAX_TYPE__=long unsigned int`, 38 | `-D__linux=1`, 39 | `-D__DEC32_EPSILON__=1E-6DF`, 40 | `-D__unix=1`, 41 | `-D__UINT32_MAX__=4294967295U`, 42 | `-D__GXX_EXPERIMENTAL_CXX0X__=1`, 43 | `-D__LDBL_MAX_EXP__=16384`, 44 | `-D__WINT_MIN__=0U`, 45 | `-D__linux__=1`, 46 | `-D__SCHAR_MAX__=127`, 47 | `-D__WCHAR_MIN__=(-__WCHAR_MAX__ - 1)`, 48 | `-D__INT64_C(c)=c ## L`, 49 | `-D__DBL_DIG__=15`, 50 | `-D__GCC_ATOMIC_POINTER_LOCK_FREE=2`, 51 | `-D__SIZEOF_INT__=4`, 52 | `-D__SIZEOF_POINTER__=8`, 53 | `-D__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2`, 54 | `-D__USER_LABEL_PREFIX__=`, 55 | `-D__STDC_HOSTED__=1`, 56 | `-D__LDBL_HAS_INFINITY__=1`, 57 | `-D__FLT_EPSILON__=1.19209289550781250000e-7F`, 58 | `-D__GXX_WEAK__=1`, 59 | `-D__LDBL_MIN__=3.36210314311209350626e-4932L`, 60 | `-D__DEC32_MAX__=9.999999E96DF`, 61 | `-D__INT32_MAX__=2147483647`, 62 | `-D__SIZEOF_LONG__=8`, 63 | `-D__UINT16_C(c)=c`, 64 | `-D__DECIMAL_DIG__=21`, 65 | `-D__gnu_linux__=1`, 66 | `-D__LDBL_HAS_QUIET_NAN__=1`, 67 | `-D__GNUC__=4`, 68 | `-D__GXX_RTTI=1`, 69 | `-D__MMX__=1`, 70 | `-D__FLT_HAS_DENORM__=1`, 71 | `-D__SIZEOF_LONG_DOUBLE__=16`, 72 | `-D__BIGGEST_ALIGNMENT__=16`, 73 | `-D__DBL_MAX__=double(1.79769313486231570815e+308L)`, 74 | `-D__INT_FAST32_MAX__=9223372036854775807L`, 75 | `-D__DBL_HAS_INFINITY__=1`, 76 | `-D__INT64_MAX__=9223372036854775807L`, 77 | `-D__DEC32_MIN_EXP__=(-94)`, 78 | `-D__INT_FAST16_TYPE__=long int`, 79 | `-D__LDBL_HAS_DENORM__=1`, 80 | `-D__cplusplus=201103L`, 81 | `-D__DEC128_MAX__=9.999999999999999999999999999999999E6144DL`, 82 | `-D__INT_LEAST32_MAX__=2147483647`, 83 | `-D__DEC32_MIN__=1E-95DF`, 84 | `-D__DBL_MAX_EXP__=1024`, 85 | `-D__DEC128_EPSILON__=1E-33DL`, 86 | `-D__SSE2_MATH__=1`, 87 | `-D__PTRDIFF_MAX__=9223372036854775807L`, 88 | `-D__amd64=1`, 89 | `-D__GNUG__=4`, 90 | `-D__LONG_LONG_MAX__=9223372036854775807LL`, 91 | `-D__SIZEOF_SIZE_T__=8`, 92 | `-D__SIZEOF_WINT_T__=4`, 93 | `-D__GCC_HAVE_DWARF2_CFI_ASM=1`, 94 | `-D__GXX_ABI_VERSION=1002`, 95 | `-D__FLT_MIN_EXP__=(-125)`, 96 | `-D__INT_FAST64_TYPE__=long int`, 97 | `-D__DBL_MIN__=double(2.22507385850720138309e-308L)`, 98 | `-D__LP64__=1`, 99 | `-D__DECIMAL_BID_FORMAT__=1`, 100 | `-D__DEC128_MIN__=1E-6143DL`, 101 | `-D__REGISTER_PREFIX__=`, 102 | `-D__UINT16_MAX__=65535`, 103 | `-D__DBL_HAS_DENORM__=1`, 104 | `-D__UINT8_TYPE__=unsigned char`, 105 | `-D__NO_INLINE__=1`, 106 | `-D__FLT_MANT_DIG__=24`, 107 | `-D__VERSION__="4.7.1"`, 108 | `-D__UINT64_C(c)=c ## UL`, 109 | `-D__GCC_ATOMIC_INT_LOCK_FREE=2`, 110 | `-D__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__`, 111 | `-D__INT32_C(c)=c`, 112 | `-D__DEC64_EPSILON__=1E-15DD`, 113 | `-D__ORDER_PDP_ENDIAN__=3412`, 114 | `-D__DEC128_MIN_EXP__=(-6142)`, 115 | `-D__INT_FAST32_TYPE__=long int`, 116 | `-D__UINT_LEAST16_TYPE__=short unsigned int`, 117 | `-Dunix=1`, 118 | `-D__INT16_MAX__=32767`, 119 | `-D__SIZE_TYPE__=long unsigned int`, 120 | `-D__UINT64_MAX__=18446744073709551615UL`, 121 | `-D__INT8_TYPE__=signed char`, 122 | `-D__ELF__=1`, 123 | `-D__FLT_RADIX__=2`, 124 | `-D__INT_LEAST16_TYPE__=short int`, 125 | `-D__LDBL_EPSILON__=1.08420217248550443401e-19L`, 126 | `-D__UINTMAX_C(c)=c ## UL`, 127 | `-D__k8=1`, 128 | `-D__SIG_ATOMIC_MAX__=2147483647`, 129 | `-D__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2`, 130 | `-D__SIZEOF_PTRDIFF_T__=8`, 131 | `-D__x86_64__=1`, 132 | `-D__DEC32_SUBNORMAL_MIN__=0.000001E-95DF`, 133 | `-D__INT_FAST16_MAX__=9223372036854775807L`, 134 | `-D__UINT_FAST32_MAX__=18446744073709551615UL`, 135 | `-D__UINT_LEAST64_TYPE__=long unsigned int`, 136 | `-D__FLT_HAS_QUIET_NAN__=1`, 137 | `-D__FLT_MAX_10_EXP__=38`, 138 | `-D__LONG_MAX__=9223372036854775807L`, 139 | `-D__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL`, 140 | `-D__FLT_HAS_INFINITY__=1`, 141 | `-D__UINT_FAST16_TYPE__=long unsigned int`, 142 | `-D__DEC64_MAX__=9.999999999999999E384DD`, 143 | `-D__CHAR16_TYPE__=short unsigned int`, 144 | `-D__PRAGMA_REDEFINE_EXTNAME=1`, 145 | `-D__INT_LEAST16_MAX__=32767`, 146 | `-D__DEC64_MANT_DIG__=16`, 147 | `-D__UINT_LEAST32_MAX__=4294967295U`, 148 | `-D__GCC_ATOMIC_LONG_LOCK_FREE=2`, 149 | `-D__INT_LEAST64_TYPE__=long int`, 150 | `-D__INT16_TYPE__=short int`, 151 | `-D__INT_LEAST8_TYPE__=signed char`, 152 | `-D__DEC32_MAX_EXP__=97`, 153 | `-D__INT_FAST8_MAX__=127`, 154 | `-D__INTPTR_MAX__=9223372036854775807L`, 155 | `-Dlinux=1`, 156 | `-D__SSE2__=1`, 157 | `-D__EXCEPTIONS=1`, 158 | `-D__LDBL_MANT_DIG__=64`, 159 | `-D__DBL_HAS_QUIET_NAN__=1`, 160 | `-D__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)`, 161 | `-D__k8__=1`, 162 | `-D__INTPTR_TYPE__=long int`, 163 | `-D__UINT16_TYPE__=short unsigned int`, 164 | `-D__WCHAR_TYPE__=int`, 165 | `-D__SIZEOF_FLOAT__=4`, 166 | `-D__UINTPTR_MAX__=18446744073709551615UL`, 167 | `-D__DEC64_MIN_EXP__=(-382)`, 168 | `-D__INT_FAST64_MAX__=9223372036854775807L`, 169 | `-D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1`, 170 | `-D__FLT_DIG__=6`, 171 | `-D__UINT_FAST64_TYPE__=long unsigned int`, 172 | `-D__INT_MAX__=2147483647`, 173 | `-D__amd64__=1`, 174 | `-D__INT64_TYPE__=long int`, 175 | `-D__FLT_MAX_EXP__=128`, 176 | `-D__ORDER_BIG_ENDIAN__=4321`, 177 | `-D__DBL_MANT_DIG__=53`, 178 | `-D__INT_LEAST64_MAX__=9223372036854775807L`, 179 | `-D__DEC64_MIN__=1E-383DD`, 180 | `-D__WINT_TYPE__=unsigned int`, 181 | `-D__UINT_LEAST32_TYPE__=unsigned int`, 182 | `-D__SIZEOF_SHORT__=2`, 183 | `-D__SSE__=1`, 184 | `-D__LDBL_MIN_EXP__=(-16381)`, 185 | `-D__INT_LEAST8_MAX__=127`, 186 | `-D__SIZEOF_INT128__=16`, 187 | `-D__LDBL_MAX_10_EXP__=4932`, 188 | `-D__ATOMIC_RELAXED=0`, 189 | `-D__DBL_EPSILON__=double(2.22044604925031308085e-16L)`, 190 | `-D_LP64=1`, 191 | `-D__UINT8_C(c)=c`, 192 | `-D__INT_LEAST32_TYPE__=int`, 193 | `-D__SIZEOF_WCHAR_T__=4`, 194 | `-D__UINT64_TYPE__=long unsigned int`, 195 | `-D__INT_FAST8_TYPE__=signed char`, 196 | `-D__GNUC_STDC_INLINE__=1`, 197 | `-D__DBL_DECIMAL_DIG__=17`, 198 | `-D__DEC_EVAL_METHOD__=2`, 199 | `-D__UINT32_C(c)=c ## U`, 200 | `-D__INTMAX_MAX__=9223372036854775807L`, 201 | `-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__`, 202 | `-D__FLT_DENORM_MIN__=1.40129846432481707092e-45F`, 203 | `-D__INT8_MAX__=127`, 204 | `-D__UINT_FAST32_TYPE__=long unsigned int`, 205 | `-D__CHAR32_TYPE__=unsigned int`, 206 | `-D__FLT_MAX__=3.40282346638528859812e+38F`, 207 | `-D__INT32_TYPE__=int`, 208 | `-D__SIZEOF_DOUBLE__=8`, 209 | `-D__INTMAX_TYPE__=long int`, 210 | `-D__DEC128_MAX_EXP__=6145`, 211 | `-D__ATOMIC_CONSUME=1`, 212 | `-D__GNUC_MINOR__=7`, 213 | `-D__UINTMAX_MAX__=18446744073709551615UL`, 214 | `-D__DEC32_MANT_DIG__=7`, 215 | `-D__DBL_MAX_10_EXP__=308`, 216 | `-D__LDBL_DENORM_MIN__=3.64519953188247460253e-4951L`, 217 | `-D__INT16_C(c)=c`, 218 | `-D__STDC__=1`, 219 | `-D__PTRDIFF_TYPE__=long int`, 220 | `-D__ATOMIC_SEQ_CST=5`, 221 | `-D__UINT32_TYPE__=unsigned int`, 222 | `-D__UINTPTR_TYPE__=long unsigned int`, 223 | `-D__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD`, 224 | `-D__DEC128_MANT_DIG__=34`, 225 | `-D__LDBL_MIN_10_EXP__=(-4931)`, 226 | `-D__SSE_MATH__=1`, 227 | `-D__SIZEOF_LONG_LONG__=8`, 228 | `-D__GCC_ATOMIC_LLONG_LOCK_FREE=2`, 229 | `-D__LDBL_DIG__=18`, 230 | `-D__FLT_DECIMAL_DIG__=9`, 231 | `-D__UINT_FAST16_MAX__=18446744073709551615UL`, 232 | `-D__FLT_MIN_10_EXP__=(-37)`, 233 | `-D__GCC_ATOMIC_SHORT_LOCK_FREE=2`, 234 | `-D__UINT_FAST8_TYPE__=unsigned char`, 235 | `-D_GNU_SOURCE=1`, 236 | `-D__ATOMIC_ACQ_REL=4`, 237 | `-D__ATOMIC_RELEASE=3`, 238 | ]; 239 | -------------------------------------------------------------------------------- /defines_gxx4_8_1.d: -------------------------------------------------------------------------------- 1 | immutable xxdefines = [ 2 | `-D__DBL_MIN_EXP__=(-1021)`, 3 | `-D__UINT_LEAST16_MAX__=65535`, 4 | `-D__ATOMIC_ACQUIRE=2`, 5 | `-D__FLT_MIN__=1.17549435082228750797e-38F`, 6 | `-D__UINT_LEAST8_TYPE__=unsigned char`, 7 | `-D__INTMAX_C(c)=c ## L`, 8 | `-D__CHAR_BIT__=8`, 9 | `-D__UINT8_MAX__=255`, 10 | `-D__WINT_MAX__=4294967295U`, 11 | `-D__ORDER_LITTLE_ENDIAN__=1234`, 12 | `-D__SIZE_MAX__=18446744073709551615UL`, 13 | `-D__WCHAR_MAX__=2147483647`, 14 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1=1`, 15 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2=1`, 16 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4=1`, 17 | `-D__DBL_DENORM_MIN__=double(4.94065645841246544177e-324L)`, 18 | `-D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8=1`, 19 | `-D__GCC_ATOMIC_CHAR_LOCK_FREE=2`, 20 | `-D__FLT_EVAL_METHOD__=0`, 21 | `-D__unix__=1`, 22 | `-D__GCC_ATOMIC_CHAR32_T_LOCK_FREE=2`, 23 | `-D__x86_64=1`, 24 | `-D__UINT_FAST64_MAX__=18446744073709551615UL`, 25 | `-D__SIG_ATOMIC_TYPE__=int`, 26 | `-D__DBL_MIN_10_EXP__=(-307)`, 27 | `-D__FINITE_MATH_ONLY__=0`, 28 | `-D__GNUC_PATCHLEVEL__=1`, 29 | `-D__UINT_FAST8_MAX__=255`, 30 | `-D__DEC64_MAX_EXP__=385`, 31 | `-D__INT8_C(c)=c`, 32 | `-D__UINT_LEAST64_MAX__=18446744073709551615UL`, 33 | `-D__SHRT_MAX__=32767`, 34 | `-D__LDBL_MAX__=1.18973149535723176502e+4932L`, 35 | `-D__UINT_LEAST8_MAX__=255`, 36 | `-D__GCC_ATOMIC_BOOL_LOCK_FREE=2`, 37 | `-D__UINTMAX_TYPE__=long unsigned int`, 38 | `-D__linux=1`, 39 | `-D__DEC32_EPSILON__=1E-6DF`, 40 | `-D__unix=1`, 41 | `-D__UINT32_MAX__=4294967295U`, 42 | `-D__GXX_EXPERIMENTAL_CXX0X__=1`, 43 | `-D__LDBL_MAX_EXP__=16384`, 44 | `-D__WINT_MIN__=0U`, 45 | `-D__linux__=1`, 46 | `-D__SCHAR_MAX__=127`, 47 | `-D__WCHAR_MIN__=(-__WCHAR_MAX__ - 1)`, 48 | `-D__INT64_C(c)=c ## L`, 49 | `-D__DBL_DIG__=15`, 50 | `-D__GCC_ATOMIC_POINTER_LOCK_FREE=2`, 51 | `-D__SIZEOF_INT__=4`, 52 | `-D__SIZEOF_POINTER__=8`, 53 | `-D__GCC_ATOMIC_CHAR16_T_LOCK_FREE=2`, 54 | `-D__USER_LABEL_PREFIX__=`, 55 | `-D__STDC_HOSTED__=1`, 56 | `-D__LDBL_HAS_INFINITY__=1`, 57 | `-D__FLT_EPSILON__=1.19209289550781250000e-7F`, 58 | `-D__GXX_WEAK__=1`, 59 | `-D__LDBL_MIN__=3.36210314311209350626e-4932L`, 60 | `-D__DEC32_MAX__=9.999999E96DF`, 61 | `-D__INT32_MAX__=2147483647`, 62 | `-D__SIZEOF_LONG__=8`, 63 | `-D__UINT16_C(c)=c`, 64 | `-D__DECIMAL_DIG__=21`, 65 | `-D__gnu_linux__=1`, 66 | `-D__LDBL_HAS_QUIET_NAN__=1`, 67 | `-D__GNUC__=4`, 68 | `-D__GXX_RTTI=1`, 69 | `-D__MMX__=1`, 70 | `-D__FLT_HAS_DENORM__=1`, 71 | `-D__SIZEOF_LONG_DOUBLE__=16`, 72 | `-D__BIGGEST_ALIGNMENT__=16`, 73 | `-D__DBL_MAX__=double(1.79769313486231570815e+308L)`, 74 | `-D__INT_FAST32_MAX__=9223372036854775807L`, 75 | `-D__DBL_HAS_INFINITY__=1`, 76 | `-D__INT64_MAX__=9223372036854775807L`, 77 | `-D__DEC32_MIN_EXP__=(-94)`, 78 | `-D__INT_FAST16_TYPE__=long int`, 79 | `-D__LDBL_HAS_DENORM__=1`, 80 | `-D__cplusplus=201103L`, 81 | `-D__DEC128_MAX__=9.999999999999999999999999999999999E6144DL`, 82 | `-D__INT_LEAST32_MAX__=2147483647`, 83 | `-D__DEC32_MIN__=1E-95DF`, 84 | `-D__DBL_MAX_EXP__=1024`, 85 | `-D__DEC128_EPSILON__=1E-33DL`, 86 | `-D__SSE2_MATH__=1`, 87 | `-D__ATOMIC_HLE_RELEASE=131072`, 88 | `-D__PTRDIFF_MAX__=9223372036854775807L`, 89 | `-D__amd64=1`, 90 | `-D__ATOMIC_HLE_ACQUIRE=65536`, 91 | `-D__GNUG__=4`, 92 | `-D__LONG_LONG_MAX__=9223372036854775807LL`, 93 | `-D__SIZEOF_SIZE_T__=8`, 94 | `-D__SIZEOF_WINT_T__=4`, 95 | `-D__GXX_ABI_VERSION=1002`, 96 | `-D__FLT_MIN_EXP__=(-125)`, 97 | `-D__INT_FAST64_TYPE__=long int`, 98 | `-D__DBL_MIN__=double(2.22507385850720138309e-308L)`, 99 | `-D__LP64__=1`, 100 | `-D__DECIMAL_BID_FORMAT__=1`, 101 | `-D__DEC128_MIN__=1E-6143DL`, 102 | `-D__REGISTER_PREFIX__=`, 103 | `-D__UINT16_MAX__=65535`, 104 | `-D__DBL_HAS_DENORM__=1`, 105 | `-D__UINT8_TYPE__=unsigned char`, 106 | `-D__NO_INLINE__=1`, 107 | `-D__FLT_MANT_DIG__=24`, 108 | `-D__VERSION__="4.8.1"`, 109 | `-D__UINT64_C(c)=c ## UL`, 110 | `-D__GCC_ATOMIC_INT_LOCK_FREE=2`, 111 | `-D__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__`, 112 | `-D__INT32_C(c)=c`, 113 | `-D__DEC64_EPSILON__=1E-15DD`, 114 | `-D__ORDER_PDP_ENDIAN__=3412`, 115 | `-D__DEC128_MIN_EXP__=(-6142)`, 116 | `-D__INT_FAST32_TYPE__=long int`, 117 | `-D__UINT_LEAST16_TYPE__=short unsigned int`, 118 | `-Dunix=1`, 119 | `-D__INT16_MAX__=32767`, 120 | `-D__SIZE_TYPE__=long unsigned int`, 121 | `-D__UINT64_MAX__=18446744073709551615UL`, 122 | `-D__INT8_TYPE__=signed char`, 123 | `-D__ELF__=1`, 124 | `-D__FLT_RADIX__=2`, 125 | `-D__INT_LEAST16_TYPE__=short int`, 126 | `-D__LDBL_EPSILON__=1.08420217248550443401e-19L`, 127 | `-D__UINTMAX_C(c)=c ## UL`, 128 | `-D__k8=1`, 129 | `-D__SIG_ATOMIC_MAX__=2147483647`, 130 | `-D__GCC_ATOMIC_WCHAR_T_LOCK_FREE=2`, 131 | `-D__SIZEOF_PTRDIFF_T__=8`, 132 | `-D__x86_64__=1`, 133 | `-D__DEC32_SUBNORMAL_MIN__=0.000001E-95DF`, 134 | `-D__INT_FAST16_MAX__=9223372036854775807L`, 135 | `-D__UINT_FAST32_MAX__=18446744073709551615UL`, 136 | `-D__UINT_LEAST64_TYPE__=long unsigned int`, 137 | `-D__FLT_HAS_QUIET_NAN__=1`, 138 | `-D__FLT_MAX_10_EXP__=38`, 139 | `-D__LONG_MAX__=9223372036854775807L`, 140 | `-D__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL`, 141 | `-D__FLT_HAS_INFINITY__=1`, 142 | `-D__UINT_FAST16_TYPE__=long unsigned int`, 143 | `-D__DEC64_MAX__=9.999999999999999E384DD`, 144 | `-D__CHAR16_TYPE__=short unsigned int`, 145 | `-D__PRAGMA_REDEFINE_EXTNAME=1`, 146 | `-D__INT_LEAST16_MAX__=32767`, 147 | `-D__DEC64_MANT_DIG__=16`, 148 | `-D__UINT_LEAST32_MAX__=4294967295U`, 149 | `-D__GCC_ATOMIC_LONG_LOCK_FREE=2`, 150 | `-D__INT_LEAST64_TYPE__=long int`, 151 | `-D__INT16_TYPE__=short int`, 152 | `-D__INT_LEAST8_TYPE__=signed char`, 153 | `-D__DEC32_MAX_EXP__=97`, 154 | `-D__INT_FAST8_MAX__=127`, 155 | `-D__INTPTR_MAX__=9223372036854775807L`, 156 | `-Dlinux=1`, 157 | `-D__SSE2__=1`, 158 | `-D__EXCEPTIONS=1`, 159 | `-D__LDBL_MANT_DIG__=64`, 160 | `-D__DBL_HAS_QUIET_NAN__=1`, 161 | `-D__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)`, 162 | `-D__code_model_small__=1`, 163 | `-D__k8__=1`, 164 | `-D__INTPTR_TYPE__=long int`, 165 | `-D__UINT16_TYPE__=short unsigned int`, 166 | `-D__WCHAR_TYPE__=int`, 167 | `-D__SIZEOF_FLOAT__=4`, 168 | `-D__UINTPTR_MAX__=18446744073709551615UL`, 169 | `-D__DEC64_MIN_EXP__=(-382)`, 170 | `-D__INT_FAST64_MAX__=9223372036854775807L`, 171 | `-D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1`, 172 | `-D__FLT_DIG__=6`, 173 | `-D__UINT_FAST64_TYPE__=long unsigned int`, 174 | `-D__INT_MAX__=2147483647`, 175 | `-D__amd64__=1`, 176 | `-D__INT64_TYPE__=long int`, 177 | `-D__FLT_MAX_EXP__=128`, 178 | `-D__ORDER_BIG_ENDIAN__=4321`, 179 | `-D__DBL_MANT_DIG__=53`, 180 | `-D__INT_LEAST64_MAX__=9223372036854775807L`, 181 | `-D__DEC64_MIN__=1E-383DD`, 182 | `-D__WINT_TYPE__=unsigned int`, 183 | `-D__UINT_LEAST32_TYPE__=unsigned int`, 184 | `-D__SIZEOF_SHORT__=2`, 185 | `-D__SSE__=1`, 186 | `-D__LDBL_MIN_EXP__=(-16381)`, 187 | `-D__INT_LEAST8_MAX__=127`, 188 | `-D__SIZEOF_INT128__=16`, 189 | `-D__LDBL_MAX_10_EXP__=4932`, 190 | `-D__ATOMIC_RELAXED=0`, 191 | `-D__DBL_EPSILON__=double(2.22044604925031308085e-16L)`, 192 | `-D_LP64=1`, 193 | `-D__UINT8_C(c)=c`, 194 | `-D__INT_LEAST32_TYPE__=int`, 195 | `-D__SIZEOF_WCHAR_T__=4`, 196 | `-D__UINT64_TYPE__=long unsigned int`, 197 | `-D__INT_FAST8_TYPE__=signed char`, 198 | `-D__GNUC_STDC_INLINE__=1`, 199 | `-D__DBL_DECIMAL_DIG__=17`, 200 | `-D__FXSR__=1`, 201 | `-D__DEC_EVAL_METHOD__=2`, 202 | `-D__UINT32_C(c)=c ## U`, 203 | `-D__INTMAX_MAX__=9223372036854775807L`, 204 | `-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__`, 205 | `-D__FLT_DENORM_MIN__=1.40129846432481707092e-45F`, 206 | `-D__INT8_MAX__=127`, 207 | `-D__UINT_FAST32_TYPE__=long unsigned int`, 208 | `-D__CHAR32_TYPE__=unsigned int`, 209 | `-D__FLT_MAX__=3.40282346638528859812e+38F`, 210 | `-D__INT32_TYPE__=int`, 211 | `-D__SIZEOF_DOUBLE__=8`, 212 | `-D__INTMAX_TYPE__=long int`, 213 | `-D__DEC128_MAX_EXP__=6145`, 214 | `-D__ATOMIC_CONSUME=1`, 215 | `-D__GNUC_MINOR__=8`, 216 | `-D__UINTMAX_MAX__=18446744073709551615UL`, 217 | `-D__DEC32_MANT_DIG__=7`, 218 | `-D__DBL_MAX_10_EXP__=308`, 219 | `-D__LDBL_DENORM_MIN__=3.64519953188247460253e-4951L`, 220 | `-D__INT16_C(c)=c`, 221 | `-D__STDC__=1`, 222 | `-D__PTRDIFF_TYPE__=long int`, 223 | `-D__ATOMIC_SEQ_CST=5`, 224 | `-D__UINT32_TYPE__=unsigned int`, 225 | `-D__UINTPTR_TYPE__=long unsigned int`, 226 | `-D__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD`, 227 | `-D__DEC128_MANT_DIG__=34`, 228 | `-D__LDBL_MIN_10_EXP__=(-4931)`, 229 | `-D__SSE_MATH__=1`, 230 | `-D__SIZEOF_LONG_LONG__=8`, 231 | `-D__GCC_ATOMIC_LLONG_LOCK_FREE=2`, 232 | `-D__LDBL_DIG__=18`, 233 | `-D__FLT_DECIMAL_DIG__=9`, 234 | `-D__UINT_FAST16_MAX__=18446744073709551615UL`, 235 | `-D__FLT_MIN_10_EXP__=(-37)`, 236 | `-D__GCC_ATOMIC_SHORT_LOCK_FREE=2`, 237 | `-D__UINT_FAST8_TYPE__=unsigned char`, 238 | `-D_GNU_SOURCE=1`, 239 | `-D__ATOMIC_ACQ_REL=4`, 240 | `-D__ATOMIC_RELEASE=3`, 241 | ]; 242 | -------------------------------------------------------------------------------- /expanded.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | module expanded; 10 | 11 | import std.stdio; 12 | 13 | import context; 14 | import macros; 15 | import util; 16 | import textbuf; 17 | 18 | /****************************************** 19 | * Expanded output. 20 | */ 21 | 22 | struct Expanded(R) 23 | { 24 | int noexpand = 0; 25 | int lineNumber = 1; // line number of expanded output 26 | 27 | Context!R* ctx; 28 | R* foutr; 29 | 30 | // Expanded output file 31 | Textbuf!(uchar,"exp") lineBuffer = void; 32 | uchar[1000] tmpbuf2 = void; 33 | 34 | void off() { ++noexpand; } 35 | void on() { --noexpand; assert(noexpand >= 0); } 36 | 37 | void initialize(Context!R* ctx) 38 | { 39 | this.ctx = ctx; 40 | lineBuffer = Textbuf!(uchar,"exp")(tmpbuf2); 41 | } 42 | 43 | void start(R* foutr) 44 | { 45 | this.foutr = foutr; 46 | this.lineBuffer.initialize(); 47 | this.lineBuffer.put(0); 48 | this.noexpand = 0; 49 | this.lineNumber = 1; 50 | } 51 | 52 | void finish() 53 | { 54 | put('\n'); // cause last line to be flushed to output 55 | } 56 | 57 | void put(uchar c) 58 | { 59 | //writefln("expanded.put(%02x '%s' %s)", c, cast(char)(c < ' ' ? '?' : c), noexpand); 60 | if (c != ESC.space && !noexpand) 61 | { 62 | if (lineBuffer.last() == '\n') 63 | put2(); 64 | //writefln("lineBuffer.put('%c')", c); 65 | lineBuffer.put(c); 66 | } 67 | } 68 | 69 | private void put2() 70 | { 71 | uchar c = lineBuffer[1]; 72 | if (c != '\n' && c != '\r') 73 | { 74 | if (auto s = ctx.currentSourceFile()) 75 | { 76 | auto linnum = s.loc.lineNumber - 1; 77 | if (!ctx.lastloc.srcFile || ctx.lastloc.fileName !is s.loc.fileName) 78 | { 79 | if (ctx.uselastloc) 80 | { 81 | ctx.lastloc.linemarker(foutr); 82 | } 83 | else 84 | { 85 | /* Since the next readLine() has already been called, 86 | * s.loc.lineNumber is one ahead of the expanded line 87 | * that has yet to be written out. So linemarker() subtracts 88 | * one to compensage. 89 | * However, if the next readLine() read a \ line spliced line, 90 | * s.loc.lineNumber may be further ahead than just one. 91 | * This, then, is a bug. 92 | */ 93 | s.loc.linemarker(foutr); 94 | ctx.lastloc = s.loc; 95 | } 96 | lineNumber = linnum; 97 | } 98 | else if (linnum != lineNumber) 99 | { 100 | if (lineNumber + 30 > linnum) 101 | { 102 | foreach (i; lineNumber .. linnum) 103 | foutr.put('\n'); 104 | } 105 | else 106 | { 107 | s.loc.linemarker(foutr); 108 | } 109 | lineNumber = linnum; 110 | } 111 | } 112 | else if (ctx.uselastloc && ctx.lastloc.srcFile) 113 | { 114 | ctx.lastloc.linemarker(foutr); 115 | } 116 | } 117 | ctx.uselastloc = false; 118 | foutr.writePreprocessedLine(lineBuffer[1 .. lineBuffer.length]); 119 | lineBuffer.initialize(); 120 | lineBuffer.put(0); // so its length is never 0 121 | ++lineNumber; 122 | } 123 | 124 | void put(const(uchar)[] s) 125 | { 126 | //writefln("expanded.put('%s')", cast(string)s); 127 | /* This will always be an identifier string, so we can skip 128 | * a lot of the checking. 129 | */ 130 | if (!noexpand) 131 | { 132 | if (s.length > 0) 133 | { 134 | put(s[0]); 135 | if (s.length > 1) 136 | lineBuffer.put(s[1 .. $]); 137 | } 138 | } 139 | } 140 | 141 | /******************* 142 | * Remove last character emitted. 143 | */ 144 | void popBack() 145 | { 146 | if (!noexpand && lineBuffer.length > 1) 147 | lineBuffer.pop(); 148 | } 149 | 150 | /**************************** 151 | * Erase current unemitted line. 152 | */ 153 | void eraseLine() 154 | { 155 | lineBuffer.initialize(); 156 | lineBuffer.put(0); 157 | } 158 | } 159 | 160 | /* 161 | * Local Variables: 162 | * mode: d 163 | * c-basic-offset: 4 164 | * End: 165 | */ 166 | -------------------------------------------------------------------------------- /file.d: -------------------------------------------------------------------------------- 1 | // Written in the D programming language. 2 | // This is derived from phobos/std/file.d, with a rewrite of the file reader. 3 | 4 | /** 5 | Utilities for manipulating files and scanning directories. Functions 6 | in this module handle files as a unit, e.g., read or write one _file 7 | at a time. For opening files and manipulating them via handles refer 8 | to module $(LINK2 std_stdio.html,$(D std.stdio)). 9 | 10 | Macros: 11 | 12 | Copyright: Copyright Digital Mars 2007 - 2011. 13 | License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 14 | Authors: $(LINK2 http://digitalmars.com, Walter Bright), 15 | $(LINK2 http://erdani.org, Andrei Alexandrescu), 16 | Jonathan M Davis 17 | */ 18 | module file; 19 | 20 | import std.file; 21 | import core.memory; 22 | import core.stdc.stdio, core.stdc.stdlib, core.stdc.string, 23 | core.stdc.errno, std.algorithm, std.array, std.conv, 24 | std.datetime, std.exception, std.format, std.path, std.process, 25 | std.range, std.stdio, std.string, std.traits, 26 | std.typecons, std.typetuple, std.utf; 27 | 28 | 29 | version (Windows) 30 | { 31 | import core.sys.windows.windows, std.windows.syserror; 32 | } 33 | else version (Posix) 34 | { 35 | import core.sys.posix.dirent, core.sys.posix.fcntl, core.sys.posix.sys.stat, 36 | core.sys.posix.sys.time, core.sys.posix.unistd, core.sys.posix.utime; 37 | } 38 | else 39 | static assert(false, "Module " ~ .stringof ~ " not implemented for this OS."); 40 | 41 | /********************** 42 | * SPAD allows us to "look behind" the start of a buffer, to avoid the check 43 | * EPAD ensures that buffers end in a \n 44 | */ 45 | enum SPAD = 16; // only need 2, the rest is to align the buffer 46 | enum EPAD = 2; 47 | 48 | /******************************************** 49 | Read entire contents of file $(D name) and returns it as an untyped 50 | array. If the file size is larger than $(D upTo), only $(D upTo) 51 | bytes are read. 52 | 53 | Returns: Untyped array of bytes _read. 54 | null if file doesn't exist. 55 | 56 | */ 57 | 58 | /* With or without this on Windows things might be faster - I get ambiguous results 59 | */ 60 | //version = onestat; 61 | 62 | void[] myRead(in char[] name, size_t upTo = size_t.max) 63 | { 64 | void* result = null; 65 | 66 | version(Windows) 67 | { 68 | auto namez = std.utf.toUTF16z(name); 69 | 70 | /* Doing a stat to see if the file is there before attempting to read it 71 | * turns out to be much faster. 72 | */ 73 | version (onestat) 74 | { 75 | WIN32_FILE_ATTRIBUTE_DATA fad; 76 | if (GetFileAttributesExW(namez, GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, &fad) == 0) 77 | return null; 78 | if (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 79 | return null; 80 | 81 | ULARGE_INTEGER li; 82 | li.LowPart = fad.nFileSizeLow; 83 | li.HighPart = fad.nFileSizeHigh; 84 | auto size = cast(size_t)li.QuadPart; 85 | } 86 | else 87 | { // Two stats 88 | auto attr = GetFileAttributesW(namez); 89 | if (attr == 0xFFFF_FFFF || attr & FILE_ATTRIBUTE_DIRECTORY) 90 | return null; 91 | } 92 | 93 | alias TypeTuple!(GENERIC_READ, 94 | FILE_SHARE_READ, (SECURITY_ATTRIBUTES*).init, OPEN_EXISTING, 95 | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 96 | HANDLE.init) 97 | defaults; 98 | auto h = CreateFileW(namez, defaults); 99 | 100 | if (h == INVALID_HANDLE_VALUE) 101 | return null; 102 | scope(exit) CloseHandle(h); 103 | 104 | version (statsize) 105 | { 106 | } 107 | else 108 | { 109 | auto size = GetFileSize(h, null); 110 | if (size == INVALID_FILE_SIZE) 111 | return null; 112 | } 113 | 114 | size = min(upTo, size); 115 | auto buf = malloc(size + SPAD + EPAD); 116 | assert(buf); 117 | 118 | DWORD numread = void; 119 | if (ReadFile(h, buf + SPAD, size, &numread, null) != 1 120 | || numread != size) 121 | { 122 | free(buf); 123 | return null; 124 | } 125 | result = buf; 126 | } 127 | else version(Posix) 128 | { 129 | auto namez = toStringz(name); 130 | 131 | /* Doing a stat to see if the file is there before attempting to read it 132 | * turns out to be much faster. 133 | */ 134 | stat_t statbuf = void; 135 | if (stat(namez, &statbuf) != 0 || 136 | (statbuf.st_mode & S_IFMT) != S_IFREG) 137 | return null; 138 | 139 | // A few internal configuration parameters { 140 | enum size_t 141 | minInitialAlloc = 1024 * 4, 142 | maxInitialAlloc = size_t.max / 2, 143 | sizeIncrement = 1024 * 16, 144 | maxSlackMemoryAllowed = 1024; 145 | // } 146 | 147 | immutable fd = core.sys.posix.fcntl.open(namez, 148 | core.sys.posix.fcntl.O_RDONLY); 149 | if (fd == -1) 150 | return null; 151 | 152 | scope(exit) core.sys.posix.unistd.close(fd); 153 | 154 | immutable initialAlloc = to!size_t(statbuf.st_size 155 | ? min(statbuf.st_size + 1, maxInitialAlloc) 156 | : minInitialAlloc); 157 | 158 | result = malloc(initialAlloc + SPAD + EPAD); 159 | assert(result); 160 | size_t result_length = initialAlloc; 161 | size_t size = 0; 162 | 163 | for (;;) 164 | { 165 | immutable actual = core.sys.posix.unistd.read(fd, result + size + SPAD, 166 | min(result_length, upTo) - size); 167 | if (actual == -1) 168 | { 169 | free(result); 170 | return null; 171 | } 172 | if (actual == 0) break; 173 | size += actual; 174 | if (size < result_length) continue; 175 | immutable newAlloc = size + sizeIncrement; 176 | result = realloc(result, newAlloc + SPAD + EPAD); 177 | assert(result); 178 | result_length = newAlloc; 179 | } 180 | 181 | result = result_length - size >= maxSlackMemoryAllowed 182 | ? realloc(result, size + SPAD + EPAD) 183 | : result; 184 | } 185 | else 186 | static assert(0); 187 | 188 | (cast(ubyte*)result)[SPAD - 2] = 0; 189 | (cast(ubyte*)result)[SPAD - 1] = 0; 190 | 191 | /* EPAD bytes are available past the end. Use to ensure file ends 192 | * in \n. Need two in case file ends with a \ character. 193 | */ 194 | if (size) 195 | { 196 | if ((cast(ubyte*)result)[SPAD + size - 1] != '\n') 197 | { 198 | (cast(ubyte*)result)[SPAD + size] = '\n'; 199 | (cast(ubyte*)result)[SPAD + size + 1] = '\n'; 200 | size += 2; 201 | } 202 | } 203 | else 204 | { // File is empty, so make it a one-liner 205 | (cast(ubyte*)result)[SPAD] = '\n'; 206 | ++size; 207 | } 208 | return result[SPAD .. SPAD + size]; 209 | } 210 | 211 | /***************************** 212 | * Free buffer allocated by myRead(). 213 | */ 214 | void myReadFree(void[] buf) 215 | { 216 | free(buf.ptr - SPAD); 217 | } 218 | 219 | /* 220 | * Local Variables: 221 | * mode: d 222 | * c-basic-offset: 4 223 | * End: 224 | */ 225 | -------------------------------------------------------------------------------- /id.d: -------------------------------------------------------------------------------- 1 | 2 | 3 | /** 4 | * C preprocessor 5 | * Copyright: 2013 by Digital Mars 6 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 7 | * Authors: Walter Bright 8 | */ 9 | 10 | module id; 11 | 12 | import core.stdc.stdio; 13 | import core.stdc.stdlib; 14 | import core.stdc.time; 15 | import std.stdio; 16 | 17 | import util; 18 | import macros; 19 | 20 | /****************************** 21 | * All identifiers become a pointer to an instance 22 | * of this. 23 | */ 24 | 25 | struct Id 26 | { 27 | enum buckets_length = 0x8000UL; 28 | __gshared Id*[] buckets; 29 | 30 | __gshared uint count; 31 | 32 | ustring name; 33 | size_t hash; 34 | Id* next; 35 | 36 | private this(ustring name, size_t hash) 37 | { 38 | this.name = name; 39 | this.hash = hash; 40 | } 41 | 42 | /****************************** 43 | * Reset in between files processed. 44 | */ 45 | static void reset() 46 | { 47 | /* Expect that the same headers will be processed again, with the 48 | * same macros. So leave the table in place - just #undef all the 49 | * entries. 50 | */ 51 | foreach (m; buckets) 52 | { 53 | for (; m; m = m.next) 54 | { 55 | m.flags = 0; 56 | m.text = null; 57 | m.parameters = null; 58 | } 59 | } 60 | } 61 | 62 | /********************* 63 | * See if this is a known identifier. 64 | * Returns: 65 | * Id* if it is, null if not 66 | */ 67 | static Id* search(const(uchar)[] name) 68 | { 69 | if (buckets.length) 70 | { 71 | auto hash = getHash(name); 72 | auto bucket = buckets[hash % buckets_length]; 73 | while (bucket) 74 | { 75 | if (bucket.hash == hash && bucket.name == name) 76 | return bucket; 77 | bucket = bucket.next; 78 | } 79 | } 80 | return null; 81 | } 82 | 83 | 84 | /************************* 85 | * Look up name in Id table. 86 | * If it's there, return it. 87 | * If not, create an Id and return it. 88 | */ 89 | static Id* pool(ustring name) 90 | { 91 | if (!buckets.length) 92 | { 93 | buckets = (cast(Id**)calloc((Id*).sizeof, buckets_length))[0 .. buckets_length]; 94 | assert(buckets.ptr); 95 | } 96 | 97 | auto hash = getHash(name); 98 | auto pbucket = &buckets[hash % buckets_length]; 99 | //int depth; 100 | while (*pbucket) 101 | { 102 | //++depth; 103 | if ((*pbucket).hash == hash && (*pbucket).name == name) 104 | return *pbucket; 105 | pbucket = &(*pbucket).next; 106 | } 107 | auto id = new Id(name, hash); 108 | *pbucket = id; 109 | //++count; 110 | //writefln("count: %s depth %s hash %s bucket %s %s", count, depth, hash, hash % buckets.length, cast(string)name); 111 | return id; 112 | } 113 | 114 | /**************************** 115 | * Define a macro. 116 | * Returns: 117 | * null if a redefinition error 118 | */ 119 | static Id* defineMacro(ustring name, ustring[] parameters, ustring text, uint flags) 120 | { 121 | //writefln("defineMacro(%s, %s, %s, %s)", cast(string)name, cast(string[])parameters, cast(string)text, flags); 122 | auto m = pool(name); 123 | if (m.flags & IDmacro) 124 | { 125 | if ((m.flags ^ flags) & (IDdotdotdot | IDfunctionLike) || 126 | m.parameters != parameters || 127 | m.text != text) 128 | { 129 | return null; 130 | } 131 | if (((m.flags ^ flags) & IDpredefined) && 132 | m.text != text) 133 | { 134 | return null; 135 | } 136 | } 137 | m.flags |= IDmacro | flags; 138 | m.parameters = parameters; 139 | m.text = text; 140 | return m; 141 | } 142 | 143 | uint flags; // flags are below 144 | enum 145 | { 146 | // Macros 147 | IDmacro = 1, // it's a macro in good standing 148 | IDdotdotdot = 2, // the macro has a ... 149 | IDfunctionLike = 4, // the macro has ( ), i.e. is function-like 150 | IDpredefined = 8, // the macro is predefined and cannot be #undef'd 151 | IDinuse = 0x10, // macro is currently being expanded 152 | 153 | // Predefined 154 | IDlinnum = 0x20, 155 | IDfile = 0x40, 156 | IDcounter = 0x80, 157 | IDpragma = 0x100, 158 | } 159 | 160 | ustring text; // replacement text of the macro 161 | ustring[] parameters; // macro parameters 162 | 163 | /* Initialize the predefined macros 164 | */ 165 | static void initPredefined() 166 | { 167 | defineMacro(cast(ustring)"__FILE__", null, null, IDpredefined | IDfile); 168 | defineMacro(cast(ustring)"__LINE__", null, null, IDpredefined | IDlinnum); 169 | defineMacro(cast(ustring)"__COUNTER__", null, null, IDpredefined | IDcounter); 170 | 171 | uchar[1+26+1] date; 172 | time_t t; 173 | 174 | time(&t); 175 | auto p = cast(ubyte*)ctime(&t); 176 | assert(p); 177 | 178 | auto len = sprintf(cast(char*)date.ptr,"\"%.24s\"",p); 179 | defineMacro(cast(ustring)"__TIMESTAMP__", null, date[0..len].idup, IDpredefined); 180 | 181 | len = sprintf(cast(char*)date.ptr,"\"%.6s %.4s\"",p+4,p+20); 182 | defineMacro(cast(ustring)"__DATE__", null, date[0..len].idup, IDpredefined); 183 | 184 | len = sprintf(cast(char*)date.ptr,"\"%.8s\"",p+11); 185 | defineMacro(cast(ustring)"__TIME__", null, date[0..len].idup, IDpredefined); 186 | 187 | static ustring[1] params = [cast(ustring)"arg"]; 188 | defineMacro(cast(ustring)"_Pragma", params, cast(ustring)("\n#pragma " ~ ESC.start ~ ESC.arg1 ~ "\n"), 189 | IDpredefined | IDpragma | IDfunctionLike); 190 | } 191 | 192 | static size_t getHash(const(uchar)[] name) 193 | { 194 | size_t hash = 0; 195 | while (name.length >= size_t.sizeof) 196 | { 197 | hash = hash * 37 + *cast(size_t*)name.ptr; 198 | name = name[size_t.sizeof .. $]; 199 | } 200 | foreach (c; name) 201 | hash = hash * 37 + c; 202 | hash ^= (hash >> 20) ^ (hash >> 12); 203 | return hash ^ (hash >> 7) ^ (hash >> 4); 204 | } 205 | } 206 | 207 | /* 208 | * Local Variables: 209 | * mode: d 210 | * c-basic-offset: 4 211 | * End: 212 | */ 213 | -------------------------------------------------------------------------------- /loc.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | module loc; 10 | 11 | import std.format; 12 | import std.stdio; 13 | 14 | import sources; 15 | 16 | /************************************* 17 | * Flags that indicate system file status. 18 | */ 19 | 20 | enum Sys : ubyte 21 | { 22 | none = 0, // not a system file 23 | angle = 1, // #include'd with < > 24 | syspath = 2, // appears in --isystem path, or was #include'd from a Sys.syspath file 25 | } 26 | 27 | /************************************* 28 | * Current location. 29 | */ 30 | 31 | struct Loc 32 | { 33 | SrcFile* srcFile; 34 | string fileName; // because #line may change the filename 35 | uint lineNumber; // line number of current position 36 | Sys system; // system file status 37 | 38 | /******************************************** 39 | * Write out linemarker for current location to range r. 40 | */ 41 | void linemarker(R)(R r) 42 | { 43 | r.formattedWrite("# %d \"%s\"", lineNumber - 1, fileName); 44 | if (system) 45 | { 46 | r.put(' '); 47 | /* Values are: 48 | * 1 start of file 49 | * 2 return to this file 50 | * 3 system file 51 | * 4 file should be wrapped in implicit extern "C" 52 | */ 53 | r.put('3'); 54 | } 55 | r.put('\n'); 56 | } 57 | 58 | /********************************************** 59 | * Write out current location to File* 60 | */ 61 | void write(File* f) 62 | { 63 | //writefln("%s(%s) %s", fileName, lineNumber, system); 64 | if (srcFile) 65 | f.writef("%s:%d: ", fileName, lineNumber); 66 | } 67 | } 68 | 69 | /************************************************* 70 | * Element of a linked list of locations. 71 | */ 72 | struct LocList 73 | { 74 | Loc first; 75 | LocList* rest; 76 | } 77 | 78 | /* 79 | * Local Variables: 80 | * mode: d 81 | * c-basic-offset: 4 82 | * End: 83 | */ 84 | -------------------------------------------------------------------------------- /main.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | import std.array; 10 | import std.format; 11 | import std.stdio; 12 | import core.stdc.stdlib; 13 | import core.memory; 14 | 15 | import cmdline; 16 | import context; 17 | import loc; 18 | import sources; 19 | import util; 20 | 21 | extern (C) int isatty(int); 22 | 23 | alias typeof(File.lockingTextWriter()) R; 24 | 25 | version (unittest) 26 | { 27 | int main() { writeln("unittests successful"); return EXIT_SUCCESS; } 28 | } 29 | else 30 | { 31 | int main(string[] args) 32 | { 33 | // No need to collect 34 | GC.disable(); 35 | 36 | const params = parseCommandLine(args); 37 | 38 | auto context = Context!R(params); 39 | 40 | try 41 | { 42 | // Preprocess each file 43 | foreach (i; 0 .. params.sourceFilenames.length) 44 | { 45 | if (i) 46 | context.reset(); 47 | 48 | auto srcFilename = params.sourceFilenames[i]; 49 | auto outFilename = params.stdout ? "-" : params.outFilenames[i]; 50 | 51 | if (context.params.verbose) 52 | writefln("from %s to %s", srcFilename, outFilename); 53 | 54 | auto sf = SrcFile.lookup(srcFilename); 55 | if (!sf.read()) 56 | err_fatal("cannot read file %s", srcFilename); 57 | 58 | if (context.doDeps) 59 | context.deps ~= srcFilename; 60 | 61 | scope(failure) if (!params.stdout) std.file.remove(outFilename); 62 | 63 | auto fout = params.stdout ? stdout : File(outFilename, "wb"); 64 | if (!isatty(fout.fileno)) 65 | fout.setvbuf(0x100000); 66 | auto foutr = fout.lockingTextWriter(); // has destructor 67 | 68 | context.localStart(sf, &foutr); 69 | context.preprocess(); 70 | context.localFinish(); 71 | 72 | /* The one source file we don't need to cache the contents 73 | * of is the .c file. 74 | */ 75 | sf.freeContents(); 76 | } 77 | } 78 | catch (Exception e) 79 | { 80 | auto printedFrom = false; 81 | for (auto trace = context.includeTrace(); 82 | trace != null; 83 | trace = trace.rest) { 84 | auto loc = trace.first; 85 | stderr.writef( 86 | "%s from %s:%u", 87 | printedFrom ? ",\n " : "In file included", 88 | loc.fileName, loc.lineNumber); 89 | printedFrom = true; 90 | } 91 | if (printedFrom) { 92 | stderr.writeln(":"); 93 | } 94 | context.loc().write(&stderr); 95 | stderr.writeln(e.msg); 96 | exit(EXIT_FAILURE); 97 | } 98 | 99 | context.globalFinish(); 100 | 101 | exit(EXIT_SUCCESS); // this prevents the collector from running on exit 102 | // (it also prevents -profile from working) 103 | return EXIT_SUCCESS; 104 | } 105 | } 106 | 107 | /* 108 | * Local Variables: 109 | * mode: d 110 | * c-basic-offset: 4 111 | * End: 112 | */ 113 | -------------------------------------------------------------------------------- /number.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | module number; 10 | 11 | import std.array; 12 | import std.ascii; 13 | import std.conv; 14 | import std.range; 15 | import std.stdio; 16 | import std.traits; 17 | 18 | import lexer : ppint_t, ppuint_t; 19 | import util : err_fatal; 20 | import ranges : BitBucket; 21 | 22 | /****************************** 23 | * Lex a number. 24 | * Input: 25 | * r source range on first digit of number 26 | * Output: 27 | * result number 28 | * isunsigned true if number is unsigned 29 | * isinteger true if it is a number (otherwise it's a floating point literal) 30 | * Returns: 31 | * range pointing past end of number 32 | */ 33 | 34 | R lexNumber(R)(R r, out ppint_t result, out bool isunsigned, out bool isinteger) 35 | if (isInputRange!R) 36 | { 37 | alias Unqual!(ElementEncodingType!R) E; 38 | 39 | BitBucket!E bitbucket = void; 40 | 41 | bool overflow = false; 42 | isinteger = true; 43 | int radix = 10; 44 | ppuint_t n = 0; 45 | 46 | if (r.empty) 47 | return r; 48 | 49 | E c = cast(E)r.front; 50 | if (c == '0') 51 | { 52 | r.popFront(); 53 | if (r.empty) 54 | return r; 55 | 56 | c = cast(E)r.front; 57 | switch (c) 58 | { 59 | case '0': .. case '9': 60 | r.popFront(); 61 | radix = 8; 62 | n = c - '0'; 63 | break; 64 | 65 | case 'x': 66 | case 'X': 67 | r.popFront(); 68 | radix = 16; 69 | break; 70 | 71 | case 'b': 72 | case 'B': 73 | r.popFront(); 74 | radix = 2; 75 | break; 76 | 77 | case '.': 78 | r = r.skipFloat(bitbucket, false, false, false); 79 | isinteger = false; 80 | return r; 81 | 82 | case 'e': 83 | case 'E': 84 | r = r.skipFloat(bitbucket, false, false, true); 85 | isinteger = false; 86 | return r; 87 | 88 | case 'A': case 'C': .. case 'D': case 'F': 89 | case 'a': case 'c': .. case 'd': case 'f': 90 | err_fatal("octal digit expected"); 91 | r.popFront(); 92 | break; 93 | 94 | default: 95 | break; 96 | } 97 | } 98 | 99 | while (!r.empty) 100 | { 101 | c = cast(E)r.front; 102 | ppint_t d; 103 | switch (c) 104 | { 105 | case '2': .. case '9': 106 | if (radix == 2) 107 | { 108 | err_fatal("0 or 1 expected"); 109 | } 110 | goto case; 111 | 112 | case '0': case '1': 113 | r.popFront(); 114 | d = c - '0'; 115 | break; 116 | 117 | case 'a': .. case 'f': 118 | case 'A': .. case 'F': 119 | if (radix != 16) 120 | { 121 | if (c == 'e' || c == 'E') 122 | goto Lsawexponent; 123 | if (c == 'f' || c == 'F') 124 | { 125 | r.popFront(); 126 | isinteger = false; 127 | return r; 128 | } 129 | err_fatal("%s digit expected not '%s'", radix == 8 ? "octal" : "decimal", cast(char)c); 130 | } 131 | r.popFront(); 132 | if (c >= 'a') 133 | d = c + 10 - 'a'; 134 | else 135 | d = c + 10 - 'A'; 136 | break; 137 | 138 | case 'p': 139 | case 'P': 140 | Lsawexponent: 141 | r = r.skipFloat(bitbucket, radix == 16, false, true); 142 | isinteger = false; 143 | return r; 144 | 145 | case '.': 146 | r = r.skipFloat(bitbucket, radix == 16, false, false); 147 | isinteger = false; 148 | return r; 149 | 150 | default: 151 | goto Ldone; 152 | } 153 | 154 | auto n2 = n * radix; 155 | if (n2 / radix != n || n2 + d < n) 156 | { 157 | overflow = true; 158 | } 159 | 160 | n = n2 + d; 161 | } 162 | 163 | Ldone: 164 | // Parse trailing 'u', 'U', 'l' or 'L' in any combination 165 | enum FLAGS { none, U = 1, L = 2, LL = 4 } 166 | FLAGS flags = FLAGS.none; 167 | while (!r.empty) 168 | { 169 | switch (r.front) 170 | { 171 | case 'U': 172 | case 'u': 173 | if (flags & FLAGS.U) 174 | err_fatal("redundant U suffix"); 175 | flags |= FLAGS.U; 176 | r.popFront(); 177 | continue; 178 | 179 | case 'L': 180 | case 'l': 181 | if (flags & FLAGS.LL) 182 | err_fatal("redundant L suffix"); 183 | flags |= (flags & FLAGS.L) ? FLAGS.LL : FLAGS.L; 184 | r.popFront(); 185 | continue; 186 | 187 | default: 188 | break; 189 | } 190 | break; 191 | } 192 | 193 | if (flags & FLAGS.U || n >= 0x8000_0000_0000_0000LU) 194 | isunsigned = true; 195 | result = n; 196 | if (overflow && isinteger) 197 | err_fatal("integer overflow"); 198 | return r; 199 | } 200 | 201 | unittest 202 | { 203 | ppint_t number; 204 | bool isunsigned; 205 | bool isinteger; 206 | string s; 207 | 208 | s = ""; 209 | s = s.lexNumber(number, isunsigned, isinteger); 210 | assert(number == 0); 211 | assert(!isunsigned); 212 | assert(s.empty); 213 | 214 | s = "0"; 215 | s = s.lexNumber(number, isunsigned, isinteger); 216 | assert(number == 0); 217 | assert(!isunsigned); 218 | assert(s.empty); 219 | 220 | s = "123456789x"; 221 | s = s.lexNumber(number, isunsigned, isinteger); 222 | assert(number == 123456789); 223 | assert(!isunsigned); 224 | assert(!s.empty && s.front == 'x'); 225 | 226 | s = "0x123abcdefx"; 227 | s = s.lexNumber(number, isunsigned, isinteger); 228 | assert(number == 0x123abcdef); 229 | assert(!isunsigned); 230 | assert(!s.empty && s.front == 'x'); 231 | 232 | s = "0x456789ABCDEFx"; 233 | s = s.lexNumber(number, isunsigned, isinteger); 234 | assert(number == 0x456789ABCDEF); 235 | assert(!isunsigned); 236 | assert(!s.empty && s.front == 'x'); 237 | 238 | s = "01234567x"; 239 | s = s.lexNumber(number, isunsigned, isinteger); 240 | assert(number == octal!1234567); 241 | assert(!isunsigned); 242 | assert(!s.empty && s.front == 'x'); 243 | 244 | s = "0L"; 245 | s = s.lexNumber(number, isunsigned, isinteger); 246 | assert(number == 0); 247 | assert(!isunsigned); 248 | assert(s.empty); 249 | 250 | s = "0l"; 251 | s = s.lexNumber(number, isunsigned, isinteger); 252 | assert(number == 0); 253 | assert(!isunsigned); 254 | assert(s.empty); 255 | 256 | s = "0U"; 257 | s = s.lexNumber(number, isunsigned, isinteger); 258 | assert(number == 0); 259 | assert(isunsigned); 260 | assert(s.empty); 261 | 262 | s = "0u"; 263 | s = s.lexNumber(number, isunsigned, isinteger); 264 | assert(number == 0); 265 | assert(isunsigned); 266 | assert(s.empty); 267 | 268 | s = "8lu"; 269 | s = s.lexNumber(number, isunsigned, isinteger); 270 | assert(number == 8); 271 | assert(isunsigned); 272 | assert(s.empty); 273 | 274 | s = "8ull"; 275 | s = s.lexNumber(number, isunsigned, isinteger); 276 | assert(number == 8); 277 | assert(isunsigned); 278 | assert(s.empty); 279 | 280 | s = "0x8000000000000000"; 281 | s = s.lexNumber(number, isunsigned, isinteger); 282 | assert(number == 0x8000_0000_0000_0000); 283 | assert(isunsigned); 284 | assert(s.empty); 285 | 286 | s = "1ff"; 287 | s = s.lexNumber(number, isunsigned, isinteger); 288 | assert(!isinteger); 289 | assert(s == "f"); 290 | 291 | s = "0b1101"; 292 | s = s.lexNumber(number, isunsigned, isinteger); 293 | assert(isinteger); 294 | assert(number == 13); 295 | assert(s.empty); 296 | 297 | s = "0B10"; 298 | s = s.lexNumber(number, isunsigned, isinteger); 299 | assert(isinteger); 300 | assert(number == 2); 301 | assert(s.empty); 302 | 303 | string[] floats = ["1f", "5e+08", "1.4", "89.", "0xep+1", "1E9", 304 | "083.", "0023.2" ]; 305 | foreach (f; floats) 306 | { 307 | f = f.lexNumber(number, isunsigned, isinteger); 308 | assert(!isinteger); 309 | assert(f.empty); 310 | } 311 | } 312 | 313 | /*********************************** 314 | * Skip over floating point number. 315 | */ 316 | 317 | R skipFloat(R, S)(R r, ref S s, bool hex, bool sawdot, bool isexponent) 318 | if (isInputRange!R && isOutputRange!(S, ElementEncodingType!R)) 319 | { 320 | alias Unqual!(ElementEncodingType!R) E; 321 | 322 | if (!r.empty) 323 | { 324 | E get() { E c = cast(E)r.front; return c; } 325 | 326 | E c = get(); 327 | 328 | bool isfloat = sawdot | isexponent; 329 | 330 | if (isexponent) 331 | goto Lisexponent; 332 | 333 | if (sawdot) 334 | goto Lsawdot; 335 | 336 | // Leading '0x' 337 | if (c == '0') 338 | { 339 | s.put(c); 340 | r.popFront(); 341 | if (r.empty) 342 | goto Lreturn; 343 | c = get(); 344 | if (c == 'x' || c == 'X') 345 | { 346 | s.put(c); 347 | r.popFront(); 348 | hex = true; 349 | if (r.empty) 350 | { 351 | err_fatal("hex digit(s) expected"); 352 | goto Lreturn; 353 | } 354 | c = get(); 355 | } 356 | } 357 | 358 | // Digits to left of '.' 359 | while (1) 360 | { 361 | if (c == '.') 362 | { 363 | isfloat = true; 364 | s.put(c); 365 | r.popFront(); 366 | if (r.empty) 367 | goto Lreturn; 368 | c = get(); 369 | break; 370 | } 371 | if (isDigit(c) || (hex && isHexDigit(c))) 372 | { 373 | s.put(c); 374 | r.popFront(); 375 | if (r.empty) 376 | goto Lreturn; 377 | c = get(); 378 | continue; 379 | } 380 | break; 381 | } 382 | 383 | Lsawdot: 384 | 385 | // Digits to right of '.' 386 | while (1) 387 | { 388 | if (isDigit(c) || (hex && isHexDigit(c))) 389 | { 390 | s.put(c); 391 | r.popFront(); 392 | if (r.empty) 393 | goto Lreturn; 394 | c = get(); 395 | continue; 396 | } 397 | break; 398 | } 399 | 400 | Lisexponent: 401 | if (c == 'e' || c == 'E' || (hex && (c == 'p' || c == 'P'))) 402 | { 403 | s.put(c); 404 | r.popFront(); 405 | if (r.empty) 406 | { 407 | err_fatal("exponent digits missing"); 408 | goto Lreturn; 409 | } 410 | c = get(); 411 | if (c == '-' || c == '+') 412 | { 413 | s.put(c); 414 | r.popFront(); 415 | if (r.empty) 416 | { 417 | err_fatal("exponent digits missing"); 418 | goto Lreturn; 419 | } 420 | c = get(); 421 | } 422 | bool anyexp; 423 | while (1) 424 | { 425 | if (isDigit(c) || (hex && isHexDigit(c))) 426 | { 427 | r.popFront(); 428 | s.put(c); 429 | anyexp = true; 430 | if (r.empty) 431 | goto Lreturn; 432 | c = get(); 433 | continue; 434 | } 435 | if (!anyexp) 436 | err_fatal("missing exponent"); 437 | break; 438 | } 439 | } 440 | else if (hex && isfloat) 441 | err_fatal("exponent required for hex float"); 442 | 443 | if (c == 'f' || c == 'F' || c == 'l' || c == 'L') 444 | { 445 | s.put(c); 446 | r.popFront(); 447 | if (r.empty) 448 | goto Lreturn; 449 | c = get(); 450 | } 451 | 452 | Lreturn: 453 | ; 454 | } 455 | return r; 456 | } 457 | 458 | unittest 459 | { 460 | BitBucket!char bitbucket = void; 461 | 462 | string[] cases = ["", "0", "1", "55.", "2.3", "0.0E+2", "0.0e-150", "0E03", 463 | "2.7l", "3.2L", "5.6e1f", "125.1234F", 464 | "0x12abcdefABCDEFp+20", "0x9.aP-10" 465 | ]; 466 | 467 | foreach (s; cases) 468 | { 469 | //writefln("before: |%s|", s); 470 | s = s.skipFloat(bitbucket, false, false, false); 471 | //writefln("after: |%s|", s); 472 | assert(s.empty); 473 | } 474 | 475 | string s; 476 | 477 | s = "123"; 478 | s = s.skipFloat(bitbucket, false, true, false); 479 | assert(s.empty); 480 | 481 | s = "e123"; 482 | s = s.skipFloat(bitbucket, false, false, true); 483 | assert(s.empty); 484 | 485 | s = "e+08"; 486 | s = s.skipFloat(bitbucket, false, false, true); 487 | assert(s.empty); 488 | } 489 | 490 | /* 491 | * Local Variables: 492 | * mode: d 493 | * c-basic-offset: 4 494 | * End: 495 | */ 496 | -------------------------------------------------------------------------------- /outdeps.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | module outdeps; 10 | 11 | import std.stdio; 12 | import std.path; 13 | import std.range; 14 | 15 | import textbuf; 16 | 17 | version (Windows) 18 | immutable string extObj = "obj"; 19 | else 20 | immutable string extObj = "o"; 21 | 22 | /*************************************** 23 | * Format dependencies into OutputRange r. 24 | * Formatting is separated from file writing so the former can be unittested. 25 | */ 26 | 27 | R dependencyFileFormat(R)(ref R r, string[] deps) if (isOutputRange!(R, char)) 28 | { 29 | void puts(string s) 30 | { 31 | foreach (char c; s) 32 | r.put(c); 33 | } 34 | 35 | void putln() { r.put('\n'); } 36 | 37 | if (deps.length) 38 | { 39 | int col = 1; 40 | 41 | string objfilename = setExtension(deps[0], extObj); 42 | puts(objfilename); 43 | puts(": "); 44 | col += objfilename.length + 2; 45 | 46 | foreach (dep; deps) 47 | { 48 | if (col >= 70) 49 | { 50 | puts(" \\"); 51 | putln(); 52 | col = 1; 53 | } 54 | r.put(' '); 55 | puts(dep); 56 | col += 1 + dep.length; 57 | } 58 | if (col > 1) 59 | putln(); 60 | } 61 | return r; 62 | } 63 | 64 | 65 | unittest 66 | { 67 | string[] deps = ["asdfasdf.d", "kjjksdkfj.d", "asdkjfksdfj.d", 68 | "asdfasdf0.d", "kjjksdkfj0.d", "asdkjfksdfj0.d", 69 | "asdfasdf1.d", "kjjksdkfj1.d", "asdkjfksdfj1.d", 70 | ]; 71 | 72 | char[1000] buf; 73 | auto textbuf = Textbuf!char(buf); 74 | 75 | textbuf.dependencyFileFormat(deps); 76 | auto r = textbuf[0 .. textbuf.length]; 77 | //writefln("|%s|", r); 78 | assert(r == 79 | "asdfasdf." ~ extObj ~ ": asdfasdf.d kjjksdkfj.d asdkjfksdfj.d asdfasdf0.d kjjksdkfj0.d \\ 80 | asdkjfksdfj0.d asdfasdf1.d kjjksdkfj1.d asdkjfksdfj1.d 81 | "); 82 | textbuf.free(); 83 | } 84 | 85 | 86 | /************************************* 87 | * Write dependencies to filename. 88 | */ 89 | void dependencyFileWrite(string filename, string[] deps) 90 | { 91 | auto f = File(filename, "w"); 92 | auto w = f.lockingTextWriter(); 93 | dependencyFileFormat(w, deps); 94 | } 95 | 96 | /* 97 | * Local Variables: 98 | * mode: d 99 | * c-basic-offset: 4 100 | * End: 101 | */ 102 | -------------------------------------------------------------------------------- /ranges.d: -------------------------------------------------------------------------------- 1 | 2 | /**** 3 | * Generic ranges not found in Phobos. 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | module ranges; 10 | 11 | /************** 12 | * BitBucket is an OutputRange that throws away its output. 13 | */ 14 | 15 | struct BitBucket(E) 16 | { 17 | static void put(E e) { } 18 | } 19 | 20 | /***************************************** 21 | */ 22 | 23 | struct EmptyInputRange(E) 24 | { 25 | enum bool empty = true; 26 | 27 | enum E front = E.init; 28 | 29 | static void popFront() { assert(0); } 30 | } 31 | 32 | /***************************************** 33 | */ 34 | 35 | struct StaticArrayBuffer(E, size_t N) 36 | { 37 | size_t i; 38 | E[N] arr = void; 39 | 40 | void initialize() { i = 0; } 41 | 42 | void put(E e) 43 | { 44 | if (i >= N) { 45 | detectedOverflow(); 46 | } 47 | arr[i] = e; 48 | ++i; 49 | } 50 | 51 | void put(E[] e) 52 | { 53 | if (i + e.length >= N + 1) { 54 | detectedOverflow(); 55 | } 56 | arr[i .. i + e.length] = e[]; 57 | i += e.length; 58 | } 59 | 60 | E[] opSlice() 61 | { 62 | return arr[0 .. i]; 63 | } 64 | 65 | @property size_t length() { return i; } 66 | 67 | private: 68 | void detectedOverflow() { 69 | import util; 70 | err_fatal("Buffer overflowed. Possibly caused by forgetting to " 71 | "complete a git merge in your code."); 72 | } 73 | } 74 | 75 | 76 | //import std.stdio; 77 | 78 | unittest 79 | { 80 | StaticArrayBuffer!(ubyte, 2) buf = void; 81 | buf.initialize(); 82 | buf.put('a'); 83 | buf.put('b'); 84 | //writefln("'%s'", buf.get()); 85 | assert(buf[] == "ab"); 86 | } 87 | 88 | unittest 89 | { 90 | ubyte[2] buf = void; 91 | size_t i; 92 | buf[i] = 'a'; 93 | ++i; 94 | buf[i] = 'b'; 95 | ++i; 96 | assert(buf[0 .. i] == "ab"); 97 | } 98 | 99 | /* 100 | * Local Variables: 101 | * mode: d 102 | * c-basic-offset: 4 103 | * End: 104 | */ 105 | -------------------------------------------------------------------------------- /run_tests.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | errors=0 4 | warp="warp -Iinclude -I." 5 | 6 | assert_eq() { 7 | if [ $1 -ne $2 ] 8 | then 9 | fail expected $2, got $1 10 | return 1 11 | fi 12 | } 13 | 14 | assert_equal() { 15 | if [ "$1" != "$2" ] 16 | then 17 | fail 18 | actualf=`mktemp` 19 | expectedf=`mktemp` 20 | echo "$1" > "$actualf" 21 | echo "$2" > "$expectedf" 22 | echo "--- EXPECTED" 23 | echo "+++ ACTUAL" 24 | diff -u "$expectedf" "$actualf" | tail -n +3 25 | return 1 26 | fi 27 | } 28 | 29 | fail() { 30 | if [ -n "$1" ] 31 | then 32 | echo "FAIL: $@" 33 | else 34 | echo FAIL 35 | fi 36 | errors=$((errors + 1)) 37 | } 38 | 39 | pass() { 40 | echo pass 41 | } 42 | 43 | cd tests 44 | 45 | printf 'comment_after_include...' 46 | err=`$warp --stdout comment_after_include.c 2>&1 > /dev/null` 47 | assert_equal "$err" "" && pass 48 | 49 | printf 'dollar_macro...' 50 | q_count=`$warp --stdout dollar_macro.S 2>&1 | egrep -c "[$]q"` 51 | assert_eq "$q_count" 1 && pass 52 | 53 | printf 'import...' 54 | foo_count=`$warp --stdout import.c | fgrep -c 'int foo'` 55 | assert_eq $foo_count 1 && pass 56 | 57 | printf 'include_guard...' 58 | foo_count=`$warp --stdout include_guard.c | fgrep -c 'int foo'` 59 | assert_eq $foo_count 1 && pass 60 | 61 | printf 'include_thrice...' 62 | foo_count=`$warp --stdout include_thrice.c | fgrep -c 'int foo'` 63 | assert_eq $foo_count 3 && pass 64 | 65 | printf 'missing_include...' 66 | err=`$warp --stdout include_nonexisting.c 2>&1 > /dev/null` 67 | assert_equal "$err" "In file included from include/include_nonexisting.h:2, 68 | from include_nonexisting.c:1: 69 | include/include_doesnotexist.h:1: #include file 'doesnotexist.h' not found" && pass 70 | 71 | printf 'pragma_once...' 72 | foo_count=`$warp --stdout pragma_once.c | fgrep -c 'int foo'` 73 | assert_eq $foo_count 1 && pass 74 | 75 | printf 'space_after_include...' 76 | err=`$warp --stdout space_after_include.cpp 2>&1 > /dev/null` 77 | assert_equal "$err" "" && pass 78 | 79 | if [ $errors -eq 0 ] 80 | then 81 | echo "All tests passed" 82 | else 83 | echo "$errors tests failed" 84 | exit 1 85 | fi 86 | -------------------------------------------------------------------------------- /skip.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | module skip; 10 | 11 | import std.ascii; 12 | import std.range; 13 | import std.traits; 14 | 15 | import std.stdio; 16 | import core.stdc.stdio; 17 | 18 | import macros : ESC; 19 | import util : err_fatal; 20 | import ranges; 21 | import context; 22 | import charclass; 23 | 24 | version (unittest) 25 | { 26 | bool err; 27 | void unittestError(T...)(T args) { err = true; } 28 | } 29 | 30 | /************** 31 | * Skip C++ style comment. 32 | * Input: 33 | * R range is on first character past // 34 | * Returns: 35 | * range starting at beginning of next line 36 | */ 37 | 38 | R skipCppComment(alias error = err_fatal, R)(R r) if (isInputRange!R) 39 | { 40 | static if (isContext!R) 41 | { 42 | // Take advantage of lookahead to speed up loop 43 | while (1) 44 | { 45 | auto a = r.lookAhead(); 46 | size_t n; 47 | while (n < a.length) 48 | { 49 | if (a[n] != '\n') 50 | ++n; 51 | else 52 | { 53 | r.popFrontN(n + 1); 54 | if (!r.empty) 55 | { 56 | r.front; 57 | r.popFront(); // to start of next line 58 | } 59 | return r; 60 | } 61 | } 62 | if (n) 63 | r.popFrontN(n); 64 | else if (!r.empty) 65 | { 66 | auto c = r.front; 67 | r.popFront(); 68 | if (c == '\n') 69 | return r; 70 | } 71 | else 72 | break; 73 | } 74 | } 75 | else 76 | { 77 | while (!r.empty) 78 | { 79 | auto c = r.front; 80 | r.popFront(); 81 | if (c == '\n') 82 | return r; 83 | } 84 | } 85 | error("// comment is not closed with newline"); 86 | return r; 87 | } 88 | 89 | unittest 90 | { 91 | auto r = "456\n89".skipCppComment(); 92 | assert(!r.empty && r.front == '8'); 93 | 94 | err = false; 95 | r = "45689".skipCppComment!unittestError(); 96 | assert(err); 97 | } 98 | 99 | /************** 100 | * Skip C style comment. 101 | * Input: 102 | * R range is on first character past / * 103 | * Returns: 104 | * range starting after closing * / 105 | */ 106 | 107 | R skipCComment(alias error = err_fatal, R)(R r) if (isInputRange!R) 108 | { 109 | static if (isContext!R) 110 | { 111 | // Take advantage of lookahead to speed up loop 112 | while (!r.empty) 113 | { 114 | auto c = r.front; 115 | if (c == '*') 116 | { 117 | r.popFront(); 118 | if (r.empty) 119 | break; 120 | if (r.front == '/') 121 | { 122 | r.popFront(); 123 | return r; 124 | } 125 | } 126 | else 127 | { 128 | auto a = r.lookAhead(); 129 | size_t n; 130 | while (n + 1 < a.length) 131 | { 132 | if (a[n] != '*' || a[n + 1] != '/') 133 | ++n; 134 | else 135 | { 136 | r.popFrontN(n + 2); 137 | if (!r.empty) 138 | { 139 | r.front; 140 | r.popFront(); 141 | } 142 | return r; 143 | } 144 | } 145 | if (n) 146 | r.popFrontN(n); 147 | else 148 | r.popFront(); 149 | } 150 | } 151 | } 152 | else 153 | { 154 | outer: 155 | for (;;) 156 | { 157 | if (r.empty) 158 | break; 159 | for (;;) 160 | { 161 | if (r.front != '*') 162 | { 163 | // Short path 164 | r.popFront(); 165 | break; 166 | } 167 | r.popFront(); 168 | if (r.empty) 169 | break outer; 170 | if (r.front == '/') 171 | { 172 | r.popFront(); 173 | return r; 174 | } 175 | } 176 | } 177 | } 178 | error("/* comment is not closed with */"); 179 | assert(0); 180 | } 181 | 182 | unittest 183 | { 184 | string s = "45/*6* /*/89"; 185 | auto r = s.skipCComment(); 186 | assert(!r.empty && r.front == '8'); 187 | } 188 | 189 | /**************************** 190 | * Skip character literal. 191 | * Input: 192 | * R range is on first character past ' 193 | * Returns: 194 | * range starting after closing ' 195 | */ 196 | 197 | R skipCharacterLiteral(alias error = err_fatal, R, S)(R r, ref S s) 198 | if (isInputRange!R && isOutputRange!(S,ElementEncodingType!R)) 199 | { 200 | bool slash; 201 | while (!r.empty) 202 | { 203 | auto c = cast(ElementEncodingType!R)r.front; 204 | s.put(c); 205 | r.popFront(); 206 | switch (c) 207 | { 208 | case '\\': 209 | slash = !slash; 210 | break; 211 | 212 | case '\'': 213 | if (!slash) 214 | return r; 215 | goto default; 216 | default: 217 | slash = false; 218 | break; 219 | } 220 | } 221 | error("character literal is not closed with '"); 222 | return r; 223 | } 224 | 225 | unittest 226 | { 227 | BitBucket!char b = void; 228 | 229 | string s = "456\\\\'x"; 230 | auto r = s.skipCharacterLiteral(b); 231 | assert(!r.empty && r.front == 'x'); 232 | 233 | StaticArrayBuffer!(char,100) a = void; 234 | a.initialize(); 235 | 236 | r = "asdf\\'a'b".skipCharacterLiteral(a); 237 | assert(!r.empty && r.front == 'b'); 238 | assert(a[] == "asdf\\'a'"); 239 | } 240 | 241 | 242 | /**************************** 243 | * Skip string literal. 244 | * Input: 245 | * R range is on first character past " 246 | * Returns: 247 | * range starting after closing " 248 | */ 249 | 250 | R skipStringLiteral(alias error = err_fatal, R, S)(R r, ref S s) 251 | if (isInputRange!R && isOutputRange!(S,ElementEncodingType!R)) 252 | { 253 | bool slash; 254 | while (!r.empty) 255 | { 256 | auto c = cast(ElementEncodingType!R)r.front; 257 | s.put(c); 258 | r.popFront(); 259 | switch (c) 260 | { 261 | case '\\': 262 | slash = !slash; 263 | break; 264 | 265 | case '"': 266 | if (!slash) 267 | return r; 268 | goto default; 269 | default: 270 | slash = false; 271 | break; 272 | } 273 | } 274 | error("string literal is not closed with \""); 275 | return r; 276 | } 277 | 278 | unittest 279 | { 280 | BitBucket!char b = void; 281 | 282 | string s = "456\\\\\"x"; 283 | auto r = s.skipStringLiteral(b); 284 | assert(!r.empty && r.front == 'x'); 285 | 286 | StaticArrayBuffer!(char,100) a = void; 287 | a.initialize(); 288 | 289 | r = "asdf\\\"a\"b".skipStringLiteral(a); 290 | assert(!r.empty && r.front == 'b'); 291 | //writefln("a = |%s|", a[]); 292 | assert(a[] == "asdf\\\"a\""); 293 | } 294 | 295 | 296 | /************** 297 | * Skip raw string literal. 298 | * Input: 299 | * R range is on first character past R" 300 | * Returns: 301 | * range starting after closing " 302 | */ 303 | 304 | R skipRawStringLiteral(alias error = err_fatal, R, S)(R r, ref S s) 305 | if (isInputRange!R && isOutputRange!(S,ElementEncodingType!R)) 306 | { 307 | enum RAW { start, string, end } 308 | 309 | RAW rawstate = RAW.start; 310 | 311 | alias Unqual!(ElementEncodingType!R) E; 312 | E[16 + 1] dcharbuf = void; 313 | size_t dchari = 0; 314 | 315 | while (!r.empty) 316 | { 317 | auto c = cast(E)r.front; 318 | s.put(c); 319 | r.popFront(); 320 | 321 | final switch (rawstate) 322 | { 323 | case RAW.start: 324 | if (c == '(') // end of d-char-string 325 | { 326 | dcharbuf[dchari] = 0; 327 | rawstate = RAW.string; 328 | } 329 | else if (c == ' ' || c == '(' || c == ')' || 330 | c == '\\' || c == '\t' || c == '\v' || 331 | c == '\f' || c == '\n' || c == '\r') 332 | { 333 | error("invalid dchar '%s'", c); 334 | return r; 335 | } 336 | else if (dchari >= dcharbuf.length) 337 | { 338 | error("dchar string maximum of %s is exceeded", dcharbuf.length); 339 | return r; 340 | } 341 | else 342 | { 343 | dcharbuf[dchari] = c; 344 | ++dchari; 345 | } 346 | break; 347 | 348 | case RAW.string: 349 | if (c == ')') 350 | { 351 | dchari = 0; 352 | rawstate = RAW.end; 353 | } 354 | break; 355 | 356 | case RAW.end: 357 | if (c == dcharbuf[dchari]) 358 | { 359 | ++dchari; 360 | } 361 | else if (dcharbuf[dchari] == 0) 362 | { 363 | if (c == '"') 364 | return r; 365 | else 366 | { 367 | rawstate = RAW.string; 368 | goto case RAW.string; 369 | } 370 | } 371 | else if (c == ')') 372 | { 373 | // Rewind ')' dcharbuf[0..dchari] 374 | dchari = 0; 375 | } 376 | else 377 | { 378 | // Rewind ')' dcharbuf[0..dchari] 379 | rawstate = RAW.string; 380 | } 381 | break; 382 | } 383 | } 384 | error("raw string literal is not closed"); 385 | return r; 386 | } 387 | 388 | unittest 389 | { 390 | StaticArrayBuffer!(char,100) a = void; 391 | a.initialize(); 392 | 393 | auto r = "a(bcd\")b\")a\"e".skipRawStringLiteral(a); 394 | assert(!r.empty && r.front == 'e'); 395 | assert(a[] == "a(bcd\")b\")a\""); 396 | 397 | a.initialize(); 398 | r = "(([^\\s]*)\\s+(.*))\"e".skipRawStringLiteral(a); 399 | assert(!r.empty && r.front == 'e'); 400 | assert(a[] == "(([^\\s]*)\\s+(.*))\""); 401 | } 402 | 403 | 404 | /************** 405 | * Skip white space, where whitespace is: 406 | * space, tab, carriage return, C comment, C++ comment 407 | * Input: 408 | * R range is on first character 409 | * Returns: 410 | * range starting at first character following whitespace 411 | */ 412 | 413 | R skipWhitespace(alias error = err_fatal, R)(R r) if (isInputRange!R) 414 | { 415 | alias Unqual!(ElementType!R) E; 416 | 417 | E lastc = ' '; 418 | while (!r.empty) 419 | { 420 | E c = r.front; 421 | switch (c) 422 | { 423 | case ' ': 424 | case '\t': 425 | case '\r': 426 | break; 427 | 428 | case '/': 429 | if (lastc == '/') 430 | { 431 | r.popFront(); 432 | r = r.skipCppComment!error(); 433 | c = ' '; 434 | continue; 435 | } 436 | break; 437 | 438 | case '*': 439 | if (lastc == '/') 440 | { 441 | r.popFront(); 442 | r = r.skipCComment!error(); 443 | c = ' '; 444 | continue; 445 | } 446 | break; 447 | 448 | default: 449 | return r; 450 | } 451 | lastc = c; 452 | r.popFront(); 453 | } 454 | return r; 455 | } 456 | 457 | unittest 458 | { 459 | auto r = (cast(immutable(ubyte)[])" \t\r/* */8").skipWhitespace(); 460 | assert(!r.empty && r.front == '8'); 461 | 462 | r = (cast(immutable(ubyte)[])" // \n8").skipWhitespace(); 463 | assert(!r.empty && r.front == '8'); 464 | 465 | r = (cast(immutable(ubyte)[])"*").skipWhitespace(); 466 | assert(r.empty); 467 | } 468 | 469 | 470 | /************************************************** 471 | * Reads in an identifier. 472 | * Output: 473 | * s OutputRange to write identifier to 474 | * Returns: 475 | * range after identifier 476 | * BUGS: doesn't handle \u, \U or Unicode chars, doesn't do Unicode decoding 477 | */ 478 | 479 | 480 | R inIdentifier(R, S)(R r, ref S s) 481 | if (isInputRange!R && isOutputRange!(S,Unqual!(ElementEncodingType!R))) 482 | { 483 | static if (isContext!R) 484 | { 485 | /* Take advantage of knowledge of Context to work with a bunch of 486 | * characters at once rather than one at a time. Much faster. 487 | */ 488 | while (1) 489 | { 490 | auto c = cast(ElementEncodingType!R)r.front; 491 | if (isIdentifierChar(c)) 492 | { 493 | s.put(c); 494 | if (r.expanded.noexpand) 495 | { 496 | auto a = r.lookAhead(); 497 | size_t n; 498 | while (n < a.length) 499 | { 500 | if (isIdentifierChar(a[n])) 501 | ++n; 502 | else 503 | break; 504 | } 505 | if (n) 506 | { 507 | s.put(a[0 .. n]); 508 | r.popFrontN(n); 509 | if (n < a.length) 510 | { 511 | r.popFront(); 512 | break; 513 | } 514 | } 515 | } 516 | } 517 | else 518 | { 519 | break; 520 | } 521 | r.popFront(); 522 | } 523 | } 524 | else 525 | { 526 | while (!r.empty) 527 | { 528 | auto c = cast(ElementEncodingType!R)r.front; 529 | if (isIdentifierChar(c)) 530 | { 531 | s.put(c); 532 | } 533 | else 534 | { 535 | break; 536 | } 537 | r.popFront(); 538 | } 539 | } 540 | return r; 541 | } 542 | 543 | unittest 544 | { 545 | { 546 | StaticArrayBuffer!(char, 1024) id = void; 547 | id.initialize(); 548 | auto r = "abZ123_ 3".inIdentifier(id); 549 | assert(!r.empty && r.front == ' ' && id[] == "abZ123_"); 550 | } 551 | { 552 | StaticArrayBuffer!(ubyte, 1024) id = void; 553 | id.initialize(); 554 | auto r = (cast(immutable(ubyte)[])"abZ123_ 3").inIdentifier(id); 555 | assert(!r.empty && r.front == ' ' && id[] == "abZ123_"); 556 | } 557 | } 558 | 559 | 560 | /************************************************** 561 | * Skip to the start of the next line. 562 | */ 563 | 564 | R skipToEndOfLine(R)(R r) if (isInputRange!R) 565 | { 566 | while (!r.empty) 567 | { 568 | auto c = r.front; 569 | r.popFront(); 570 | if (c == '\n') 571 | break; 572 | } 573 | return r; 574 | } 575 | 576 | unittest 577 | { 578 | string s = "abc\ndef"; 579 | auto r = s.skipToEndOfLine(); 580 | assert(!r.empty && r.front == 'd'); 581 | } 582 | 583 | /************************************************** 584 | * Skip to the start of the next line - the rest of the current line 585 | * should be blank. 586 | */ 587 | 588 | R skipBlankLine(R)(R r) if (isInputRange!R) 589 | { 590 | while (!r.empty) 591 | { 592 | auto c = r.front; 593 | r.popFront(); 594 | switch (c) 595 | { 596 | case '\n': 597 | break; 598 | 599 | case ' ': 600 | case '\t': 601 | case '\v': 602 | case '\f': 603 | case '\r': 604 | case ESC.space: 605 | case ESC.brk: 606 | continue; 607 | 608 | case '/': 609 | if (r.empty) 610 | break; 611 | auto c2 = r.front; 612 | r.popFront(); 613 | if (c2 == '*') 614 | { 615 | r = r.skipCComment(); 616 | continue; 617 | } 618 | else if (c2 == '/') 619 | { 620 | return r.skipCppComment(); 621 | } 622 | goto default; 623 | 624 | default: 625 | // The line isn't blank, which is an error according to the Standard 626 | return r.skipToEndOfLine(); 627 | } 628 | break; 629 | } 630 | return r; 631 | } 632 | 633 | unittest 634 | { 635 | auto s = cast(immutable(ubyte)[])(" \t\v\f" ~ ESC.space ~ ESC.brk ~ " /* abc */\ndef"); 636 | auto r = s.skipBlankLine(); 637 | assert(!r.empty && r.front == 'd'); 638 | 639 | auto s2 = " //C++ comment\nd"; 640 | auto r2 = s2.skipBlankLine(); 641 | assert(!r2.empty && r2.front == 'd'); 642 | 643 | s2 = " \nd"; 644 | r2 = s2.skipBlankLine(); 645 | assert(!r2.empty && r2.front == 'd'); 646 | 647 | s2 = " "; 648 | r2 = s2.skipBlankLine(); 649 | assert(r2.empty); 650 | 651 | s2 = " /"; 652 | r2 = s2.skipBlankLine(); 653 | assert(r2.empty); 654 | 655 | s2 = " /a"; 656 | r2 = s2.skipBlankLine(); 657 | assert(r2.empty); 658 | 659 | s2 = " a"; 660 | r2 = s2.skipBlankLine(); 661 | assert(r2.empty); 662 | } 663 | 664 | /* 665 | * Local Variables: 666 | * mode: d 667 | * c-basic-offset: 4 668 | * End: 669 | */ 670 | -------------------------------------------------------------------------------- /sources.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | // Deals with source file I/O 10 | 11 | module sources; 12 | 13 | import core.memory; 14 | import core.stdc.stdlib; 15 | import std.file; 16 | import file; 17 | import std.path; 18 | import std.stdio; 19 | import std.string; 20 | 21 | import util; 22 | import textbuf; 23 | 24 | /********************************* 25 | * Things to know about source files. 26 | */ 27 | 28 | struct SrcFile 29 | { 30 | string filename; // fully qualified file name 31 | ustring contents; // contents of the file 32 | ustring includeGuard; // macro #define used for #include guard 33 | bool once; // set if #pragma once set 34 | bool doesNotExist; // file does not exist 35 | bool cachedRead; // read a cached version 36 | 37 | __gshared SrcFile[string] table; 38 | 39 | /************************************** 40 | * Look up filename in table[]. 41 | * If it isn't there, insert it. 42 | * Input: 43 | * filename the file name 44 | * tmp if filename needs to be dup'd 45 | * Returns: 46 | * SrcFile* (never null) 47 | */ 48 | static SrcFile* lookup(const(char)[] filename, bool tmp = false) 49 | { 50 | auto p = cast(string)filename in table; 51 | if (!p) 52 | { 53 | SrcFile sf; 54 | sf.filename = tmp ? filename.idup : cast(string)filename; 55 | table[sf.filename] = sf; 56 | p = filename in table; 57 | } 58 | return p; 59 | } 60 | 61 | /******************************* 62 | * Reset in between processing source files 63 | */ 64 | static void reset() 65 | { 66 | foreach (ref sf; table) 67 | { 68 | /* Just need to reset 'once', otherwise the files 69 | * will be skipped instead of read. 70 | */ 71 | sf.once = false; 72 | sf.cachedRead = false; 73 | } 74 | } 75 | 76 | /******************************* 77 | * Release the contents of this source file. 78 | * It'll get re-read if needed. 79 | */ 80 | void freeContents() 81 | { 82 | myReadFree(cast(void[]) contents); 83 | contents = null; 84 | } 85 | 86 | /******************************* 87 | * Read a file and set its contents. 88 | */ 89 | bool read() 90 | { 91 | if (doesNotExist) 92 | return false; 93 | 94 | if (contents) 95 | { cachedRead = true; 96 | return true; // already read 97 | } 98 | 99 | bool result = true; 100 | contents = cast(ustring)file.myRead(filename); 101 | if (contents.ptr == null) 102 | { 103 | result = false; 104 | doesNotExist = true; 105 | } 106 | return result; 107 | } 108 | } 109 | 110 | /********************************* 111 | * Search for file along paths[]. 112 | * Cache results. 113 | * Input: 114 | * filename file to look for (in a tmp buffer) 115 | * paths[] search paths 116 | * starti start searching at paths[starti] 117 | * currentPath if !null, then the path to the enclosing file 118 | * Output: 119 | * foundi paths[index] is where the file was found, 120 | * paths.length if not in paths[] 121 | * Returns: 122 | * fully qualified filename if found, null if not 123 | */ 124 | 125 | SrcFile* fileSearch(const(char)[] filename, const string[] paths, int starti, out int foundi, 126 | string currentPath) 127 | { 128 | //writefln("fileSearch(filename='%s', starti=%s, currentPath='%s')", filename, starti, currentPath); 129 | //foreach (i,path; paths) writefln(" [%s] '%s'", i, path); 130 | 131 | foundi = cast(int)paths.length; 132 | 133 | filename = strip(filename); 134 | SrcFile* sf; 135 | 136 | char[120] tmpbuf = void; 137 | auto buf = Textbuf!char(tmpbuf); 138 | 139 | if (isRooted(filename)) 140 | { 141 | sf = SrcFile.lookup(filename, true); 142 | if (!sf.read()) 143 | return null; 144 | } 145 | else 146 | { 147 | if (currentPath) 148 | { 149 | buf.initialize(); 150 | buf.myBuildPath(currentPath, filename); 151 | sf = SrcFile.lookup(buf[], true); 152 | if (sf.read()) 153 | { 154 | goto L1; 155 | } 156 | } 157 | if (starti < paths.length) 158 | { 159 | foreach (key, path; paths[starti .. $]) 160 | { 161 | buf.initialize(); 162 | buf.myBuildPath(path, filename); 163 | //writefln("path = '%s', filename = '%s', buf[] = '%s'", path, filename, buf[]); 164 | sf = SrcFile.lookup(buf[], true); 165 | if (sf.read()) 166 | { foundi = cast(int)(starti + key); 167 | goto L1; 168 | } 169 | } 170 | } 171 | buf.free(); 172 | return null; 173 | } 174 | L1: 175 | auto normfilename = buildNormalizedPath(sf.filename); 176 | if (filenameCmp(normfilename, sf.filename)) 177 | { // Cache the normalized file name as a clone of the original unnormalized one 178 | auto sf2 = SrcFile.lookup(normfilename); 179 | if (!sf2.contents) 180 | sf2.contents = sf.contents; 181 | if (!sf2.includeGuard) 182 | sf2.includeGuard = sf.includeGuard; 183 | sf2.once |= sf.once; 184 | sf2.doesNotExist |= sf.doesNotExist; 185 | sf = sf2; 186 | } 187 | buf.free(); 188 | return sf; 189 | } 190 | 191 | /******************************************* 192 | * Create our own version of std.path.buildPath() that writes to an output range 193 | * instead of allocating memory. 194 | */ 195 | 196 | void myBuildPath(R)(ref R buf, const(char)[] seg1, const(char)[] seg2) 197 | { 198 | char sep; 199 | foreach (char c; seg1) 200 | { sep = c; 201 | buf.put(c); 202 | } 203 | if (!isDirSeparator(sep)) 204 | buf.put(dirSeparator[0]); 205 | foreach (char c; seg2) 206 | { 207 | buf.put(c); 208 | } 209 | } 210 | 211 | /* 212 | * Local Variables: 213 | * mode: d 214 | * c-basic-offset: 4 215 | * End: 216 | */ 217 | -------------------------------------------------------------------------------- /stringlit.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | module stringlit; 10 | 11 | import std.array; 12 | import std.range; 13 | import std.stdio; 14 | import std.traits; 15 | import std.utf; 16 | 17 | import lexer; 18 | import util; 19 | import macros; 20 | import ranges; 21 | 22 | // Kind of string literal 23 | enum STR 24 | { 25 | s, // default 26 | f, // #include string, i.e. no special meaning for \ character 27 | L, // wchar_t 28 | u8, // UTF-8 29 | u, // wchar 30 | U // dchar 31 | } 32 | 33 | /***************************************** 34 | * Read in a string literal. 35 | * Input: 36 | * tc string terminating character, which is one of ', " or > 37 | * Output: 38 | * bytes written to s 39 | */ 40 | 41 | R lexStringLiteral(R, S)(R r, ref S s, char tc, STR str) 42 | { 43 | alias Unqual!(ElementEncodingType!R) E; 44 | 45 | /* Read \0, \x, \u and \U digit sequences 46 | */ 47 | dchar readRadix(int radix, int ndigits) 48 | { 49 | int n = 0; 50 | dchar d = 0; 51 | do 52 | { 53 | if (r.empty) 54 | break; 55 | E c = cast(E)r.front; 56 | uint i = 32; 57 | if (c >= '0' && c <= '9') 58 | i = c - '0'; 59 | else if (c >= 'A' && c <= 'F') 60 | i = c + 10 - 'A'; 61 | else if (c >= 'a' && c <= 'f') 62 | i = c + 10 - 'a'; 63 | if (i >= radix) 64 | { 65 | if (n == 0 || ndigits >= 4) 66 | err_fatal("radix %s digit expected, saw '%c'", radix, c); 67 | break; 68 | } 69 | d = d * radix + i; 70 | r.popFront(); 71 | } while (++n < ndigits); 72 | 73 | /* Don't worry about disallowed Universal characters, as they 74 | * vary from Standard to Standard, and we want this to work with 75 | * all of them. 76 | */ 77 | return d; 78 | } 79 | 80 | bool slash; 81 | while (!r.empty) 82 | { 83 | E c = cast(E)r.front; 84 | dchar d = c; 85 | switch (c) 86 | { 87 | case '"': 88 | case '\'': 89 | case '>': 90 | if (c == tc && !slash) 91 | { 92 | r.popFront(); 93 | return r; 94 | } 95 | goto default; 96 | 97 | case ESC.space: 98 | case ESC.brk: // token separator 99 | r.popFront(); 100 | break; 101 | 102 | case '\\': 103 | if (str == STR.f) // ignore escapes in #include strings 104 | goto default; 105 | Lslash: 106 | /* Escape sequences 107 | */ 108 | r.popFront(); 109 | if (r.empty) 110 | goto Lerror; 111 | c = cast(E)r.front; 112 | switch (c) 113 | { 114 | case '\r': 115 | goto Lslash; 116 | 117 | case '\n': 118 | r.popFront(); 119 | continue; 120 | 121 | case '"': 122 | case '\'': 123 | case '\\': 124 | case '?': d = c; break; 125 | case 'a': d = '\a'; break; 126 | case 'b': d = '\b'; break; 127 | case 'f': d = '\f'; break; 128 | case 'n': d = '\n'; break; 129 | case 'r': d = '\r'; break; 130 | case 't': d = '\t'; break; 131 | case 'v': d = '\v'; break; 132 | 133 | case '0': .. case '7': // \nnn octal 134 | d = readRadix(8, 3); 135 | if (d >= 0x100) 136 | err_fatal("octal escape exceeds 0xFF"); 137 | goto Lput; 138 | 139 | case 'x': // \xnn hex 140 | r.popFront(); 141 | d = readRadix(16, 2); 142 | goto Lput; 143 | 144 | case 'u': // \unnnn hex 145 | r.popFront(); 146 | d = readRadix(16, 4); 147 | goto Lput; 148 | 149 | case 'U': // \Unnnnnnnn hex 150 | r.popFront(); 151 | d = readRadix(16, 8); 152 | goto Lput; 153 | 154 | default: 155 | err_fatal("invalid escape sequence"); 156 | break; 157 | } 158 | goto default; 159 | 160 | default: 161 | r.popFront(); 162 | Lput: 163 | /* Stuff d into the output buffer, how it is done 164 | * depends on the kind of string literal being built. 165 | */ 166 | final switch (str) 167 | { 168 | case STR.s: 169 | case STR.f: 170 | s.put(cast(E)d); 171 | break; 172 | 173 | case STR.u8: 174 | { 175 | char[4] buf = void; 176 | size_t len = std.utf.encode(buf, d); 177 | foreach (chr; buf[0 .. len]) 178 | s.put(chr); 179 | break; 180 | } 181 | 182 | case STR.L: 183 | s.put(cast(E)d); 184 | s.put(cast(E)(d >> 8)); 185 | version (Windows) 186 | { 187 | } 188 | else 189 | { 190 | s.put(cast(E)(d >> 16)); 191 | s.put(cast(E)(d >> 24)); 192 | } 193 | break; 194 | 195 | case STR.u: 196 | { 197 | wchar[2] buf = void; 198 | size_t len = std.utf.encode(buf, d); 199 | foreach (chr; (cast(E*)buf.ptr)[0 .. len * wchar.sizeof]) 200 | s.put(chr); 201 | break; 202 | } 203 | 204 | case STR.U: 205 | s.put(cast(E)d); 206 | s.put(cast(E)(d >> 8)); 207 | s.put(cast(E)(d >> 16)); 208 | s.put(cast(E)(d >> 24)); 209 | break; 210 | } 211 | slash = false; 212 | break; 213 | } 214 | } 215 | Lerror: 216 | err_fatal("string literal is not closed with %s", tc); 217 | return r; 218 | } 219 | 220 | unittest 221 | { 222 | StaticArrayBuffer!(char, 100) buf = void; 223 | 224 | buf.initialize(); 225 | auto r = `abc"`.lexStringLiteral(buf, '"', STR.s); 226 | assert(r.empty && buf[] == "abc"); 227 | 228 | buf.initialize(); 229 | r = `\\\"\'\?\a\b\f\n\r\t\v"`.lexStringLiteral(buf, '"', STR.s); 230 | assert(r.empty && buf[] == "\\\"\'\?\a\b\f\n\r\t\v"); 231 | 232 | buf.initialize(); 233 | r = `\0x\1773"`.lexStringLiteral(buf, '"', STR.s); 234 | assert(r.empty && buf[] == "\0x\1773"); 235 | 236 | buf.initialize(); 237 | r = `\xa\xAFc"`.lexStringLiteral(buf, '"', STR.s); 238 | //writefln("|%s|", buf[]); 239 | assert(r.empty && buf[] == "\x0a\xafc"); 240 | 241 | buf.initialize(); 242 | r = `\uabcdc"`.lexStringLiteral(buf, '"', STR.u); 243 | assert(r.empty && buf.length == 4 && buf[][0] == 0xCD && 244 | buf[][1] == 0xAB && 245 | buf[][2] == 'c' && 246 | buf[][3] == 0x00); 247 | 248 | buf.initialize(); 249 | r = `\U000DEF01c"`.lexStringLiteral(buf, '"', STR.U); 250 | //writef("%d:", buf.length); 251 | //foreach (c; 0..buf.length) writef(" %02x", buf[][c]); 252 | //writeln(); 253 | assert(r.empty && buf.length == 8 && buf[][0] == 0x01 && 254 | buf[][1] == 0xEF && 255 | buf[][2] == 0x0D && 256 | buf[][3] == 0x00 && 257 | buf[][4] == 'c' && 258 | buf[][5] == 0x00 && 259 | buf[][6] == 0x00 && 260 | buf[][7] == 0x00); 261 | } 262 | 263 | /******************************************* 264 | * Lex a character literal, and convert it to an integer i. 265 | */ 266 | 267 | R lexCharacterLiteral(R)(R r, ref ppint_t i, STR str) 268 | { 269 | alias Unqual!(ElementEncodingType!R) E; 270 | 271 | StaticArrayBuffer!(E, 100) buf; 272 | buf.initialize(); 273 | 274 | r = r.lexStringLiteral(buf, '\'', str); 275 | 276 | E[] a = buf[]; 277 | 278 | size_t n; 279 | final switch (str) 280 | { 281 | case STR.s: 282 | case STR.u8: 283 | n = a.length; 284 | if (n == 1) // most common case 285 | { 286 | i = a[0]; 287 | return r; 288 | } 289 | if (n > ppint_t.sizeof) 290 | err_fatal("too many characters in literal"); 291 | else 292 | { 293 | E* p = cast(E*)(&i) + n; 294 | foreach (c; a[0 .. n]) 295 | *--p = c; 296 | } 297 | break; 298 | 299 | case STR.L: 300 | version (Windows) 301 | { 302 | i = *cast(ushort*)a.ptr; 303 | } 304 | else 305 | { 306 | i = *cast(uint*)a.ptr; 307 | } 308 | break; 309 | 310 | case STR.u: 311 | i = *cast(ushort*)a.ptr; 312 | break; 313 | 314 | case STR.U: 315 | i = *cast(uint*)a.ptr; 316 | break; 317 | 318 | case STR.f: 319 | assert(0); 320 | } 321 | 322 | return r; 323 | } 324 | 325 | unittest 326 | { 327 | ppint_t n; 328 | { 329 | auto r = `a'`.lexCharacterLiteral(n, STR.s); 330 | assert(r.empty && n == 'a'); 331 | } 332 | { 333 | auto r = `ab'`.lexCharacterLiteral(n, STR.s); 334 | assert(r.empty && n == 0x6162); 335 | } 336 | } 337 | 338 | /* 339 | * Local Variables: 340 | * mode: d 341 | * c-basic-offset: 4 342 | * End: 343 | */ 344 | -------------------------------------------------------------------------------- /tests/comment_after_include.c: -------------------------------------------------------------------------------- 1 | #include /* comment */ 2 | #include "guard.h"// comment 3 | -------------------------------------------------------------------------------- /tests/dollar_macro.S: -------------------------------------------------------------------------------- 1 | #define M q 2 | $M 3 | -------------------------------------------------------------------------------- /tests/import.c: -------------------------------------------------------------------------------- 1 | #import "foo.h" 2 | #import 3 | #import "include/foo.h" 4 | -------------------------------------------------------------------------------- /tests/include/foo.h: -------------------------------------------------------------------------------- 1 | int foo() { return 42; } 2 | -------------------------------------------------------------------------------- /tests/include/guard.h: -------------------------------------------------------------------------------- 1 | #ifndef GUARD_H 2 | #define GUARD_H 3 | 4 | int foo() { return 42; } 5 | 6 | #endif /* ndef GUARD_H */ 7 | -------------------------------------------------------------------------------- /tests/include/include_doesnotexist.h: -------------------------------------------------------------------------------- 1 | #include "doesnotexist.h" 2 | -------------------------------------------------------------------------------- /tests/include/include_nonexisting.h: -------------------------------------------------------------------------------- 1 | #include "once.h" 2 | #include "include_doesnotexist.h" 3 | #if 0 4 | # define something 5 | #endif 6 | -------------------------------------------------------------------------------- /tests/include/once.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | int foo() { return 42; } 4 | -------------------------------------------------------------------------------- /tests/include_guard.c: -------------------------------------------------------------------------------- 1 | #include "guard.h" 2 | #include 3 | #include "include/guard.h" 4 | -------------------------------------------------------------------------------- /tests/include_nonexisting.c: -------------------------------------------------------------------------------- 1 | #include "include_nonexisting.h" 2 | -------------------------------------------------------------------------------- /tests/include_thrice.c: -------------------------------------------------------------------------------- 1 | #include "foo.h" 2 | #include 3 | #include "include/foo.h" 4 | -------------------------------------------------------------------------------- /tests/pragma_once.c: -------------------------------------------------------------------------------- 1 | #include "once.h" 2 | #include 3 | #include "include/once.h" 4 | -------------------------------------------------------------------------------- /tests/space_after_include.cpp: -------------------------------------------------------------------------------- 1 | #include "foo.h" 2 | -------------------------------------------------------------------------------- /textbuf.d: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * C preprocessor 4 | * Copyright: 2013 by Digital Mars 5 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 | * Authors: Walter Bright 7 | */ 8 | 9 | module textbuf; 10 | 11 | import core.stdc.stdlib; 12 | import core.stdc.string; 13 | import std.stdio; 14 | 15 | /************************************** 16 | * Textbuf encapsulates using a local array as a buffer. 17 | * It is initialized with the local array that should be large enough for 18 | * most uses. If the need exceeds the size, it will resize it 19 | * using malloc() and friends. 20 | */ 21 | 22 | //debug=Textbuf; 23 | 24 | struct Textbuf(T, string id = null) 25 | { 26 | this(T[] buf) 27 | { 28 | assert(!(buf.length & RESIZED)); 29 | this.buf = buf.ptr; 30 | this.buflen = cast(uint)buf.length - 2; // 1 for storing past end, 1 for RESIZED 31 | } 32 | 33 | void put(T c) 34 | { 35 | const j = i; 36 | buf[j] = c; 37 | i = j + 1; 38 | if (j == buflen) 39 | { 40 | resize(j * 2 + 16); 41 | } 42 | } 43 | 44 | static if (T.sizeof == 1) 45 | { 46 | void put(dchar c) 47 | { 48 | put(cast(T)c); 49 | } 50 | 51 | void put(const(T)[] s) 52 | { 53 | const newlen = i + s.length; 54 | const len = buflen; 55 | if (newlen > len) 56 | resize(newlen <= len * 2 ? len * 2 : newlen); 57 | buf[i .. newlen] = s[]; 58 | i = cast(uint)newlen; 59 | } 60 | } 61 | 62 | /****** 63 | * Use this to retrieve the result. 64 | */ 65 | T[] opSlice(size_t lwr, size_t upr) pure 66 | { 67 | assert(lwr <= buflen); 68 | assert(upr <= buflen); 69 | assert(lwr <= upr); 70 | return buf[lwr .. upr]; 71 | } 72 | 73 | T[] opSlice() pure 74 | { 75 | assert(i <= buflen); 76 | return buf[0 .. i]; 77 | } 78 | 79 | T opIndex(size_t i) const pure 80 | { 81 | assert(i < buflen); 82 | return buf[i]; 83 | } 84 | 85 | void initialize() pure { i = 0; } 86 | 87 | T last() const pure 88 | { 89 | assert(i - 1 < buflen); 90 | return buf[i - 1]; 91 | } 92 | 93 | T pop() pure 94 | { 95 | assert(i - 1 < buflen); 96 | return buf[--i]; 97 | } 98 | 99 | @property size_t length() const pure 100 | { 101 | return i; 102 | } 103 | 104 | void setLength(size_t i) pure 105 | { 106 | assert(i < buflen); 107 | this.i = cast(uint)i; 108 | } 109 | 110 | /************************** 111 | * Release any malloc'd data. 112 | */ 113 | void free() 114 | { 115 | debug(Textbuf) buf[0 .. buflen] = 0; 116 | if (buflen & RESIZED) 117 | .free(buf); 118 | this = this.init; 119 | } 120 | 121 | private: 122 | T* buf; 123 | uint buflen; 124 | enum RESIZED = 1; // this bit is set in buflen if we control the memory 125 | uint i; 126 | 127 | void resize(size_t newsize) 128 | { 129 | //writefln("%s: oldsize %s newsize %s %s", id, buflen, newsize, &this); 130 | void* p; 131 | if (buflen & RESIZED) 132 | { 133 | /* Prefer realloc when possible 134 | */ 135 | p = realloc(buf, (newsize + 2) * T.sizeof); 136 | assert(p); 137 | } 138 | else 139 | { 140 | assert(i < newsize + 2); 141 | p = malloc((newsize + 2) * T.sizeof); 142 | assert(p); 143 | memcpy(p, buf, i * T.sizeof); 144 | debug(Textbuf) buf[0 .. buflen] = 0; 145 | } 146 | buf = cast(T*)p; 147 | buflen = cast(uint)newsize | RESIZED; 148 | 149 | /* Fake loop to prevent inlining. This function is called only rarely, 150 | * inlining results in poorer register allocation. 151 | */ 152 | while (1) { break; } 153 | } 154 | } 155 | 156 | unittest 157 | { 158 | char[4] buf = void; 159 | auto textbuf = Textbuf!char(buf); 160 | textbuf.put('a'); 161 | textbuf.put('x'); 162 | textbuf.put("abc"); 163 | assert(textbuf.length == 5); 164 | assert(textbuf[1..3] == "xa"); 165 | assert(textbuf[3] == 'b'); 166 | textbuf.pop(); 167 | assert(textbuf[0..textbuf.length] == "axab"); 168 | textbuf.setLength(3); 169 | assert(textbuf[0..textbuf.length] == "axa"); 170 | assert(textbuf.last() == 'a'); 171 | assert(textbuf[1..3] == "xa"); 172 | textbuf.put(cast(dchar)'z'); 173 | assert(textbuf[] == "axaz"); 174 | textbuf.initialize(); 175 | assert(textbuf.length == 0); 176 | textbuf.free(); 177 | } 178 | 179 | /* 180 | * Local Variables: 181 | * mode: d 182 | * c-basic-offset: 4 183 | * End: 184 | */ 185 | -------------------------------------------------------------------------------- /util.d: -------------------------------------------------------------------------------- 1 | import std.stdio; 2 | import std.array; 3 | import std.format; 4 | 5 | import loc; 6 | 7 | // Data type for C source code characters 8 | alias ubyte uchar; 9 | alias immutable(uchar)[] ustring; 10 | 11 | void err_fatal(T...)(T args) 12 | { 13 | auto app = appender!string(); 14 | app.formattedWrite(args); 15 | throw new Exception(app.data); 16 | } 17 | 18 | void err_warning(T...)(Loc loc, T args) 19 | { 20 | loc.write(&stderr); 21 | stderr.write("warning: "); 22 | stderr.writefln(args); 23 | } 24 | -------------------------------------------------------------------------------- /warpdrive.d: -------------------------------------------------------------------------------- 1 | /** 2 | * C preprocessor driver 3 | * Copyright 2014 Facebook, Inc. 4 | * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0). 5 | * Authors: Andrei Alexandrescu 6 | */ 7 | 8 | // Forwards to warp by emulating the predefined options defined by gcc 9 | // 4.7 or gcc 4.8. Use -version=gcc47 or -version=gcc48 when building. 10 | // 11 | // The predefined preprocessor flags have been 12 | // obtained by running: 13 | // 14 | // g++ -dM -E -