├── .clang-format
├── .gitattributes
├── .gitignore
├── .vs
├── tpp.sln
├── tpp.vcxproj
├── tpp.vcxproj.filters
└── tpp.vcxproj.user
├── LICENSE
├── README.md
├── make.sh
├── samples
├── advanced
│ ├── Makefile
│ ├── README.md
│ ├── input.c
│ ├── main.c
│ ├── my-custom-tpp-defs.h
│ ├── mywrapper-for-tpp.c
│ └── mywrapper-for-tpp.h
└── simple
│ ├── Makefile
│ ├── README.md
│ ├── input.c
│ └── main.c
├── src
├── frontend.c
├── tpp-backwards-compatibility.h
├── tpp-defs.inl
├── tpp-gcc-defs.inl
├── tpp.c
└── tpp.h
└── test
├── _runall.sh
├── arguments_as_macro.h
├── clone_linefeed.h
├── count_tokens.h
├── cxx_comments_in_macro.h
├── define_directives.h
├── directives_in_macros.h
├── directives_start_of_line.h
├── double_counter.h
├── glue.h
├── has_include.h
├── include
├── def.h
└── test.h
├── include_path.h
├── inner
└── test.h
├── macro-argument-whitespace.h
├── macro_call_conv.h
├── macro_escape_lf.h
├── null_directive.h
├── pound_xclaim.h
├── prevent_macro_expansion.h
├── push_pop_macro.h
├── quotes_in_error.h
├── self_redef.h
├── stdc_6.10.3.5_5.h
├── stdc_6.10.3.5_6.h
├── stdc_6.10.3.5_7.h
├── stdc_6.10.3.5_9.h
├── stdc_6.10.3_5+6.h
├── strings_in_expressions.h
├── tpp_exec.h
├── traditional_macros.h
├── undef_current_macro.h
├── undef_macro_cexpr.h
├── user_error.h
├── varargs_empty.h
├── varargs_named.h
├── varargs_va_comma.h
├── varargs_va_nargs.h
└── varargs_va_opt.h
/.clang-format:
--------------------------------------------------------------------------------
1 |
2 | # Find stuff that this format defines incorrectly:
3 | # REPLACE: "(?<=(|un)likely) \(", "("
4 | # - Spaces after [un]likely (caused by 'SpaceBeforeParens: ControlStatements'),
5 | # though with LLVM9, the produced formatting was waaay worse than this :)
6 | # REPLACE: "}[ \t]*\n[ \t]+(?=\bEXCEPT\b)" --> "} "
7 | # - EXCEPT on a new line
8 | # FIND: "\t/\*[^\n]*\n [ ]+\*"
9 | # - Block-comments that need to be re-aligned
10 | #
11 | # Really though: there needs to be a simple directive to perform
12 | # finalizing regex-based text replacement on otherwise already
13 | # formatted source code:
14 | # >> RegexReplacements:
15 | # >> - Regex: '(?<=(|un)likely) \('
16 | # >> Replacement: '('
17 | # >> - Regex: '}[ \t]*\n[ \t]+(?=\bEXCEPT\b)'
18 | # >> Replacement: '} '
19 |
20 | AccessModifierOffset: -4
21 | AlignAfterOpenBracket: Align
22 | AlignConsecutiveAssignments: true
23 | # AlignConsecutiveBitFields: true
24 | AlignConsecutiveDeclarations: false
25 | AlignConsecutiveMacros: true
26 | AlignEscapedNewlines: Left
27 | AlignOperands: true
28 | AlignTrailingComments: true
29 | AllowAllArgumentsOnNextLine: false
30 | AllowAllConstructorInitializersOnNextLine: false
31 | AllowAllParametersOfDeclarationOnNextLine: false
32 | AllowShortBlocksOnASingleLine: false
33 | AllowShortCaseLabelsOnASingleLine: true
34 | # AllowShortEnumsOnASingleLine: false
35 | AllowShortFunctionsOnASingleLine: Empty
36 | AllowShortIfStatementsOnASingleLine: Never
37 | AllowShortLambdasOnASingleLine: All
38 | AllowShortLoopsOnASingleLine: false
39 | AlwaysBreakAfterReturnType: None
40 | AlwaysBreakBeforeMultilineStrings: false
41 | AlwaysBreakTemplateDeclarations: No
42 | BinPackArguments: true
43 | BinPackParameters: true
44 | ExperimentalAutoDetectBinPacking: true
45 | BraceWrapping:
46 | AfterCaseLabel: false
47 | AfterClass: false
48 | AfterControlStatement: false
49 | AfterEnum: false
50 | AfterFunction: false
51 | AfterNamespace: false
52 | AfterObjCDeclaration: false
53 | AfterStruct: false
54 | AfterUnion: false
55 | AfterExternBlock: false
56 | BeforeCatch: false
57 | BeforeElse: false
58 | # BeforeLambdaBody: false
59 | # BeforeWhile: false
60 | IndentBraces: false
61 | SplitEmptyFunction: false
62 | SplitEmptyRecord: false
63 | SplitEmptyNamespace: false
64 | BreakAfterJavaFieldAnnotations: true
65 | BreakBeforeBinaryOperators: None
66 | BreakBeforeBraces: Custom
67 | BreakBeforeTernaryOperators: true
68 | BreakConstructorInitializers: BeforeComma
69 | BreakInheritanceList: BeforeComma
70 | BreakStringLiterals: false
71 | ColumnLimit: 0
72 | CommentPragmas: '^\[\[\['
73 | CompactNamespaces: false
74 | ConstructorInitializerAllOnOneLineOrOnePerLine: false
75 | ConstructorInitializerIndentWidth: 4
76 | ContinuationIndentWidth: 0
77 | Cpp11BracedListStyle: false
78 | DeriveLineEnding: true
79 | DerivePointerAlignment: false
80 | DisableFormat: false
81 | ExperimentalAutoDetectBinPacking: false
82 | FixNamespaceComments: false
83 | IndentCaseLabels: false
84 | IndentGotoLabels: false
85 | IndentPPDirectives: None
86 | IndentWidth: 4
87 | IndentWrappedFunctionNames: false
88 | JavaScriptQuotes: Leave
89 | JavaScriptWrapImports: true
90 | KeepEmptyLinesAtTheStartOfBlocks: true
91 | MaxEmptyLinesToKeep: 8
92 | NamespaceIndentation: None
93 | ObjCBinPackProtocolList: Auto
94 | ObjCBlockIndentWidth: 1
95 | ObjCSpaceAfterProperty: false
96 | ObjCSpaceBeforeProtocolList: false
97 | PenaltyBreakAssignment: 1
98 | PenaltyBreakBeforeFirstCallParameter: 1
99 | PenaltyBreakComment: 1
100 | PenaltyBreakFirstLessLess: 1
101 | PenaltyBreakString: 0
102 | PenaltyBreakTemplateDeclaration: 1
103 | PenaltyExcessCharacter: 1
104 | PenaltyReturnTypeOnItsOwnLine: 1
105 | PointerAlignment: Right
106 | ReflowComments: true
107 | SortIncludes: true
108 | SortUsingDeclarations: true
109 | SpaceAfterCStyleCast: false
110 | SpaceAfterLogicalNot: false
111 | SpaceAfterTemplateKeyword: false
112 | SpaceBeforeAssignmentOperators: true
113 | SpaceBeforeCpp11BracedList: true
114 | SpaceBeforeCtorInitializerColon: false
115 | SpaceBeforeInheritanceColon: false
116 | SpaceBeforeParens: ControlStatements
117 | SpaceBeforeRangeBasedForLoopColon: false
118 | SpaceInEmptyBlock: true
119 | SpaceInEmptyParentheses: false
120 | SpacesBeforeTrailingComments: 1
121 | SpacesInAngles: false
122 | SpacesInCStyleCastParentheses: false
123 | SpacesInConditionalStatement: false
124 | SpacesInContainerLiterals: false
125 | SpacesInParentheses: false
126 | SpacesInSquareBrackets: false
127 | Standard: Cpp03
128 | TabWidth: 4
129 | UseCRLF: false
130 | UseTab: ForIndentation
131 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * -crlf
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/*
2 | build/*
3 | lib/*
4 | .vs/*.sdf
5 | .vs/*.suo
6 | .vs/*.opensdf
7 | .vs/.vs/
8 | *.exe
9 | *.dat
10 | *.VC.db
11 | *.VC.opendb
12 |
--------------------------------------------------------------------------------
/.vs/tpp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.31101.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tpp", "tpp.vcxproj", "{86D226C5-EF62-4562-AC06-E6A753DFA7CF}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {86D226C5-EF62-4562-AC06-E6A753DFA7CF}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {86D226C5-EF62-4562-AC06-E6A753DFA7CF}.Debug|Win32.Build.0 = Debug|Win32
16 | {86D226C5-EF62-4562-AC06-E6A753DFA7CF}.Release|Win32.ActiveCfg = Release|Win32
17 | {86D226C5-EF62-4562-AC06-E6A753DFA7CF}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/.vs/tpp.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | {86D226C5-EF62-4562-AC06-E6A753DFA7CF}
27 | tpp
28 | 10.0.17763.0
29 |
30 |
31 |
32 | Application
33 | true
34 | v141
35 | MultiByte
36 |
37 |
38 | Application
39 | false
40 | v141
41 | true
42 | MultiByte
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | $(ProjectDir)..\bin\
56 | $(IncludePath)
57 | AllRules.ruleset
58 | $(ProjectDir)..\build\$(Configuration)\
59 |
60 |
61 | $(IncludePath)
62 | $(ProjectDir)..\bin\
63 | AllRules.ruleset
64 | $(ProjectDir)..\build\$(Configuration)\
65 |
66 |
67 |
68 | Level4
69 | Disabled
70 | true
71 | false
72 | CompileAsCpp
73 | %(PreprocessorDefinitions)
74 |
75 |
76 | true
77 |
78 |
79 |
80 |
81 | Level4
82 | Full
83 | true
84 | true
85 | true
86 | CompileAsCpp
87 | NDEBUG;%(PreprocessorDefinitions)
88 | Speed
89 | AnySuitable
90 |
91 |
92 | true
93 | true
94 | true
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/.vs/tpp.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {cda78eda-b19b-4d47-8417-c11383d571ff}
6 |
7 |
8 |
9 |
10 | src
11 |
12 |
13 | src
14 |
15 |
16 |
17 |
18 | src
19 |
20 |
21 | src
22 |
23 |
24 |
25 |
26 | src
27 |
28 |
29 | src
30 |
31 |
32 |
--------------------------------------------------------------------------------
/.vs/tpp.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | --tok -o out.c ..\bin\input.c
5 | WindowsLocalDebugger
6 | $(ProjectDir)..\bin\
7 |
8 |
9 | --tok -o out.c ..\bin\input.c
10 | WindowsLocalDebugger
11 | $(ProjectDir)..\bin\
12 |
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ZLIB LICENSE (https://en.wikipedia.org/wiki/Zlib_License)
2 |
3 | Copyright (c) 2017-2023 Griefer@Work
4 |
5 | This software is provided 'as-is', without any express or implied
6 | warranty. In no event will the authors be held liable for any damages
7 | arising from the use of this software.
8 |
9 | Permission is granted to anyone to use this software for any purpose,
10 | including commercial applications, and to alter it and redistribute it
11 | freely, subject to the following restrictions:
12 |
13 | 1. The origin of this software must not be misrepresented; you must not
14 | claim that you wrote the original software. If you use this software
15 | in a product, an acknowledgement (see the following) in the product
16 | documentation is required:
17 | Portions Copyright (c) 2017-2023 Griefer@Work
18 | 2. Altered source versions must be plainly marked as such, and must not be
19 | misrepresented as being the original software.
20 | 3. This notice may not be removed or altered from any source distribution.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tpp - Tiny PreProcessor
2 |
3 | TPP is a tiny (single source file) C Preprocessor, meant as a low-level backend for compilers of C and C-like languages, whilst implementing pretty much all preprocessor extensions supported by other compilers, ontop of a large number of its own (tpp-specific) extensions.
4 |
5 | ### Usage
6 |
7 | TPP is designed to be used in 1 of 2 ways:
8 |
9 | - As a back-end for writing C and C-like compilers with all of the work needed for dealing with macros, directives, warnings, and preprocessor-related pragmas already taken care of.
10 | For this purpose, TPP is meant to be included statically as part of another project's source tree.
11 | - For samples on how this can be done, look in `/samples`
12 |
13 | - As a standalone Preprocessor (similar to GNU's `cpp` utility).
14 | For this purpose, you may build `src/frontend.c` to produce the commandline utility
15 |
16 |
17 | ### Features
18 |
19 | - TPP operates without any intermediate buffers, in that it is capable of preprocessing/tokenizing text in real-time from stream-like input sources:
20 |
21 | ```sh
22 | cat file.c | tpp
23 | ```
24 |
25 | The above command can be used to preprocess text, without any need for any intermediate buffers (beyond what is needed for a single token) before TPP will start producing output.
26 |
27 | This means that TPP will be able to parse input, and print preprocessed output in real-time, without needing to wait for you to close a PIPE, or reach the end of its input file, first.
28 |
29 | In a sense, this can be compared to python's interactive commandline, which allows it to execute code as you write it. So while an interactive C commandline ~~is probably impossible~~ [is possible](https://github.com/GrieferAtWork/dcc), an interactive C preprocessor ~~most definitely isn't~~ obviously is, too. - Because that's what TPP is.
30 |
31 | - Invocation of the TPP frontend is also designed to be usable by other utilities via the `--pp` switch, which, rather than producing preprocessed output, will emit individual tokens seperated by `'\0'`-characters, allowing you to leave all of the tokenization to tpp, and do the processing yourself in a seperate process.
32 |
33 |
34 | ### Preprocessor Extensions
35 |
36 | All extensions can be hard enabled/disabled when building tpp, or soft-enabled/disabled via `#pragma extension("-fname")` / `#pragma extension("-fno-name")` directives.
37 |
38 | Supported extensions can be tested for with `__has_known_extension("name")`, and supported+enabled extensions with `__has_extension("name")`. In turn, `__has_known_extension` and `__has_extension` can be tested for with `#ifdef`.
39 |
40 | - Trigraphs (`??*`)
41 | - Digraphs (`<%` is `{`, etc...)
42 | - STDC `__VA_ARGS__` (`#define printf(...) fprintf(stderr, __VA_ARGS__)`)
43 | - GCC-style varargs macros (`#define printf(format...) fprintf(stderr, format)`)
44 | - GCC-style va-comma (`#define printf(format, ...) fprintf(stderr, format, ##__VA_ARGS__)`)
45 | - GCC-style if-else in expressions (`#if foo ?: bar`; same as `#if foo ? foo : bar`)
46 | - c++20 `__VA_OPT__` (`#define printf(format, ...) fprintf(stderr, format __VA_OPT__(,) __VA_ARGS__)`)
47 | - `'\e'` escape codes in strings and characters (for ASCII `ESC`, iow: `'\x1b'`)
48 | - Binary literals (`0b00101010`)
49 | - MSVC's `__pragma(foo)` built-in function-like directive/macro
50 | - STDC's `_Pragma("foo")` built-in function-like directive/macro
51 | - GCC-style `#warning My Message Here` directives
52 | - GCC-style `#include_next ` directives
53 | - OBJc-style `#import ` directives
54 | - `#ident` and `#sccs` directives (true origin unknown; accepted by some ancient compilers for placing comments into `.o`-files)
55 | - STDC magic macros `__FILE__`, `__LINE__`, `__TIME__` and `__DATE__`
56 | - Magic macro `__BASE_FILE__`
57 | - Magic macros `__INCLUDE_LEVEL__` and `__INCLUDE_DEPTH__`
58 | - Magic macro `__COUNTER__`
59 | - Magic macro `__TIMESTAMP__`
60 | - Magic macro `__COLUMN__` (tpp-specific; like `__LINE__`, but the current column-position)
61 | - STDC-compliant preprocessor `#if`-expressions
62 | - All STDC-required preprocessor directives (`#define`, `#undef`, `#if`, `#ifdef`, `#ifndef`, `#elif`, `#else`, `#endif`, `#include`, `#pragma`, `#error`)
63 | - Clang-style feature test macros:
64 | - `__has_include()`
65 | - `__has_include_next()`
66 | - `__is_identifier()`, `__is_deprecated()`, `__is_poisoned()`
67 | - `__has_attribute()`, `__has_builtin()`, ...
68 | - `__is_builtin_identifier()` (tpp-specific)
69 | - `__has_extension()`, `__has_known_extension()` (tpp-specific)
70 | - `__has_warning()`, `__has_known_warning()` (tpp-specific)
71 | - Treat `#!`-directives as comments (i.e. `#!/bin/tpp` is treated as a comment)
72 | - Treat `$` as a character, which may thus appear in an identifier
73 | - Preprocessor assertions (no; not those from ``..., but this):
74 | - `#assert cpu(mycpu)`
75 | - `#unassert cpu(yourcpu)`
76 | - `#if #cpu(mycpu)`
77 | - Multi-char character literals (e.g. `#if 'abc' == 6513249`)
78 | - `__VA_COMMA__` (tpp-specific extension)
79 | - `#define printf(format, ...) fprintf(stderr, format __VA_COMMA__ __VA_ARGS__)`
80 | - Expands to `,` when `__VA_ARGS__` are non-empty and `/**/` when empty.
81 | - Essentially the same as `__VA_OPT__(,)`
82 | - `__VA_NARGS__` (tpp-specific extension)
83 | - Expands to the decimal representation of the # of arguments in `__VA_ARGS__`
84 | - Useful for overloading macros by argument count
85 |
86 | ```c
87 | #define min_1(a) a
88 | #define min_2(a, b) ((a) < (b) ? (a) : (b))
89 | #define min_3(a, b, c) min_2(min_2(a, b), c)
90 | #define min(...) min_##__VA_NARGS__(__VA_ARGS__)
91 | ```
92 | - Optional support for traditional macro expansion rules (disabled by default, can be enabled temporarily via `#pragma extension`)
93 | - ```c
94 | #define CAT(a,b) a ## b
95 | #define STR(x) #x
96 | #pragma extension(push, "-ftraditional-macro")
97 | #define T_CAT(a, b) a/**/b
98 | #define T_STR(x) "x"
99 | #pragma extension(pop)
100 | CAT(10, 20) // 1020
101 | STR(10) // "10"
102 | T_CAT(10, 20) // 1020
103 | T_STR(10) // "10"
104 | ```
105 | - Test for with `#if __has_known_extension("traditional-macro")`
106 | - Alternative parenthesis for macro definitions (tpp-specific extension):
107 | - Allow use of:
108 | - `#define foo(a,b) ...`
109 | - `#define foo[a,b] ...`
110 | - `#define foo{a,b} ...`
111 | - `#define foo ...`
112 | - In other words: define macros that use tokens other than `(...)`-pairs for arguments
113 | - Test for with `#if __has_extension("alternative-macro-parenthesis")`
114 | - Self-recursive macros (tpp-specific extension):
115 | - STDC specifies that macros that try to expand to themselves should not be allowed to do so when this happens
116 | - TPP has an optional extension to relax this rule for function-like macros defined while this extension is active
117 | - Such function-like macros are allowed to expand to themselves, so-long as arguments passed during expansion differ from all other invocations of the same macro along the macro-expansion call-stack
118 | - Test for with `#if __has_known_extension("macro-recursion")`
119 | - Enable/disable with `#pragma extension("-fmacro-recursion")` and `#pragma extension("-fno-macro-recursion")`
120 | - Whitespace-sensitivity (tpp-specific extension):
121 | - STDC specifies that whitespace should be stripped around macro bodies. - However, some programming languages are whitespace sensitive, meaning that the removal of whitespace in such cincumstances may alter program behavior.
122 | - For this purpose, TPP has an option to keep whitespace if necessary.
123 | - Test for with `#if __has_extension("macro-argument-whitespace")`
124 | - Allow select operations on string literals in preprocessor expressions (tpp-specific extension):
125 | - `#if "FOO" != "BAR"`
126 | - `#if "FOO"[0] == 'F'`
127 | - `#if "FOO"[1:] == "OO"`
128 | - `#if #"FOO" == 3`
129 | - Test for with `#if __has_extension("strings-in-expressions")`
130 | - Allow for GCC-style `__builtin_*` function calls in preprocessor expressions (tpp-specific extension):
131 | - `#if __builtin_ffs(0x100) == 9`
132 | - Test for with `#if __has_extension("builtins-in-expressions")`
133 | - Allow for `#@` as a replacement for `#` to convert macro arguments into character literals, rather than strings:
134 | - ```c
135 | #define STR(x) #x
136 | #define CHR(x) #@x
137 | STR(f) // "f"
138 | CHR(f) // 'f'
139 | ```
140 | - Test for with `#if __has_extension("charize-macro-argument")`
141 | - Prevent in-place expansion of macro arguments during macro-function-expansion (tpp-specific extension) (s.a. `/test/pound_xclaim.h`)
142 | - Test for with `#if __has_extension("dont-expand-macro-argument")`
143 | - Logical Xor operators (`A ^^ B`; same as `!!(A) ^ !!(B)`) (tpp-specific extension)
144 | - Precise date/time macros (tpp-specific extension):
145 | - `__DATE_DAY__`, `__DATE_WDAY__`, `__DATE_YDAY__`, `__DATE_MONTH__`, `__DATE_YEAR__`
146 | - `__TIME_SEC__`, `__TIME_MIN__`, `__TIME_HOUR__`
147 | - Test for with `#ifdef `
148 | - Evaluate preprocessor expressions, and expand to their decimal/string representation (tpp-specific extension):
149 | - For example: `__TPP_EVAL(10 + 20)` would expand to exactly 1 token `30`
150 | - Highly useful because you can do stuff like:
151 |
152 | ```c
153 | #define CAT2(a, b) a##b
154 | #define CAT(a, b) CAT2(a, b)
155 | #define ISLESS_0 more than
156 | #define ISLESS_1 less than
157 | #define SELECT(n) CAT(ISLESS_, __TPP_EVAL(n < 10))
158 | SELECT(7) // Expands to `less than'
159 | SELECT(10) // Expands to `more than'
160 | ```
161 | - Can also be combined with `"strings-in-expressions"` to operate on strings:
162 |
163 | ```c
164 | __TPP_EVAL("foobar"[3:]) // Expands to "bar"
165 | ```
166 | - Test for with `#ifdef __TPP_EVAL`
167 | - Generate unique IDs for a given keyword/name (that remain unchanged when re-compiling the same file without altering its contents) (tpp-specific extension):
168 | - For example, `__TPP_UNIQUE(foo)` expands to a unique decimal integer that will remain the same for `foo` within the entire input (though not necessarily within other files that may be preprocessed seperately)
169 | - Test for with `#ifdef __TPP_UNIQUE`
170 | - Load the contents of a #include-file into a string (tpp-specific extension):
171 | - For example, `__TPP_LOAD_FILE("file.c")` will expand to the the contents of `file.c`, contained in, and escaped as a `"string"`
172 | - Test for with `#ifdef __TPP_LOAD_FILE`
173 | - An arbitrary number of `__COUNTER__`-like counters (tpp-specific extension):
174 | - For example, each time `__TPP_COUNTER(foo)` is encountered, it will expand to 1 greater than its previous expansion (starting at `0`)
175 | - Similar behavior is also possible with `__COUNTER__`, however using `__TPP_COUNTER`, you can have an arbitrary number of counters operating independent of each other.
176 | - Test for with `#ifdef __TPP_COUNTER`
177 | - Random number generation (tpp-specific extension):
178 | - Generate a random number in `[0,hi)` with `__TPP_RANDOM(hi)`
179 | - Generate a random number in `[lo,hi)` with `__TPP_RANDOM(lo, hi)`
180 | - Test for with `#ifdef __TPP_RANDOM`
181 | - Re-interprete the contents of a string token as input text (tpp-specific extension):
182 | - ```c
183 | #define foo 42
184 | __TPP_STR_DECOMPILE("foo bar") // Expands to `42 bar'
185 | ```
186 | - Test for with `#ifdef __TPP_STR_DECOMPILE`
187 | - Pack together a string token from the ASCII codes of its individual characters (tpp-specific extension):
188 | - For example, `__TPP_STR_PACK(0x48, 0x65, 0x6c, 0x6c, 0x6f)` expands to `"Hello"`
189 | - Test for with `#ifdef __TPP_STR_PACK`
190 | - More extensions exist, but I feel those are not important enough to document here
191 | - Most notably, supported `#pragma` directives, such as `#pragma once`, `#pragma push_macro()`, etc...
192 |
--------------------------------------------------------------------------------
/make.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | CFLAGS=""
4 |
5 | # I told you this is a ~tiny~ preprocessor.
6 | # >> No dependencies other than libc & only 2 source files.
7 | gcc $CFLAGS -o tpp src/frontend.c src/tpp.c
8 |
9 | # NOTE: TPP Also recognizes a few compiler options.
10 | # All options begin with 'TPP_CONFIG_*' and must either
11 | # be predefined as '0' or '1' to override their behavior.
12 | # When not defined at all, they will default to the values
13 | # specified below.
14 | #
15 | # - TPP_CONFIG_DEBUG: DEFAULT: 1
16 | # Enable debug mode and internaly assertions.
17 | # This option is enabled by default and helps
18 | # detect internal problems with TPP.
19 | #
20 | # - TPP_CONFIG_ONELEXER: DEFAULT: 1
21 | # Configure TPP to only use one lexer globally.
22 | # When disabled, a global pointer 'TPPLexer_Current'
23 | # can be overwritten to set the currently used
24 | # lexer, allowing you to set up your own synchronization
25 | # when attempting to use multiple lexers between
26 | # different threads.
27 | # When disabled, only one lexer 'TPPLexer_Global'
28 | # is made available and used, and 'TPPLexer_Current' is
29 | # defined as a macro simply referring to 'TPPLexer_Global',
30 | # as well as lacking the ability of being overwritable.
31 | # In both cases, the used TPP lexer must be initialized
32 | # before being used first, as well as be finalized after
33 | # you're doing, which can easily be achieved using
34 | # 'TPP_INITIALIZE()' and 'TPP_FINALIZE()', which
35 | # will always perform the necessary steps to setup
36 | # and initialize the/a-new global lexer.
37 | #
38 | # - TPP_CONFIG_EXPORT: DEFAULT: 0
39 | # May be used to have TPP export its public functions
40 | # from a shared library, thus allowing you to create
41 | # and link it as a .dll or .so library.
42 | #
43 | # - TPP_CONFIG_MINMACRO: DEFAULT: 0
44 | # Configure TPP never to define builtin macros such
45 | # as '__SIZEOF_POINTER__' or '__INT32_C', essentially
46 | # forcing it to always behave as though '-undef'
47 | # was passed on the commandline.
48 | #
49 |
--------------------------------------------------------------------------------
/samples/advanced/Makefile:
--------------------------------------------------------------------------------
1 |
2 | a.out: main.c ../../src/tpp.h ../../src/tpp.c mywrapper-for-tpp.h mywrapper-for-tpp.c my-custom-tpp-defs.h
3 | gcc -o a.out main.c mywrapper-for-tpp.c
4 |
5 | a.exe: main.c ../../src/tpp.h ../../src/tpp.c mywrapper-for-tpp.h mywrapper-for-tpp.c my-custom-tpp-defs.h
6 | gcc -o a.exe main.c mywrapper-for-tpp.c
7 |
--------------------------------------------------------------------------------
/samples/advanced/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Running this sample
3 |
4 | ```sh
5 | make a.out # or "a.exe" on windows
6 | ./a.out
7 | ```
8 |
--------------------------------------------------------------------------------
/samples/advanced/input.c:
--------------------------------------------------------------------------------
1 |
2 | #pragma message "It's working!"
3 |
4 | #define foo(a, b) a+b+a+b
5 |
6 | printf("x = %d", foo(10, MY_MACRO) == __TPP_EVAL(foo(10, MY_MACRO)));
7 | #ifdef __MY_PREDEFINED_MACRO__
8 | IS PREDEFINED
9 | #endif
10 | #if __has_extension("-fawesome")
11 | awesome
12 | #endif
13 |
14 | #if __is_builtin_identifier(async)
15 | Its-a-builtin!
16 | #endif
17 |
18 | #if __is_builtin_identifier(not_async)
19 | #error "This one wasn't defined in 'my-custom-tpp-defs.h', so it shouldn't be a builtin"
20 | #endif
21 |
22 | /*Expected output (token IDs may differ):
23 |
24 | It's working!
25 | input.c:6:1: 814: 'printf'
26 | input.c:6:7: 40: '('
27 | input.c:6:8: 34: '"x = %d"'
28 | input.c:6:16: 44: ','
29 | input.c:6:35: 48: '10' [in macro 'foo' at input.c:4:19]
30 | input.c:6:35: 43: '+' [in macro 'foo' at input.c:4:20]
31 | input.c:6:35: 48: '42' [in macro 'foo' at input.c:4:21]
32 | input.c:6:35: 43: '+' [in macro 'foo' at input.c:4:22]
33 | input.c:6:35: 48: '10' [in macro 'foo' at input.c:4:23]
34 | input.c:6:35: 43: '+' [in macro 'foo' at input.c:4:24]
35 | input.c:6:35: 48: '42' [in macro 'foo' at input.c:4:25]
36 | input.c:6:36: 258: '=='
37 | input.c:6:68: 48: '104'
38 | input.c:6:68: 41: ')'
39 | input.c:6:69: 59: ';'
40 | input.c:8:1: 815: 'IS'
41 | input.c:8:4: 816: 'PREDEFINED'
42 | input.c:11:1: 817: 'awesome'
43 | input.c:15:1: 818: 'Its'
44 | input.c:15:4: 45: '-'
45 | input.c:15:5: 812: 'a'
46 | input.c:15:6: 45: '-'
47 | input.c:15:7: 819: 'builtin'
48 | input.c:15:14: 33: '!'
49 |
50 | */
51 |
--------------------------------------------------------------------------------
/samples/advanced/main.c:
--------------------------------------------------------------------------------
1 |
2 | #include "mywrapper-for-tpp.h"
3 | /**/
4 |
5 | #include
6 | #include
7 | #include
8 |
9 |
10 | #define ERROR_HANDLING fatal(__LINE__)
11 | static void fatal(int line) {
12 | /* Should probably do "TPP_FINALIZE()", unless error was caused by "TPP_INITIALIZE()" */
13 | fprintf(stderr, "%d: something went horribly wrong\n", line);
14 | exit(1);
15 | }
16 |
17 |
18 | int main() {
19 | /* Initialization */
20 | if (!TPP_INITIALIZE())
21 | ERROR_HANDLING;
22 |
23 | /* Configure `TPPLexer_Current' to your liking */
24 | // TPPLexer_Current->l_flags = ...;
25 | // TPPLexer_Current->l_extokens = ...;
26 |
27 | /* -DMY_MACRO=42 */
28 | char const *name = "MY_MACRO";
29 | char const *val = "42";
30 | if (!TPPLexer_Define(name, strlen(name), val, strlen(val),
31 | TPPLEXER_DEFINE_FLAG_NONE))
32 | ERROR_HANDLING;
33 |
34 | /* -I/usr/include */
35 | char incpath[] = "/usr/include"; // Must be writable; use strdup() when in doubt
36 | if (!TPPLexer_AddIncludePath(incpath, strlen(incpath)))
37 | ERROR_HANDLING;
38 |
39 | /* Push an initial file onto the #include-stack */
40 | char const *filename = "input.c";
41 | struct TPPFile *file = TPPLexer_OpenFile(TPPLEXER_OPENFILE_MODE_NORMAL |
42 | TPPLEXER_OPENFILE_FLAG_CONSTNAME,
43 | (char *)filename, strlen(filename),
44 | NULL);
45 | if (!file)
46 | ERROR_HANDLING;
47 | TPPLexer_PushFile(file);
48 |
49 | /* Process input one token at a time.
50 | * Hint: emission of certain tokens depends on `TPPLEXER_FLAG_WANT*' and `TPPLEXER_TOKEN_*' */
51 | while (TPPLexer_Yield() > 0) {
52 | int id = TPPLexer_Current->l_token.t_id;
53 | char *tokstr = TPPLexer_Current->l_token.t_begin;
54 | size_t toklen = (size_t)(TPPLexer_Current->l_token.t_end - tokstr);
55 | struct TPPLCInfo lc;
56 | struct TPPFile *f = TPPLexer_Textfile();
57 | struct TPPFile *current = TPPLexer_GetFile();
58 | char *f_ptr = current == f ? tokstr : f->f_pos;
59 | TPPFile_LCAt(f, &lc, f_ptr);
60 | printf("%s:%d:%d: %d: '%.*s'", TPPFile_Filename(f, NULL),
61 | (int)lc.lc_line + 1, (int)lc.lc_col + 1,
62 | id, (int)toklen, tokstr);
63 | if (current != f) {
64 | struct TPPFile *mac = current;
65 | while (mac != f && mac->f_kind != TPPFILE_KIND_MACRO)
66 | mac = mac->f_prev;
67 | if (mac != f) {
68 | struct TPPLCInfo mac_lc;
69 | TPPFile_LCAt(mac, &mac_lc, current == mac ? tokstr : mac->f_pos);
70 | printf(" [in macro '%.*s' at %s:%d:%d]",
71 | (int)mac->f_namesize, mac->f_name, TPPFile_Filename(mac, NULL),
72 | (int)mac_lc.lc_line + 1, (int)mac_lc.lc_col + 1);
73 | }
74 | }
75 | putchar('\n');
76 | }
77 |
78 | /* Check if something went wrong (stuff like `#error' directives, or syntax errors) */
79 | if ((TPPLexer_Current->l_flags & TPPLEXER_FLAG_ERROR) ||
80 | (TPPLexer_Current->l_errorcount != 0))
81 | ERROR_HANDLING;
82 |
83 | /* Cleanup the lexer (must be called after successful a `TPPLexer_Init()') */
84 | TPP_FINALIZE();
85 | return 0;
86 | }
87 |
--------------------------------------------------------------------------------
/samples/advanced/my-custom-tpp-defs.h:
--------------------------------------------------------------------------------
1 | /* Custom keywords (but be careful not to re-define ones already defined by TPP)
2 | * When parsed, you can check for these keywords like:
3 | * >> switch (TPPLexer_Current->l_token.t_id) {
4 | * >> case KWD_async:
5 | * >> ...;
6 | * >> break;
7 | * >> case KWD_function:
8 | * >> ...;
9 | * >> break;
10 | * >> }
11 | * */
12 | DEF_K(async)
13 | DEF_K(function)
14 | DEF_K(def)
15 | DEF_K(awesome_keyword)
16 |
17 | /* These you would probably replace with something else... */
18 | #define should_be_defined 1
19 | #define enabled_by_default 1
20 |
21 | /* A pre-defined macro (as in `#ifdef __MY_PREDEFINED_MACRO__')
22 | * This should be used for stuff like `__GNUC__' or `__cplusplus', etc... */
23 | PREDEFINED_MACRO_IF(__MY_PREDEFINED_MACRO__, "42", should_be_defined ? 1 : 0)
24 |
25 | /* Custom warnings groups. (see "tpp-defs.inl" for the default groups)
26 | * Warnings can be enabled/disabled on a per-group basis by parsed text:
27 | * >> #pragma warning("-Wmygroup") // Enable
28 | * >> #pragma warning("-Wno-mygroup") // Disable
29 | * >> #pragma GCC diagnostic error "-Wmygroup"
30 | * >> #pragma GCC diagnostic warning "-Wmygroup"
31 | * >> #pragma GCC diagnostic ignored "-Wmygroup"
32 | */
33 | WGROUP(WG_MYGROUP, "mygroup", WSTATE_FATAL) // Warnings controlled by "-Wmygroup" / "-Wno-mygroup" / ...
34 |
35 | /* Custom warnings.
36 | * Your compiler would trigger this like (note: it's a varargs function):
37 | * >> if (!TPPLexer_Warn(W_MYWARNING, "first variable argument"))
38 | * >> HANDLE_AS_CRITICAL_ERROR;
39 | * >> TRY_TO_CONTINUE_COMPILING;
40 | */
41 | DEF_WARNING(W_MYWARNING, (WG_MYGROUP, WG_SYNTAX), WSTATE_ERROR, {
42 | char *mesg = ARG(char *);
43 | WARNF("My warning handler: %s", mesg);
44 | })
45 |
46 | /* Custom extension. Input code can enable/disable this by:
47 | * >> #pragma extension("-fawesome") // Turn on
48 | * >> #pragma extension("-fno-awesome") // Turn off
49 | * Your compiler can check if it's enabled with `TPPLexer_HasExtension(EXT_AWESOME)' */
50 | EXTENSION(EXT_AWESOME, "awesome", enabled_by_default ? 1 : 0)
51 |
--------------------------------------------------------------------------------
/samples/advanced/mywrapper-for-tpp.c:
--------------------------------------------------------------------------------
1 | #define TPP_USERDEFS "../samples/advanced/my-custom-tpp-defs.h"
2 | #include "../../src/tpp.c"
3 |
--------------------------------------------------------------------------------
/samples/advanced/mywrapper-for-tpp.h:
--------------------------------------------------------------------------------
1 | #define TPP_USERDEFS "../samples/advanced/my-custom-tpp-defs.h"
2 | #include "../../src/tpp.h"
3 |
--------------------------------------------------------------------------------
/samples/simple/Makefile:
--------------------------------------------------------------------------------
1 |
2 | a.out: main.c ../../src/tpp.h ../../src/tpp.c
3 | gcc -o a.out main.c ../../src/tpp.c
4 |
5 | a.exe: main.c ../../src/tpp.h ../../src/tpp.c
6 | gcc -o a.exe main.c ../../src/tpp.c
7 |
--------------------------------------------------------------------------------
/samples/simple/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Running this sample
3 |
4 | ```sh
5 | make a.out # or "a.exe" on windows
6 | ./a.out
7 | ```
8 |
--------------------------------------------------------------------------------
/samples/simple/input.c:
--------------------------------------------------------------------------------
1 |
2 | #pragma message "It's working!"
3 |
4 | #define foo(a, b) a+b+a+b
5 |
6 | printf("x = %d", foo(10, MY_MACRO) == __TPP_EVAL(foo(10, MY_MACRO)));
7 |
8 | /*Expected output (token IDs may differ):
9 |
10 | It's working!
11 | token: 806: 'printf'
12 | token: 40: '('
13 | token: 34: '"x = %d"'
14 | token: 44: ','
15 | token: 48: '10'
16 | token: 43: '+'
17 | token: 48: '42'
18 | token: 43: '+'
19 | token: 48: '10'
20 | token: 43: '+'
21 | token: 48: '42'
22 | token: 258: '=='
23 | token: 48: '104'
24 | token: 41: ')'
25 | token: 59: ';'
26 |
27 | */
28 |
--------------------------------------------------------------------------------
/samples/simple/main.c:
--------------------------------------------------------------------------------
1 |
2 | #include "../../src/tpp.h"
3 | /**/
4 |
5 | #include
6 | #include
7 | #include
8 |
9 |
10 | #define ERROR_HANDLING fatal(__LINE__)
11 | static void fatal(int line) {
12 | /* Should probably do "TPP_FINALIZE()", unless error was caused by "TPP_INITIALIZE()" */
13 | fprintf(stderr, "%d: something went horribly wrong\n", line);
14 | exit(1);
15 | }
16 |
17 |
18 | int main() {
19 | /* Initialization */
20 | if (!TPP_INITIALIZE())
21 | ERROR_HANDLING;
22 |
23 | /* Configure `TPPLexer_Current' to your liking */
24 | // TPPLexer_Current->l_flags = ...;
25 | // TPPLexer_Current->l_extokens = ...;
26 |
27 | /* -DMY_MACRO=42 */
28 | char const *name = "MY_MACRO";
29 | char const *val = "42";
30 | if (!TPPLexer_Define(name, strlen(name), val, strlen(val),
31 | TPPLEXER_DEFINE_FLAG_NONE))
32 | ERROR_HANDLING;
33 |
34 | /* -I/usr/include */
35 | char incpath[] = "/usr/include"; // Must be writable; use strdup() when in doubt
36 | if (!TPPLexer_AddIncludePath(incpath, strlen(incpath)))
37 | ERROR_HANDLING;
38 |
39 | /* Push an initial file onto the #include-stack */
40 | char const *filename = "input.c";
41 | struct TPPFile *file = TPPLexer_OpenFile(TPPLEXER_OPENFILE_MODE_NORMAL |
42 | TPPLEXER_OPENFILE_FLAG_CONSTNAME,
43 | (char *)filename, strlen(filename),
44 | NULL);
45 | if (!file)
46 | ERROR_HANDLING;
47 | TPPLexer_PushFile(file);
48 |
49 | /* Process input one token at a time.
50 | * Hint: emission of certain tokens depends on `TPPLEXER_FLAG_WANT*' and `TPPLEXER_TOKEN_*' */
51 | while (TPPLexer_Yield() > 0) {
52 | int id = TPPLexer_Current->l_token.t_id;
53 | char *tokstr = TPPLexer_Current->l_token.t_begin;
54 | size_t toklen = (size_t)(TPPLexer_Current->l_token.t_end - tokstr);
55 | printf("token: %d: '%.*s'\n", id, (int)toklen, tokstr);
56 | }
57 |
58 | /* Check if something went wrong (stuff like `#error' directives, or syntax errors) */
59 | if ((TPPLexer_Current->l_flags & TPPLEXER_FLAG_ERROR) ||
60 | (TPPLexer_Current->l_errorcount != 0))
61 | ERROR_HANDLING;
62 |
63 | /* Cleanup the lexer (must be called after successful a `TPPLexer_Init()') */
64 | TPP_FINALIZE();
65 | return 0;
66 | }
67 |
--------------------------------------------------------------------------------
/src/frontend.c:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #define TPP(x) x /* Global namespace. */
21 | #define _CRT_SECURE_NO_WARNINGS
22 | #define _CRT_NONSTDC_NO_WARNINGS
23 | #define _CRT_OBSOLETE_NO_DEPRECATE
24 |
25 | #if defined(_MSC_VER) && defined(_DEBUG)
26 | /* Make use of MSVC's builtin memory leak detector. */
27 | #define _CRTDBG_MAP_ALLOC
28 | #include
29 | #include
30 | #endif
31 |
32 | #include "tpp.h"
33 | #include
34 | #include
35 | #include
36 |
37 | #ifdef _WIN32
38 | #include
39 | #else /* _WIN32 */
40 | #include
41 | #include
42 | #endif /* !_WIN32 */
43 |
44 | #ifdef __cplusplus
45 | extern "C" {
46 | #endif /* __cplusplus */
47 |
48 | #define STR2(x) #x
49 | #define STR(x) STR2(x)
50 | #if defined(_MSC_FULL_VER) && defined(__cplusplus)
51 | # define TPP_COMPILER "VC++ " STR(_MSC_FULL_VER)
52 | #elif defined(_MSC_FULL_VER)
53 | # define TPP_COMPILER "VC " STR(_MSC_FULL_VER)
54 | #elif defined(__clang__) && defined(__cplusplus)
55 | # define TPP_COMPILER "clang++ " STR(__clang__)
56 | #elif defined(__clang__)
57 | # define TPP_COMPILER "clang " STR(__clang__)
58 | #elif defined(__GNUC__) && defined(__cplusplus)
59 | # define TPP_COMPILER "g++ " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__)
60 | #elif defined(__GNUC__)
61 | # define TPP_COMPILER "gcc " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__)
62 | #elif defined(__TINYC__)
63 | # define TPP_COMPILER "tcc " STR(__TINYC__)
64 | #elif defined(__cplusplus)
65 | # define TPP_COMPILER "Unknown c++ compiler"
66 | #else
67 | # define TPP_COMPILER "Unknown c compiler"
68 | #endif
69 |
70 |
71 | #define OUTLINE_MODE_NONE 0
72 | #define OUTLINE_MODE_TOK 1 /* Outline with [...] */
73 | #define OUTLINE_MODE_ZERO 2 /* Separate with `\0' */
74 | static int outline_tokens = OUTLINE_MODE_NONE;
75 | static int no_magic_tokens = 1; /*< Disable ~magic~ tokens for small line-shifts to prevent a #line being emit. */
76 | static int line_directives = 2; /*< Enable #line directives being emit. */
77 | static int decode_tokens = 1; /*< Decode stuff like escape sequences and trigraphs before writing to out. */
78 | static uint32_t base_flags; /*< Base set of lexer flags. */
79 |
80 | #ifdef _WIN32
81 | static TPP(stream_t) stdout_handle;
82 | #define write(fd, p, s) (void)WriteFile(fd, p, s, NULL, NULL)
83 | #else /* _WIN32 */
84 | #define stdout_handle STDOUT_FILENO
85 | #endif /* !_WIN32 */
86 |
87 | /* We prefer using unbuffered I/O to not create
88 | * bottlenecks when running in immediate mode.
89 | * Also: Window's libc does some weird $h1t to linefeeds,
90 | * inserting a magic '\r' character before every '\n`...
91 | * (You can probably turn that off, but I'm not even gonna bother) */
92 | #define out_write(p, s) write(stdout_handle, p, s)
93 |
94 | static ptrdiff_t
95 | out_printer(void *closure, char const *buf, size_t bufsize) {
96 | (void)closure;
97 | out_write(buf, bufsize * sizeof(char));
98 | return 0;
99 | }
100 |
101 | static int is_at_linefeed;
102 | static int current_line;
103 |
104 | void put_line(void) {
105 | static char const *last_filename = NULL;
106 | size_t filename_size;
107 | char const *filename_text;
108 | struct TPPFile *f;
109 | int line;
110 | char buffer[16];
111 | if (!line_directives)
112 | return;
113 | f = TPPLexer_Textfile();
114 | if (TPPLexer_Current->l_token.t_file == f) {
115 | /* Try to use the start of the current token.
116 | * NOTE: Something like `f->f_oldpos' would be more
117 | * appropriate to use, but we don't track that... */
118 | line = TPPFile_LineAt(f, TPPLexer_Current->l_token.t_begin);
119 | } else {
120 | /* Fallback: Use the current position within the file. */
121 | line = TPPFile_LineAt(f, f->f_pos);
122 | }
123 | filename_text = TPPFile_Filename(f, &filename_size);
124 | if (current_line == line && last_filename == filename_text)
125 | return;
126 | if (outline_tokens != OUTLINE_MODE_ZERO && !no_magic_tokens &&
127 | last_filename == filename_text && current_line <= line - 1 &&
128 | current_line >= line - 2) {
129 | /* Optimization: For smaller line-offsets of less than 2, it is usually
130 | * easier to simply emit the linefeeds individually.
131 | * WARNING: We can't do this in ZERO-mode though, as in this mode linefeeds
132 | * must only be emit when they actually exist
133 | */
134 | size_t offset = line - current_line;
135 | current_line = line;
136 | if (outline_tokens == OUTLINE_MODE_TOK) {
137 | out_write("[\n][\n]", (offset * 3) * sizeof(char));
138 | } else {
139 | out_write("\n\n", offset * sizeof(char));
140 | }
141 | return;
142 | }
143 | if (!is_at_linefeed)
144 | out_write("\n", sizeof(char));
145 | current_line = line;
146 | if (line_directives == 2) {
147 | out_write("# ", 2 * sizeof(char));
148 | } else {
149 | out_write("#line ", 6 * sizeof(char));
150 | }
151 | out_write(buffer, (TPP_Itos(buffer, (TPP(tint_t))(line + 1)) - buffer) * sizeof(char));
152 | if (last_filename != filename_text) {
153 | char *quote_buffer;
154 | size_t quote_size;
155 | last_filename = filename_text;
156 | out_write(" \"", 2);
157 | quote_size = TPP_SizeofEscape(filename_text, filename_size);
158 | quote_buffer = (char *)malloc(quote_size * sizeof(char));
159 | if (quote_buffer) {
160 | TPP_Escape(quote_buffer, filename_text, filename_size);
161 | out_write(quote_buffer, quote_size * sizeof(char));
162 | free(quote_buffer);
163 | }
164 | out_write(outline_tokens == OUTLINE_MODE_ZERO
165 | ? "\"\0"
166 | : "\"\n",
167 | 2 * sizeof(char));
168 | } else {
169 | out_write(outline_tokens == OUTLINE_MODE_ZERO
170 | ? "\0"
171 | : "\n",
172 | sizeof(char));
173 | }
174 | is_at_linefeed = 1;
175 | }
176 |
177 | TPP_LOCAL size_t get_file_offset(char *p) {
178 | struct TPPFile *f = TPPLexer_Current->l_token.t_file;
179 | size_t result = p - f->f_begin;
180 | if (f->f_kind == TPPFILE_KIND_TEXT) {
181 | result += (f->f_textfile.f_rdata - f->f_text->s_size);
182 | }
183 | return result;
184 | }
185 |
186 | TPP_LOCAL int
187 | count_linefeeds(char const *iter, char const *end) {
188 | int result = 0;
189 | while (iter != end) {
190 | if (*iter == '\r') {
191 | if (iter != end - 1 &&
192 | iter[1] == '\n')
193 | ++iter;
194 | ++result;
195 | } else if (*iter == '\n') {
196 | ++result;
197 | }
198 | ++iter;
199 | }
200 | return result;
201 | }
202 |
203 | static char const version[] =
204 | "tpp version " STR(TPP_API_VERSION) "/" STR(TPP_PREPROCESSOR_VERSION) " - New Tiny PreProcessor - "
205 | "Copyright (C) 2017 Griefer@Work "
206 | "["
207 | #if TPP_CONFIG_DEBUG
208 | "DEBUG|"
209 | #endif /* TPP_CONFIG_DEBUG */
210 | #if TPP_CONFIG_ONELEXER
211 | "ONE|"
212 | #endif /* TPP_CONFIG_ONELEXER */
213 | #ifdef __TPP_VERSION__
214 | "TPP " STR(__TPP_VERSION__) "|"
215 | #endif
216 | TPP_COMPILER
217 | #if defined(__TIME__) && defined(__DATE__)
218 | "|" __TIME__ " " __DATE__
219 | #endif
220 | "]\n\n";
221 |
222 | struct tpp_extension {
223 | int e_flag;
224 | char const *e_name;
225 | size_t e_size;
226 | };
227 | extern struct tpp_extension const tpp_extensions[];
228 | extern char const *const wgroup_names[TPP(WG_COUNT) + 1];
229 |
230 | void usage(char *appname, char *subject) {
231 | if (subject) {
232 | if (!strcmp(subject, "extensions")) {
233 | struct tpp_extension const *iter;
234 | for (iter = tpp_extensions; iter->e_name; ++iter) {
235 | fprintf(stderr, "-f%s%s\n", TPPLexer_HasExtension(iter - tpp_extensions) ? "" : "no-", iter->e_name);
236 | }
237 | } else if (!strcmp(subject, "warnings")) {
238 | char const *const *iter;
239 | #define getstate(wid) \
240 | (TPP(wstate_t))((TPPLexer_Current->l_warnings.w_curstate->ws_state[(wid) / (8 / TPP_WARNING_BITS)] >> \
241 | (((wid) % (8 / TPP_WARNING_BITS)) * TPP_WARNING_BITS)) & \
242 | 3)
243 | for (iter = wgroup_names; *iter; ++iter) {
244 | fprintf(stderr, "-W%s%s\n",
245 | getstate(iter - wgroup_names) == TPP(WSTATE_DISABLE) ? "no-"
246 | : "",
247 | *iter);
248 | }
249 | #undef getstate
250 | } else {
251 | fprintf(stderr, "Unknown subject: %s\n", subject);
252 | }
253 | return;
254 | }
255 | fprintf(stderr, "Usage: %s [options...] [-o outfile] [infile]\n"
256 | " %s [options...] [-o outfile] -i string...\n"
257 | "options:\n"
258 | #define INDENT "\t"
259 | INDENT "-o Redirect output to a given file (defauls to STDOUT).\n"
260 | INDENT "-i Preprocess the remained of the commandline\n"
261 | INDENT "-Idir Adds `dir' to the list of #include <...> paths\n"
262 | INDENT "-Dsym[=val=1] Defines `sym' as `val'\n"
263 | INDENT "-Usym Undefine a previously defined symbol `sym'\n"
264 | INDENT "-Apred=answer Define an assertion `pred' as `answer'\n"
265 | INDENT "-A-pred[=answer] Delete `answer' or all assertions previously made about `pred'\n"
266 | INDENT "-P Disable emission of #line adjustment directives (Default: on).\n"
267 | INDENT "-M Instead of emitting preprocessor output, emit a make-style list of dependencies.\n"
268 | INDENT "-MM Similar to `-M', but don't include system headers.\n"
269 | INDENT "-MD Like `-M', but don't disable preprocessing.\n"
270 | INDENT "-MMD Like `-MD', but don't disable preprocessing.\n"
271 | INDENT "-MG Disable preprocessing, but include missing files as dependencies, assuming they will be generated.\n"
272 | INDENT "-MP Emit dummy targets for every dependency.\n"
273 | INDENT "-MF Enable dependency tracking and emit its output to , but also preprocess regularly.\n"
274 | INDENT "-MT Specify the target object name used within the generated make dependency.\n"
275 | INDENT "-MQ Same as `-MT', but escape characters special to make, such as `$'.\n"
276 | INDENT "-trigraphs Enable recognition of trigraph character sequences.\n"
277 | INDENT "-traditional[-cpp] Enable recognition of traditional tokens & macros (Default: off).\n"
278 | INDENT "-undef Disable all builtin macros.\n"
279 | INDENT "--tok Outline all tokens using the [...] notation (Default: off).\n"
280 | INDENT "--pp Enable preprocess-mode, which emits all tokens separated by `\\0'-bytes.\n"
281 | INDENT " Enabling this option also disabled SPACE and LF tokens, though\n"
282 | INDENT " they can be re-enabled using the -spc and -lf switches.\n"
283 | INDENT "-ftabstop=width Set the width of tab characters used by __COLUMN__ and in warning/error messages (Default: " STR(TPPLEXER_DEFAULT_TABSIZE) ")\n"
284 | INDENT "-f[no-]spc Configure emission of SPACE tokens (Default: on).\n"
285 | INDENT "-f[no-]lf Configure emission of LF tokens (Default: on).\n"
286 | INDENT "-f[no-]comments Configure emission of COMMENT tokens (Default: off).\n"
287 | INDENT "-f[no-]magiclf Enable/Disable magic linefeeds sometimes used in place of #line (Default: off).\n"
288 | INDENT "-f[no-]longstring Enable/Disable string continuation between lines (Default: off).\n"
289 | INDENT "-f[(cpp|no)-]line Enable/Disable emission of #line directives (Default: cpp-compatible).\n"
290 | INDENT "-f[no-]decode Enable/Disable decoding of di/tri-graphs, as well as escaped linefeeds in output (Default: on).\n"
291 | INDENT "-f[no-]unify-pragma Unify all unknown pragmas to use the preprocessor-directive syntax before re-emission (Default: on).\n"
292 | INDENT "-f[no-] Enable/Disable a given `extension' (s.a.: `--help extensions').\n"
293 | INDENT "-W[no-] Enable/Disable a given `warning' group (s.a.: `--help warnings').\n"
294 | INDENT "--name Set the name used for __FILE__ by INFILE (Useful when INFILE is stdin).\n"
295 | INDENT "--help [subject] Display this help and exit.\n"
296 | INDENT " When specified, subject may be one of {extensions|warnings}\n"
297 | INDENT "--version Display version information and exit.\n"
298 | #ifdef _WIN32
299 | INDENT "--message-format={msvc|gcc} Set the format for error message (Default: msvc).\n"
300 | #else /* _WIN32 */
301 | INDENT "--message-format={msvc|gcc} Set the format for error message (Default: gcc).\n"
302 | #endif /* !_WIN32 */
303 | "infile:\n"
304 | INDENT "- When not specified or set to `-', use STDIN as input\n"
305 | INDENT " The name of a file to preprocess, as well as the default value for `--name'\n",
306 | appname, appname);
307 | #undef INDENT
308 | }
309 |
310 | static /*ref*/ struct TPPString *
311 | merge_argv_str(int argc, char **argv) {
312 | struct TPPString *result;
313 | char **iter, **end, *dest;
314 | size_t total_size;
315 | if (!argc)
316 | return TPPString_New("", 0);
317 | total_size = argc - 1; /* All arguments are separated by ` '. */
318 | end = (iter = argv) + argc;
319 | for (; iter != end; ++iter)
320 | total_size += strlen(*iter);
321 | result = TPPString_NewSized(total_size);
322 | if (!result)
323 | return NULL;
324 | dest = result->s_text;
325 | for (iter = argv; iter != end; ++iter) {
326 | size_t len = strlen(*iter);
327 | memcpy(dest, *iter, len * sizeof(char));
328 | dest += len;
329 | *dest++ = ' ';
330 | }
331 | return result;
332 | }
333 |
334 | static /*ref*/ struct TPPFile *
335 | merge_argv(int argc, char **argv) {
336 | struct TPPString *argv_string;
337 | struct TPPFile *result;
338 | argv_string = merge_argv_str(argc, argv);
339 | if (!argv_string)
340 | return NULL;
341 | result = (struct TPPFile *)malloc(TPPFILE_SIZEOF_TEXT);
342 | if (!result)
343 | goto err_argv_string;
344 | result->f_refcnt = 1;
345 | result->f_kind = TPPFILE_KIND_TEXT;
346 | result->f_prev = NULL;
347 | result->f_name = strdup("");
348 | if (!result->f_name)
349 | goto err_r;
350 | result->f_namesize = 13;
351 | #if __SIZEOF_POINTER__ == 8
352 | result->f_namehash = 12182544704004658106ull;
353 | #else /* __SIZEOF_POINTER__ == 8 */
354 | result->f_namehash = 3330511802ul;
355 | #endif /* __SIZEOF_POINTER__ != 8 */
356 | result->f_text = argv_string; /* Inherit reference. */
357 | result->f_begin = argv_string->s_text;
358 | result->f_end = argv_string->s_text + argv_string->s_size;
359 | result->f_pos = argv_string->s_text;
360 | result->f_textfile.f_cacheentry = NULL;
361 | result->f_textfile.f_usedname = NULL;
362 | result->f_textfile.f_lineoff = 0;
363 | result->f_textfile.f_stream = TPP_STREAM_INVALID;
364 | result->f_textfile.f_ownedstream = TPP_STREAM_INVALID;
365 | result->f_textfile.f_guard = NULL;
366 | result->f_textfile.f_cacheinc = 0;
367 | result->f_textfile.f_rdata = argv_string->s_size;
368 | result->f_textfile.f_prefixdel = '\0';
369 | result->f_textfile.f_flags = TPP_TEXTFILE_FLAG_NOGUARD;
370 | result->f_textfile.f_newguard = NULL;
371 | return result;
372 | err_r:
373 | free(result);
374 | err_argv_string:
375 | TPPString_Decref(argv_string);
376 | return NULL;
377 | }
378 |
379 | static struct TPPFile *last_token_file;
380 | static char *last_token_end;
381 | size_t file_offset;
382 | static void pp_print(char const *buf, size_t bufsize) {
383 | if (outline_tokens == OUTLINE_MODE_TOK)
384 | out_write("[", sizeof(char));
385 | out_write(buf, bufsize * sizeof(char));
386 | switch (outline_tokens) {
387 |
388 | case OUTLINE_MODE_ZERO:
389 | out_write("\0", sizeof(char));
390 | is_at_linefeed = 1;
391 | break;
392 | case OUTLINE_MODE_TOK:
393 | out_write("]", sizeof(char));
394 | /* FALLTHRU */
395 | default:
396 | is_at_linefeed = 0;
397 | break;
398 | }
399 | }
400 | static void pp_emit_raw(void) {
401 | last_token_file = TPPLexer_Current->l_token.t_file;
402 | last_token_end = TPPLexer_Current->l_token.t_end;
403 | file_offset = get_file_offset(last_token_end);
404 | if (outline_tokens == OUTLINE_MODE_TOK)
405 | out_write("[", sizeof(char));
406 | if (decode_tokens) {
407 | TPP_PrintToken(&out_printer, NULL);
408 | if (TPPLexer_Current->l_token.t_id == '\n')
409 | ++current_line;
410 | } else {
411 | out_write(TPPLexer_Current->l_token.t_begin,
412 | (size_t)(TPPLexer_Current->l_token.t_end -
413 | TPPLexer_Current->l_token.t_begin) *
414 | sizeof(char));
415 | /* Track what we expect the current line number to be,
416 | * which is them compared to the actual line number. */
417 | current_line += count_linefeeds(TPPLexer_Current->l_token.t_begin,
418 | TPPLexer_Current->l_token.t_end);
419 | }
420 | switch (outline_tokens) {
421 |
422 | case OUTLINE_MODE_ZERO:
423 | out_write("\0", sizeof(char));
424 | is_at_linefeed = 1;
425 | break;
426 |
427 | case OUTLINE_MODE_TOK:
428 | out_write("]", sizeof(char));
429 | is_at_linefeed = 0;
430 | break;
431 |
432 | default:
433 | is_at_linefeed = last_token_end[-1] == '\n' ||
434 | last_token_end[-1] == '\r';
435 | break;
436 | }
437 | }
438 | static void pp_emit(void) {
439 | if (last_token_file != TPPLexer_Current->l_token.t_file ||
440 | (last_token_end != TPPLexer_Current->l_token.t_begin &&
441 | file_offset != get_file_offset(TPPLexer_Current->l_token.t_begin))) {
442 | /* The file changed, or there is a difference in the in-file position
443 | * between the end of the last token and the start of this one.
444 | * >> In any case, we must update the #line offset. */
445 | put_line();
446 | }
447 | pp_emit_raw();
448 | }
449 |
450 | static void pp_normal(void) {
451 | /* Initial values to simulate the last token
452 | * ending where the first file starts. */
453 | last_token_file = NULL; // infile; /* Force a line directive at the first token. */
454 | last_token_end = TPPLexer_Current->l_token.t_file->f_begin;
455 | file_offset = 0;
456 | current_line = 0;
457 | is_at_linefeed = 1;
458 | while (TPPLexer_Yield() > 0)
459 | pp_emit();
460 | if (outline_tokens == OUTLINE_MODE_ZERO) {
461 | out_write("\0", sizeof(char));
462 | }
463 | }
464 |
465 | static TPP(stream_t) dep_outfile = TPP_STREAM_INVALID;
466 | static int dep_nonsystem_only = 0;
467 | static int dep_emit_dummy = 0;
468 | static void write_filename(TPP(stream_t) fd, char const *p, size_t s) {
469 | /* TODO: Escape special characters, such as ` ' or `\\' */
470 | write(fd, p, s * sizeof(char));
471 | }
472 |
473 | static void write_filename_makeescape(TPP(stream_t) fd, char const *p, size_t s) {
474 | /* TODO: Escape special characters, such as `$' */
475 | write_filename(fd, p, s);
476 | }
477 |
478 | static size_t curline_length = 0;
479 | static void pp_depprint(char *filename, size_t filename_size) {
480 | #define DEP_MAX_LINELENGTH 70
481 | if (dep_outfile == TPP_STREAM_INVALID)
482 | return;
483 | if ((curline_length += (filename_size + 1)) >= DEP_MAX_LINELENGTH) {
484 | write(dep_outfile, " \\\n\t", 4 * sizeof(char));
485 | curline_length = 0;
486 | } else {
487 | write(dep_outfile, " ", 1 * sizeof(char));
488 | }
489 | write_filename(dep_outfile, filename, filename_size);
490 | }
491 |
492 | static char **dep_filenamev = NULL;
493 | static size_t dep_filenamec = 0;
494 | static size_t dep_filenamea = 0;
495 | static int pp_add_dep_filename(char const *filename, size_t filename_size) {
496 | char *filename_copy, **new_vec;
497 | if (!dep_emit_dummy || dep_outfile == TPP_STREAM_INVALID)
498 | return 1;
499 | filename_copy = (char *)malloc((filename_size + 1) * sizeof(char));
500 | if (!filename_copy)
501 | return 0;
502 | memcpy(filename_copy, filename, filename_size * sizeof(char));
503 | filename_copy[filename_size] = '\0';
504 | new_vec = dep_filenamev;
505 | if (dep_filenamea == dep_filenamec) {
506 | size_t new_alloc = dep_filenamea ? dep_filenamea * 2 : 2;
507 | new_vec = (char **)realloc(new_vec, new_alloc * sizeof(char *));
508 | if (!new_vec) {
509 | free(filename_copy);
510 | return 0;
511 | }
512 | dep_filenamev = new_vec;
513 | dep_filenamea = new_alloc;
514 | }
515 | new_vec[dep_filenamec++] = filename_copy;
516 | return 1;
517 | }
518 |
519 | static void pp_emit_dummy_targets(void) {
520 | char **iter, **end, *filename;
521 | end = (iter = dep_filenamev) + dep_filenamec;
522 | if (dep_outfile == TPP_STREAM_INVALID)
523 | dep_emit_dummy = 0;
524 | for (; iter != end; ++iter) {
525 | filename = *iter;
526 | if (dep_emit_dummy) {
527 | write(dep_outfile, "\n\n", 2 * sizeof(char));
528 | write_filename(dep_outfile, filename, strlen(filename));
529 | write(dep_outfile, ":", sizeof(char));
530 | }
531 | free(filename);
532 | }
533 | free(dep_filenamev);
534 | dep_filenamev = NULL;
535 | dep_filenamec = 0;
536 | dep_filenamea = 0;
537 | if (dep_outfile != TPP_STREAM_INVALID) {
538 | write(dep_outfile, "\n", 1 * sizeof(char));
539 | }
540 | }
541 |
542 |
543 | static int pp_depcallback(struct TPPFile *file, int is_system_header) {
544 | /* Don't emit entries for system header if we`re not supposed to. */
545 | if (is_system_header && dep_nonsystem_only)
546 | return 1;
547 | if (!pp_add_dep_filename(file->f_name, file->f_namesize))
548 | return 0;
549 | pp_depprint(file->f_name, file->f_namesize);
550 | return 1;
551 | }
552 |
553 |
554 | static struct TPPFile *TPPCALL
555 | pp_depunknown(int mode, char *__restrict filename,
556 | size_t filename_size,
557 | struct TPPKeyword **pkeyword_entry) {
558 | (void)mode;
559 | (void)pkeyword_entry;
560 | if (!pp_add_dep_filename(filename, filename_size))
561 | TPPLexer_SetErr();
562 | pp_depprint(filename, filename_size);
563 | return NULL;
564 | }
565 |
566 | static int dep_escapetarget = 0; /* Escape characters special to make from `dep_targetname'. */
567 | static char *dep_targetname = NULL;
568 | static int pp_depfirst(struct TPPFile *file) {
569 | char *used_filename, *filename_extension, old;
570 | if (dep_outfile == TPP_STREAM_INVALID)
571 | return 1;
572 | used_filename = file->f_name;
573 | if (dep_targetname) {
574 | dep_escapetarget
575 | ? write_filename_makeescape(dep_outfile, dep_targetname, strlen(dep_targetname))
576 | : write_filename(dep_outfile, dep_targetname, strlen(dep_targetname));
577 | } else {
578 | filename_extension = strrchr(used_filename, '.');
579 | if (!filename_extension) {
580 | size_t filename_size = file->f_namesize;
581 | used_filename = (char *)malloc((filename_size + 2) * sizeof(char));
582 | if (!used_filename)
583 | return 0;
584 | memcpy(used_filename, file->f_name, filename_size * sizeof(char));
585 | filename_extension = used_filename + filename_size;
586 | *filename_extension = '.';
587 | }
588 | old = filename_extension[1], filename_extension[1] = 'o';
589 | write_filename_makeescape(dep_outfile, used_filename, ((filename_extension - used_filename) + 2));
590 | filename_extension[1] = old;
591 | if (used_filename != file->f_name)
592 | free(used_filename);
593 | }
594 | write(dep_outfile, ":", 1 * sizeof(char));
595 | pp_depprint(file->f_name, file->f_namesize);
596 | return 1;
597 | }
598 |
599 | static void pp_deponly(void) {
600 | /* fallback: Use stdout as output file for dependencies if no other file was set.
601 | * HINT: stdout may have previously been redirected with the '-o' option. */
602 | if (dep_outfile == TPP_STREAM_INVALID)
603 | dep_outfile = stdout_handle;
604 | TPPLexer_Current->l_callbacks.c_parse_pragma = NULL;
605 | while (TPPLexer_Yield() > 0)
606 | ;
607 | }
608 |
609 | static int reemit_pragma(void) {
610 | #define PRAGMA_COPYMASK \
611 | (TPPLEXER_FLAG_WANTCOMMENTS | \
612 | TPPLEXER_FLAG_WANTSPACE | \
613 | TPPLEXER_FLAG_WANTLF)
614 | if (!is_at_linefeed && outline_tokens != OUTLINE_MODE_NONE)
615 | pp_print("\n", 1), ++current_line;
616 | pp_print("#", 1);
617 | pp_print("pragma", 6);
618 | if (base_flags & TPPLEXER_FLAG_WANTSPACE)
619 | pp_print(" ", 1);
620 | TPPLexer_Current->l_flags &= ~(PRAGMA_COPYMASK);
621 | TPPLexer_Current->l_flags |= (base_flags & PRAGMA_COPYMASK);
622 | do {
623 | pp_emit_raw();
624 | } while (TPPLexer_Yield() > 0);
625 | pp_print("\n", 1);
626 | ++current_line;
627 | is_at_linefeed = 1;
628 | last_token_file = NULL;
629 | last_token_end = NULL;
630 | return 1;
631 | }
632 |
633 |
634 | #ifdef _WIN32
635 | #define close_stream CloseHandle
636 | #else /* _WIN32 */
637 | #define close_stream close
638 | #endif /* !_WIN32 */
639 |
640 | static TPP(stream_t) open_out_file(char const *filename) {
641 | TPP(stream_t)
642 | result;
643 | if (!strcmp(filename, "-"))
644 | return stdout_handle;
645 | #ifdef _WIN32
646 | result = CreateFileA(filename, GENERIC_WRITE,
647 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
648 | NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
649 | if (!result)
650 | result = TPP_STREAM_INVALID;
651 | #else /* _WIN32 */
652 | result = open(filename, O_CREAT | O_WRONLY, 0644);
653 | #endif /* !_WIN32 */
654 | if (result == TPP_STREAM_INVALID) {
655 | fprintf(stderr, "Failed to create output file: \"%s\"\n", filename);
656 | fflush(stderr);
657 | _exit(1);
658 | }
659 | return result;
660 | }
661 |
662 | #define PPMODE_NORMAL 0
663 | #define PPMODE_DEPENDENCY 1
664 | int main(int argc, char *argv[]) {
665 | struct TPPFile *infile;
666 | int result = 0;
667 | int pp_mode = PPMODE_NORMAL;
668 | char *output_filename = NULL, *appname, *firstname = NULL;
669 | #ifdef _WIN32
670 | stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
671 | #endif /* _WIN32 */
672 | if (!TPP_INITIALIZE())
673 | return 1;
674 | if (argc)
675 | appname = argv[0], --argc, ++argv;
676 | else {
677 | appname = "tpp";
678 | }
679 | TPPLexer_Current->l_callbacks.c_parse_pragma = &reemit_pragma;
680 | TPPLexer_Current->l_flags |= (TPPLEXER_FLAG_WANTSPACE |
681 | TPPLEXER_FLAG_WANTLF |
682 | #ifdef _WIN32
683 | TPPLEXER_FLAG_MSVC_MESSAGEFORMAT |
684 | #endif /* _WIN32 */
685 | TPPLEXER_FLAG_TERMINATE_STRING_LF);
686 | #if 1
687 | #define BACKWARDS(x) x /* Backwards-compatibility with old TPP */
688 | #else
689 | #define BACKWARDS(x) /* nothing */
690 | #endif
691 | while (argc && (argv[0][0] == '-' BACKWARDS(|| argv[0][0] == '/'))) {
692 | char *arg = argv[0] + 1;
693 | /* TODO: Look at the arguments `cpp' can take and try to implement them all (or most).
694 | * >> This new version of TPP is meant as a drop-in replacement for cpp! */
695 | if (!strcmp(arg, "-tok")
696 | BACKWARDS(|| !strcmp(arg, "tok"))
697 | BACKWARDS(|| !strcmp(arg, "-tokens"))) {
698 | outline_tokens = OUTLINE_MODE_TOK;
699 | } else if (!strcmp(arg, "fspc")) {
700 | TPPLexer_Current->l_flags |= TPPLEXER_FLAG_WANTSPACE;
701 | } else if (!strcmp(arg, "fno-spc")) {
702 | TPPLexer_Current->l_flags &= ~(TPPLEXER_FLAG_WANTSPACE);
703 | } else if (!strcmp(arg, "flf")) {
704 | TPPLexer_Current->l_flags |= TPPLEXER_FLAG_WANTLF;
705 | } else if (!strcmp(arg, "fno-lf")) {
706 | TPPLexer_Current->l_flags &= ~(TPPLEXER_FLAG_WANTLF);
707 | } else if (!strcmp(arg, "fcomments")) {
708 | TPPLexer_Current->l_flags |= TPPLEXER_FLAG_WANTCOMMENTS;
709 | } else if (!strcmp(arg, "fno-comments")) {
710 | TPPLexer_Current->l_flags &= ~(TPPLEXER_FLAG_WANTCOMMENTS);
711 | } else if (!strcmp(arg, "fmagiclf")) {
712 | no_magic_tokens = 0;
713 | } else if (!strcmp(arg, "fno-magiclf")) {
714 | no_magic_tokens = 1;
715 | } else if (!strcmp(arg, "fdecode")) {
716 | decode_tokens = 1;
717 | } else if (!strcmp(arg, "fno-decode")) {
718 | decode_tokens = 0;
719 | } else if (!strcmp(arg, "flongstring")) {
720 | TPPLexer_Current->l_flags &= ~(TPPLEXER_FLAG_TERMINATE_STRING_LF);
721 | } else if (!strcmp(arg, "fno-longstring")) {
722 | TPPLexer_Current->l_flags |= TPPLEXER_FLAG_TERMINATE_STRING_LF;
723 | } else if (!strcmp(arg, "funify-pragma")) {
724 | TPPLexer_Current->l_callbacks.c_parse_pragma = &reemit_pragma;
725 | } else if (!strcmp(arg, "fno-unify-pragma")) {
726 | TPPLexer_Current->l_callbacks.c_parse_pragma = NULL;
727 | } else if (!strcmp(arg, "fline")) {
728 | line_directives = 1;
729 | } else if (!strcmp(arg, "fno-line") BACKWARDS(|| !strcmp(arg, "no-line"))) {
730 | line_directives = 0;
731 | } else if (!strcmp(arg, "fcpp-line")) {
732 | line_directives = 2;
733 | } else if (!memcmp(arg, "ftabstop=", 9 * sizeof(char))) {
734 | TPPLexer_Current->l_tabsize = (size_t)atol(arg + 9);
735 | } else if (!strcmp(arg, "trigraphs")) {
736 | TPPLexer_EnableExtension(EXT_TRIGRAPHS);
737 | } else if (!strcmp(arg, "traditional") ||
738 | !strcmp(arg, "traditional-cpp")) {
739 | TPPLexer_EnableExtension(EXT_TRADITIONAL_MACRO);
740 | TPPLexer_Current->l_extokens |= TPPLEXER_TOKEN_EQUALBINOP;
741 | } else if (!strcmp(arg, "Werror")) {
742 | TPPLexer_Current->l_flags |= TPPLEXER_FLAG_WERROR;
743 | }
744 | #if !TPP_CONFIG_MINMACRO
745 | else if (!strcmp(arg, "undef")) {
746 | TPPLexer_DisableExtension(EXT_CPU_MACROS);
747 | TPPLexer_DisableExtension(EXT_SYSTEM_MACROS);
748 | TPPLexer_DisableExtension(EXT_UTILITY_MACROS);
749 | }
750 | #else /* !TPP_CONFIG_MINMACRO */
751 | else if (!strcmp(arg, "undef")) {
752 | }
753 | #endif /* TPP_CONFIG_MINMACRO */
754 | else if (!strcmp(arg, "P")) {
755 | line_directives = 0;
756 | } else if (!strcmp(arg, "M") ||
757 | !strcmp(arg, "MM")) {
758 | /* Switch to dependency-only mode. */
759 | pp_mode = PPMODE_DEPENDENCY;
760 | /* Change the output file to stdout. */
761 | if (dep_outfile == TPP_STREAM_INVALID)
762 | dep_outfile = stdout_handle;
763 | /* Check if we`re supposed to include system-headeres. */
764 | dep_nonsystem_only = !strcmp(arg, "MM");
765 | } else if (!strcmp(arg, "MD") ||
766 | !strcmp(arg, "MMD")) {
767 | /* Change the output file to stdout. */
768 | if (dep_outfile == TPP_STREAM_INVALID)
769 | dep_outfile = stdout_handle;
770 | /* Check if we`re supposed to include system-headeres. */
771 | dep_nonsystem_only = !strcmp(arg, "MMD");
772 | } else if (!strcmp(arg, "MG")) {
773 | /* Setup an unknown-file handler, assuming generated headers. */
774 | TPPLexer_Current->l_callbacks.c_unknown_file = &pp_depunknown;
775 | /* Disable file-not-found warnings (We`re assuming generated headers). */
776 | TPPLexer_SetWarning(TPP(W_FILE_NOT_FOUND), TPP(WSTATE_DISABLE));
777 | /* Switch to dependency-only mode. */
778 | pp_mode = PPMODE_DEPENDENCY;
779 | } else if (!strcmp(arg, "MP")) {
780 | dep_emit_dummy = 1; /* Emit a dummy target for every dependency. */
781 | } else if (!strcmp(arg, "MF")) {
782 | if (argc > 1) {
783 | /* Close a previously opened dependency output stream. */
784 | if (dep_outfile != TPP_STREAM_INVALID && dep_outfile != stdout_handle)
785 | close_stream(dep_outfile);
786 | dep_outfile = open_out_file(argv[1]);
787 | ++argv;
788 | --argc;
789 | }
790 | } else if (!strcmp(arg, "MT") || /* Specify a custom target name for dependencies. */
791 | !strcmp(arg, "MQ")) {
792 | if (argc > 1) {
793 | dep_targetname = argv[1];
794 | ++argv;
795 | --argc;
796 | }
797 | dep_escapetarget = !strcmp(arg, "MQ");
798 | } else if (!strcmp(arg, "o") BACKWARDS(|| !strcmp(arg, "-out"))) {
799 | if (argc > 1) {
800 | output_filename = argv[1];
801 | ++argv;
802 | --argc;
803 | }
804 | } else if (!strcmp(arg, "-name")) {
805 | if (argc > 1) {
806 | firstname = argv[1];
807 | ++argv;
808 | --argc;
809 | }
810 | } else if (!strcmp(arg, "-message-format=gcc")) {
811 | TPPLexer_Current->l_flags &= ~(TPPLEXER_FLAG_MSVC_MESSAGEFORMAT);
812 | } else if (!strcmp(arg, "-message-format=msvc")) {
813 | TPPLexer_Current->l_flags |= TPPLEXER_FLAG_MSVC_MESSAGEFORMAT;
814 | } else if (!strcmp(arg, "-help") BACKWARDS(|| !strcmp(arg, "h") || !strcmp(arg, "?"))) {
815 | usage(appname, argc > 1 && argv[1][0] != '-' ? argv[1] : NULL), _exit(2);
816 | } else if (!strcmp(arg, "-version") BACKWARDS(|| !strcmp(arg, "v"))) {
817 | fwrite(version, sizeof(char), sizeof(version) / sizeof(char) - 1, stderr), _exit(2);
818 | } else if (!strcmp(arg, "i") BACKWARDS(|| !strcmp(arg, "-in"))) {
819 | if (argc) {
820 | --argc;
821 | ++argv;
822 | }
823 | infile = merge_argv(argc, argv);
824 | goto use_infile;
825 | } else if (!strcmp(arg, "-pp")) {
826 | /* Intermediate preprocessor mode:
827 | * - Very useful for invoking tpp from another
828 | * application to really just tokenize a file.
829 | * - Emit tokens separated by `\0'-characters
830 | * - Don't emit whitespace, or linefeeds.
831 | */
832 | TPPLexer_Current->l_flags &= ~(TPPLEXER_FLAG_WANTSPACE |
833 | TPPLEXER_FLAG_WANTLF);
834 | outline_tokens = OUTLINE_MODE_ZERO;
835 | } else if (*arg == 'I') {
836 | ++arg;
837 | BACKWARDS(add_inc:)
838 | if (!*arg && argc > 1)
839 | arg = argv[1], ++argv, --argc;
840 | if (!TPPLexer_AddIncludePath(arg, strlen(arg)))
841 | _exit(1);
842 | } else if (*arg == 'D') {
843 | char *val;
844 | ++arg;
845 | BACKWARDS(add_def:)
846 | if (!*arg && argc > 1)
847 | arg = argv[1], ++argv, --argc;
848 | val = strchr(arg, '=');
849 | if (val)
850 | *val++ = '\0';
851 | else {
852 | val = "1";
853 | }
854 | if (!TPPLexer_Define(arg, strlen(arg), val, strlen(val),
855 | TPPLEXER_DEFINE_FLAG_BUILTIN))
856 | _exit(1);
857 | } else if (*arg == 'U') {
858 | if (!*++arg && argc > 1)
859 | arg = argv[1], ++argv, --argc;
860 | TPPLexer_Undef(arg, strlen(arg));
861 | } else if (*arg == 'A') {
862 | int add = 1;
863 | char *val;
864 | if (!*++arg && argc > 1)
865 | arg = argv[1], ++argv, --argc;
866 | if (*arg == '-')
867 | ++arg, add = 0;
868 | val = strchr(arg, '=');
869 | if (val)
870 | *val++ = '\0';
871 | else if (add) {
872 | goto noopt;
873 | }
874 | if (add)
875 | TPPLexer_AddAssert(arg, strlen(arg), val, strlen(val));
876 | else {
877 | TPPLexer_DelAssert(arg, strlen(arg), val, val ? strlen(val) : 0);
878 | }
879 | } else if (*arg == 'f') {
880 | int enable = 1;
881 | ++arg; /* Set an extension. */
882 | if (!memcmp(arg, "no-", 3))
883 | arg += 3, enable = 0;
884 | if (!TPPLexer_SetExtension(arg, enable))
885 | goto noopt;
886 | } else if (*arg == 'W') {
887 | TPP(wstate_t)
888 | state = TPP(WSTATE_ERROR);
889 | ++arg; /* Set an extension. */
890 | if (!memcmp(arg, "no-", 3))
891 | arg += 3, state = TPP(WSTATE_DISABLE);
892 | if (!TPPLexer_SetWarnings(arg, state))
893 | goto noopt;
894 | }
895 | BACKWARDS(else if (!memcmp(arg, "-Inc", 4)) {
896 | arg += 4;
897 | goto add_inc;
898 | })
899 | BACKWARDS(else if (!memcmp(arg, "-Def", 4)) {
900 | arg += 4;
901 | goto add_def;
902 | })
903 | else {
904 | noopt:
905 | fprintf(stderr,
906 | "Unknown option: \"%s\"\n"
907 | "See '%s --help' for more help\n",
908 | arg - 1, appname);
909 | _exit(1);
910 | }
911 | --argc, ++argv;
912 | }
913 | if (output_filename && strcmp(output_filename, "-")) {
914 | TPP(stream_t)
915 | newout = open_out_file(output_filename);
916 | if (dep_outfile == stdout_handle)
917 | dep_outfile = newout;
918 | #ifdef _WIN32
919 | stdout_handle = newout;
920 | #else /* _WIN32 */
921 | dup2(STDOUT_FILENO, newout);
922 | #endif /* !_WIN32 */
923 | }
924 | if (argc && strcmp(argv[0], "-") != 0) {
925 | infile = TPPLexer_OpenFile(TPPLEXER_OPENFILE_MODE_NORMAL |
926 | TPPLEXER_OPENFILE_FLAG_NOCASEWARN,
927 | argv[0], strlen(argv[0]), NULL);
928 | if (infile)
929 | TPPFile_Incref(infile);
930 | if (infile && firstname) {
931 | infile->f_textfile.f_usedname = TPPString_New(firstname, strlen(firstname));
932 | if (!infile->f_textfile.f_usedname)
933 | _exit(1);
934 | }
935 | if (!infile)
936 | fprintf(stderr, "File not found: \"%s\"\n", argv[0]);
937 | } else {
938 | /* Fallback: Use stdin as input stream. */
939 | if (!firstname)
940 | firstname = "";
941 | #ifdef _WIN32
942 | infile = TPPFile_OpenStream(GetStdHandle(STD_INPUT_HANDLE), firstname);
943 | #else /* _WIN32 */
944 | infile = TPPFile_OpenStream(STDIN_FILENO, firstname);
945 | #endif /* !_WIN32 */
946 | }
947 | use_infile:
948 | if (!infile)
949 | goto err1;
950 | TPPLexer_PushFileInherited(infile);
951 | TPPLexer_Current->l_callbacks.c_new_textfile = &pp_depcallback;
952 | if (!pp_depfirst(infile))
953 | goto err1;
954 | base_flags = TPPLexer_Current->l_flags;
955 | switch (pp_mode) {
956 |
957 | case PPMODE_DEPENDENCY:
958 | pp_deponly();
959 | break;
960 |
961 | default:
962 | pp_normal();
963 | break;
964 | }
965 | pp_emit_dummy_targets();
966 | /* Check if something went wrong. */
967 | if ((TPPLexer_Current->l_flags & TPPLEXER_FLAG_ERROR) ||
968 | (TPPLexer_Current->l_errorcount != 0))
969 | result = 1;
970 | end:
971 | TPP_FINALIZE();
972 | #ifdef _CRTDBG_MAP_ALLOC
973 | _CrtDumpMemoryLeaks();
974 | #endif /* _CRTDBG_MAP_ALLOC */
975 | return result;
976 | err1:
977 | result = 1;
978 | goto end;
979 | }
980 |
981 | #ifdef __cplusplus
982 | }
983 | #endif /* __cplusplus */
984 |
--------------------------------------------------------------------------------
/src/tpp-backwards-compatibility.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2025 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2025 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #ifndef GUARD_TPP_BACKWARDS_COMPATIBILITY_H
21 | #define GUARD_TPP_BACKWARDS_COMPATIBILITY_H 1
22 |
23 | #ifndef TPP
24 | #define TPP(x) TPP_##x
25 | #endif /* !TPP */
26 |
27 | #include "tpp.h"
28 |
29 | /* NOTE: This header is completely optional and only required
30 | * for backwards compatibility with the old TPP. */
31 |
32 | #ifdef __cplusplus
33 | extern "C" {
34 | #endif /* __cplusplus */
35 |
36 | /* Old token names. */
37 | #define TPP_TOK_EOF TPP(TOK_EOF)
38 | #define TPP_TOK_SPACE TPP(TOK_SPACE)
39 | #define TPP_TOK_LF TPP(TOK_LF)
40 | #define TPP_TOK_INT TPP(TOK_INT)
41 | #define TPP_TOK_FLOAT TPP(TOK_FLOAT)
42 | #define TPP_TOK_COMMENT TPP(TOK_COMMENT)
43 | #define TPP_TOK_CHR TPP(TOK_CHAR)
44 | #define TPP_TOK_STR TPP(TOK_STRING)
45 | #define TPP_TOK_ASSIGN TPP(TOK_ASSIGN)
46 | #define TPP_TOK_CMP_LO TPP(TOK_LOWER)
47 | #define TPP_TOK_CMP_GR TPP(TOK_GREATER)
48 | #define TPP_TOK_QUESTION TPP(TOK_QUESTION)
49 | #define TPP_TOK_COLLON TPP(TOK_COLON)
50 | #define TPP_TOK_ADD TPP(TOK_ADD)
51 | #define TPP_TOK_SUB TPP(TOK_SUB)
52 | #define TPP_TOK_MUL TPP(TOK_MUL)
53 | #define TPP_TOK_DIV TPP(TOK_DIV)
54 | #define TPP_TOK_MOD TPP(TOK_MOD)
55 | #define TPP_TOK_DOT TPP(TOK_DOT)
56 | #define TPP_TOK_COMMA TPP(TOK_COMMA)
57 | #define TPP_TOK_SEMICOLON TPP(TOK_SEMICOLON)
58 | #define TPP_TOK_HASH TPP(TOK_HASH)
59 | #define TPP_TOK_LPAREN TPP(TOK_LPAREN)
60 | #define TPP_TOK_RPAREN TPP(TOK_RPAREN)
61 | #define TPP_TOK_LBRACKET TPP(TOK_LBRACKET)
62 | #define TPP_TOK_RBRACKET TPP(TOK_RBRACKET)
63 | #define TPP_TOK_LBRACE TPP(TOK_LBRACE)
64 | #define TPP_TOK_RBRACE TPP(TOK_RBRACE)
65 | #define TPP_TOK_TILDE TPP(TOK_TILDE)
66 | #define TPP_TOK_AT TPP(TOK_AT)
67 | #define TPP_TOK_BIN_AND TPP(TOK_AND)
68 | #define TPP_TOK_BIN_OR TPP(TOK_OR)
69 | #define TPP_TOK_BIN_XOR TPP(TOK_XOR)
70 | #define TPP_TOK_EXCLAIM TPP(TOK_NOT)
71 | #define TPP_TOK_CMP_LE TPP(TOK_LOWER_EQUAL)
72 | #define TPP_TOK_CMP_EQ TPP(TOK_EQUAL)
73 | #define TPP_TOK_CMP_NE TPP(TOK_NOT_EQUAL)
74 | #define TPP_TOK_CMP_GE TPP(TOK_GREATER_EQUAL)
75 | #define TPP_TOK_ADD_ASSIGN TPP(TOK_ADD_EQUAL)
76 | #define TPP_TOK_SUB_ASSIGN TPP(TOK_SUB_EQUAL)
77 | #define TPP_TOK_MUL_ASSIGN TPP(TOK_MUL_EQUAL)
78 | #define TPP_TOK_DIV_ASSIGN TPP(TOK_DIV_EQUAL)
79 | #define TPP_TOK_MOD_ASSIGN TPP(TOK_MOD_EQUAL)
80 | #define TPP_TOK_SHL TPP(TOK_SHL)
81 | #define TPP_TOK_SHR TPP(TOK_SHR)
82 | #define TPP_TOK_SHL_ASSIGN TPP(TOK_SHL_EQUAL)
83 | #define TPP_TOK_SHR_ASSIGN TPP(TOK_SHR_EQUAL)
84 | #define TPP_TOK_DOTS TPP(TOK_DOTS)
85 | #define TPP_TOK_GLUE TPP(TOK_GLUE)
86 | #define TPP_TOK_BIN_AND_ASSIGN TPP(TOK_AND_EQUAL)
87 | #define TPP_TOK_BIN_OR_ASSIGN TPP(TOK_OR_EQUAL)
88 | #define TPP_TOK_BIN_XOR_ASSIGN TPP(TOK_XOR_EQUAL)
89 | #define TPP_TOK_LAND TPP(TOK_LAND)
90 | #define TPP_TOK_LOR TPP(TOK_LOR)
91 | #define TPP_TOK_INC TPP(TOK_INC)
92 | #define TPP_TOK_DEC TPP(TOK_DEC)
93 | #define TPP_TOK_POW TPP(TOK_POW)
94 | #define TPP_TOK_POW_ASSIGN TPP(TOK_POW_EQUAL)
95 | #define TPP_TOK_LXOR TPP(TOK_LXOR)
96 | #define TPP_TOK_TILDE_TILDE TPP(TOK_TILDE_TILDE)
97 | #define TPP_TOK_ARROW TPP(TOK_ARROW)
98 | #define TPP_TOK_COLLON_ASSIGN TPP(TOK_COLON_EQUAL)
99 | #define TPP_TOK_COLLON_COLLON TPP(TOK_COLON_COLON)
100 | #define TPP_TOK_IDENT_START TPP(TOK_KEYWORD_BEGIN)
101 |
102 | typedef TPP(tok_t) TPPTokenID;
103 | #define TPPTokenID_IS_KEYWORD TPP_ISKEYWORD
104 | #define TPPTokenID_IS_USER_KEYWORD TPP_ISUSERKEYWORD
105 | #define TPPTokenID_IS_INT(id) ((id) == TPP_TOK_INT || (id) == TPP_TOK_CHR)
106 |
107 | typedef TPP(tint_t) TPPInteger;
108 | typedef TPP(tint_t) TPPUInteger;
109 | typedef TPP(tint_t) TPPCounter;
110 | typedef size_t TPPKeywordHash;
111 |
112 | #define TPPMacroCallingConvention_PAREN 0
113 | #define TPPMacroCallingConvention_BRACKET 1
114 | #define TPPMacroCallingConvention_BRACE 2
115 | #define TPPMacroCallingConvention_ANGLE 3
116 |
117 | #define TPPKeywordFlag_NONE 0x00
118 | #define TPPKeywordFlag_HAS_ATTRIBUTE 0x01
119 | #define TPPKeywordFlag_HAS_BUILTIN 0x02
120 | #define TPPKeywordFlag_HAS_CPP_ATTRIBUTE 0x04
121 | #define TPPKeywordFlag_HAS_DECLSPEC_ATTRIBUTE 0x08
122 | #define TPPKeywordFlag_HAS_EXTENSION 0x10
123 | #define TPPKeywordFlag_HAS_FEATURE 0x20
124 | #define TPPKeywordFlag_IS_DEPRECATED 0x40
125 |
126 | # define TPPLexer_FLAG_NONE TPPLEXER_FLAG_NONE
127 | # define TPPLexer_FLAG_WANT_LF TPPLEXER_FLAG_WANTLF
128 | # define TPPLexer_FLAG_WANT_SPC TPPLEXER_FLAG_WANTSPACE
129 | # define TPPLexer_FLAG_NO_MACROS TPPLEXER_FLAG_NO_MACROS
130 | # define TPPLexer_FLAG_NO_DIRECTIVES TPPLEXER_FLAG_NO_DIRECTIVES
131 | # define TPPLexer_FLAG_ASM_COMMENTS TPPLEXER_FLAG_ASM_COMMENTS
132 | # define TPPLexer_FLAG_ONE_FILE TPPLEXER_FLAG_NO_POP_ON_EOF
133 | //#define TPPLexer_FLAG_ONE_REAL_FILE TPPLEXER_FLAG_NO_POP_ON_EOF
134 | # define TPPLexer_FLAG_INC_STRING TPPLEXER_FLAG_INCLUDESTRING
135 | # define TPPLexer_FLAG_RAND_INIT TPPLEXER_FLAG_RANDOM_INITIALIZED
136 | # define TPPLexer_FLAG_NO_DEPRECATED TPPLEXER_FLAG_NO_DEPRECATED
137 | # define TPPLexer_FLAG_TOK_COMMENTS TPPLEXER_FLAG_WANTCOMMENTS
138 |
139 |
140 |
141 | # define f_refcnt f_refcnt
142 | # define f_prev f_prev
143 | # define f_name f_name
144 | # define f_new_name f_textfile.f_usedname->s_text
145 | # define f_ref_file f_macro.m_deffile
146 | //#define f_ref_file_off f_macro.m_defline
147 | # define f_line_offset f_textfile.f_lineoff
148 | # define f_iter f_pos
149 | # define f_end f_end
150 | # define f_data f_text->s_text
151 | typedef struct TPPFile TPPFileObject;
152 |
153 | # define tk_id t_id
154 | # define tk_file t_file
155 | //#define tk_file_off ...
156 | # define tk_str_file t_file
157 | # define tk_str_begin t_begin
158 | # define tk_str_end t_end
159 | typedef struct TPPToken TPPTokenObject;
160 |
161 | # define he_next k_next
162 | # define he_id k_id
163 | # define he_flags k_rare->kr_flags
164 | # define he_counter k_rare->kr_counter
165 | # define he_raw_hash k_hash
166 | # define he_str_len k_size
167 | # define he_str k_name
168 | typedef struct TPPKeyword TPPKeywordListHashEntryObject;
169 |
170 | //#define kl_next km_entryc
171 | # define kl_hash_alloc km_bucketc
172 | # define kl_hash km_bucketv
173 | typedef struct TPPKeywordMap TPPKeywordListObject;
174 |
175 | # define a_name ai_id
176 | # define a_references ai_ins_exp
177 | # define a_quote_references ai_ins_str
178 | #define TPPMacroArgument TPP(arginfo_t)
179 |
180 |
181 | //typedef ... TPPMacroObject; /* Replaced by `TPPFile'. */
182 | //typedef ... TPPMacroListObject; /* Merged with `TPPKeywordMap'. */
183 |
184 |
185 | # define il_size il_pathc
186 | //#define il_paths il_pathv
187 | typedef struct TPPIncludeList TPPIncludeListObject;
188 |
189 |
190 | # define e_value iss_mode
191 | //#define e_token ...
192 | typedef struct TPPIfdefStackSlot TPPIfdefStackEntryObject;
193 |
194 | #define s_size is_slotc
195 | #define s_alloc is_slota
196 | #define s_stack is_slotv
197 | typedef struct TPPIfdefStack TPPIfdefStackObject;
198 |
199 | //typedef ... TPPIncludeCacheEntry; /* Merged with `TPPKeyword'. */
200 | //typedef ... TPPIncludeCacheObject; /* Merged with `TPPKeywordMap'. */
201 |
202 | #define wc_prev ws_prev
203 | #define wc_warnings ws_state
204 | typedef struct TPPWarningState TPPWarningsFrameObject;
205 |
206 | #define w_top w_curstate
207 | typedef struct TPPWarnings TPPWarningsObject;
208 |
209 |
210 | # define l_files l_token.t_file
211 | # define l_keywords l_keywords
212 | # define l_flags l_flags
213 | # define l_macros l_keywords
214 | //#define l_include_list ...
215 | # define l_sys_include_list l_syspaths
216 | # define l_ifdef_stack l_ifdef
217 | # define l_include_cache l_keywords
218 | //#define l_one_file_rec ...
219 | # define l_warnings l_warnings
220 | # define l_counter l_counter
221 | typedef struct TPPLexer TPPLexerObject;
222 |
223 | #define TPPLexer_FastDefine(self, name, code) \
224 | (assert(TPPLexer_Current == (self)), \
225 | TPPLexer_Define(name, strlen(name), code, strlen(code)) \
226 | ? 0 \
227 | : -1)
228 |
229 | #ifdef __cplusplus
230 | }
231 | #endif /* __cplusplus */
232 |
233 | #endif /* !GUARD_TPP_BACKWARDS_COMPATIBILITY_H */
234 |
--------------------------------------------------------------------------------
/src/tpp-gcc-defs.inl:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2025 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2025 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 |
21 | #define TPP_PRIVATE_PP_CAT2(a, b) a##b
22 | #define TPP_PRIVATE_PP_CAT3(a, b, c) a##b##c
23 | #define TPP_PP_CAT2(a, b) TPP_PRIVATE_PP_CAT2(a, b)
24 | #define TPP_PP_CAT3(a, b, c) TPP_PRIVATE_PP_CAT3(a, b, c)
25 |
26 | /* CPU-specific predefined macros. */
27 | #if defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA)
28 | PREDEFINED_MACRO_IF(__alpha__, HAS(EXT_CPU_MACROS), "1")
29 | #endif
30 |
31 | #if defined(__amd64__) || defined(__amd64) || \
32 | defined(__x86_64__) || defined(__x86_64) || \
33 | defined(_M_X64) || defined(_M_AMD64)
34 | PREDEFINED_MACRO_IF(__x86_64__, HAS(EXT_CPU_MACROS), "1")
35 | #endif
36 |
37 | #if defined(__TARGET_ARCH_ARM)
38 | #define TPP_ARM_VERSION __TARGET_ARCH_ARM
39 | #elif defined(_M_ARM)
40 | #define TPP_ARM_VERSION _M_ARM
41 | #elif defined(__ARM_ARCH_8__)
42 | #define TPP_ARM_VERSION 8
43 | #elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
44 | defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || \
45 | defined(__ARM_ARCH_7S__)
46 | #define TPP_ARM_VERSION 7
47 | #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
48 | defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \
49 | defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
50 | #define TPP_ARM_VERSION 6
51 | #elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__) || \
52 | defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) || \
53 | defined(__ARM_ARCH_5TEJ__)
54 | #define TPP_ARM_VERSION 5
55 | #elif defined(__ARM_ARCH_4T__) || defined(__TARGET_ARM_4T)
56 | #define TPP_ARM_VERSION 4
57 | #elif defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__)
58 | #define TPP_ARM_VERSION 3
59 | #elif defined(__ARM_ARCH_2__)
60 | #define TPP_ARM_VERSION 2
61 | #elif defined(__arm__) || defined(__arm) || defined(_ARM) || defined(__ARM_ARCH_1__)
62 | #define TPP_ARM_VERSION 1
63 | #endif
64 | #ifdef TPP_ARM_VERSION
65 | PREDEFINED_MACRO_IF(__arm__, HAS(EXT_CPU_MACROS), TPP_PP_STR(TPP_ARM_VERSION))
66 | #if TPP_ARM_VERSION == 8
67 | PREDEFINED_MACRO_IF(__ARM_ARCH_8__, HAS(EXT_CPU_MACROS), "1")
68 | #elif TPP_ARM_VERSION == 7
69 | PREDEFINED_MACRO_IF(__ARM_ARCH_7__, HAS(EXT_CPU_MACROS), "1")
70 | #elif TPP_ARM_VERSION == 6
71 | #ifdef __ARM_ARCH_6T2__
72 | PREDEFINED_MACRO_IF(__ARM_ARCH_6T2__, HAS(EXT_CPU_MACROS), "1")
73 | #else
74 | PREDEFINED_MACRO_IF(__ARM_ARCH_6__, HAS(EXT_CPU_MACROS), "1")
75 | #endif
76 | #elif TPP_ARM_VERSION == 5
77 | #if defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)
78 | PREDEFINED_MACRO_IF(__ARM_ARCH_5T__, HAS(EXT_CPU_MACROS), "1")
79 | #else
80 | PREDEFINED_MACRO_IF(__ARM_ARCH_5__, HAS(EXT_CPU_MACROS), "1")
81 | #endif
82 | #elif TPP_ARM_VERSION == 4
83 | PREDEFINED_MACRO_IF(__ARM_ARCH_4T__, HAS(EXT_CPU_MACROS), "1")
84 | #elif TPP_ARM_VERSION == 3
85 | PREDEFINED_MACRO_IF(__ARM_ARCH_3__, HAS(EXT_CPU_MACROS), "1")
86 | #elif TPP_ARM_VERSION == 2
87 | PREDEFINED_MACRO_IF(__ARM_ARCH_2__, HAS(EXT_CPU_MACROS), "1")
88 | #else
89 | PREDEFINED_MACRO_IF(__ARM_ARCH_1__, HAS(EXT_CPU_MACROS), "1")
90 | #endif
91 | #if defined(__TARGET_ARCH_THUMB)
92 | PREDEFINED_MACRO_IF(__thumb__, HAS(EXT_CPU_MACROS), TPP_PP_STR(__TARGET_ARCH_THUMB))
93 | #elif defined(_M_ARMT)
94 | PREDEFINED_MACRO_IF(__thumb__, HAS(EXT_CPU_MACROS), TPP_PP_STR(_M_ARM))
95 | #elif defined(__thumb__)
96 | PREDEFINED_MACRO_IF(__thumb__, HAS(EXT_CPU_MACROS), TPP_PP_STR(TPP_ARM_VERSION))
97 | #endif
98 | #undef TPP_ARM_VERSION
99 | #endif
100 |
101 | #ifdef __aarch64__
102 | PREDEFINED_MACRO_IF(__aarch64__, HAS(EXT_CPU_MACROS), "1")
103 | #endif /* __aarch64__ */
104 |
105 | #if defined(__bfin) || defined(__BFIN__)
106 | PREDEFINED_MACRO_IF(__bfin, HAS(EXT_CPU_MACROS), "1")
107 | #endif /* __bfin || __BFIN__ */
108 |
109 | #ifdef __C67__
110 | PREDEFINED_MACRO_IF(__C67__, HAS(EXT_CPU_MACROS), "1")
111 | #endif /* __C67__ */
112 |
113 | #ifdef __convex__
114 | PREDEFINED_MACRO_IF(__convex__, HAS(EXT_CPU_MACROS), "1")
115 | #ifdef __convex_c1__
116 | PREDEFINED_MACRO_IF(__convex_c1__, HAS(EXT_CPU_MACROS), "1")
117 | #endif /* __convex_c1__ */
118 | #ifdef __convex_c2__
119 | PREDEFINED_MACRO_IF(__convex_c2__, HAS(EXT_CPU_MACROS), "1")
120 | #endif /* __convex_c2__ */
121 | #ifdef __convex_c32__
122 | PREDEFINED_MACRO_IF(__convex_c32__, HAS(EXT_CPU_MACROS), "1")
123 | #endif /* __convex_c32__ */
124 | #ifdef __convex_c34__
125 | PREDEFINED_MACRO_IF(__convex_c34__, HAS(EXT_CPU_MACROS), "1")
126 | #endif /* __convex_c34__ */
127 | #ifdef __convex_c38__
128 | PREDEFINED_MACRO_IF(__convex_c38__, HAS(EXT_CPU_MACROS), "1")
129 | #endif /* __convex_c38__ */
130 | #endif /* __convex__ */
131 |
132 | #ifdef __epiphany__
133 | PREDEFINED_MACRO_IF(__epiphany__, HAS(EXT_CPU_MACROS), "1")
134 | #endif /* __epiphany__ */
135 |
136 | #if defined(__hppa__) || defined(__HPPA__) || defined(__hppa)
137 | PREDEFINED_MACRO_IF(__hppa__, HAS(EXT_CPU_MACROS), "1")
138 | #endif /* __hppa__ || __HPPA__ || __hppa */
139 |
140 | #if defined(__I86__)
141 | #define TPP_I386_VERSION (__I86__ * 100)
142 | #elif defined(_M_IX86)
143 | #define TPP_I386_VERSION _M_IX86
144 | #elif defined(__i686__) || defined(__i686) || defined(i686)
145 | #define TPP_I386_VERSION 600
146 | #elif defined(__i586__) || defined(__i586) || defined(i586)
147 | #define TPP_I386_VERSION 500
148 | #elif defined(__i486__) || defined(__i486) || defined(i486)
149 | #define TPP_I386_VERSION 400
150 | #elif defined(__i386__) || defined(__i386) || defined(i386) || \
151 | defined(__X86__) || defined(_X86_) || \
152 | defined(__THW_INTEL__) || defined(__INTEL__)
153 | #define TPP_I386_VERSION 300
154 | #endif
155 | #ifdef TPP_I386_VERSION
156 | #if TPP_I386_VERSION >= 600
157 | PREDEFINED_MACRO_IF(__i686__, HAS(EXT_CPU_MACROS), "1")
158 | #endif
159 | #if TPP_I386_VERSION >= 500
160 | PREDEFINED_MACRO_IF(__i586__, HAS(EXT_CPU_MACROS), "1")
161 | #endif
162 | #if TPP_I386_VERSION >= 400
163 | PREDEFINED_MACRO_IF(__i486__, HAS(EXT_CPU_MACROS), "1")
164 | #endif
165 | #if TPP_I386_VERSION >= 300
166 | PREDEFINED_MACRO_IF(__i386__, HAS(EXT_CPU_MACROS), "1")
167 | #endif
168 | #undef TPP_I386_VERSION
169 | #endif /* TPP_I386_VERSION */
170 |
171 | #if defined(__ia64__) || defined(_IA64) || defined(__IA64__) || \
172 | defined(__ia64) || defined(_M_IA64) || defined(__itanium__)
173 | PREDEFINED_MACRO_IF(__ia64__, HAS(EXT_CPU_MACROS), "1")
174 | #endif /* __ia64__ || _IA64 || __IA64__ || __ia64 || _M_IA64 || __itanium__ */
175 |
176 | #if defined(__mc68060__) || defined(__mc68060) || defined(mc68060)
177 | #define TPP_M64K_VERSION 68060
178 | #elif defined(__mc68040__) || defined(__mc68040) || defined(mc68040)
179 | #define TPP_M64K_VERSION 68040
180 | #elif defined(__mc68030__) || defined(__mc68030) || defined(mc68030)
181 | #define TPP_M64K_VERSION 68030
182 | #elif defined(__mc68020__) || defined(__mc68020) || defined(mc68020)
183 | #define TPP_M64K_VERSION 68020
184 | #elif defined(__mc68010__) || defined(__mc68010) || defined(mc68010)
185 | #define TPP_M64K_VERSION 68010
186 | #elif defined(__mc68000__) || defined(__mc68000) || defined(mc68000) || \
187 | defined(__MC68000__) || defined(M68000) || defined(__MC68K__)
188 | #define TPP_M64K_VERSION 68000
189 | #endif
190 | #ifdef TPP_M64K_VERSION
191 | PREDEFINED_MACRO_IF(__m68k__, HAS(EXT_CPU_MACROS), TPP_PP_STR(TPP_M64K_VERSION))
192 | PREDEFINED_KWD_MACRO_IF(TPP_PP_CAT3(KWD___mc, TPP_M64K_VERSION, __),
193 | "__mc" TPP_PP_STR(TPP_M64K_VERSION) "__",
194 | HAS(EXT_CPU_MACROS), "1")
195 | #undef TPP_M64K_VERSION
196 | #endif /* TPP_M64K_VERSION */
197 |
198 | #if defined(__mips)
199 | #define TPP_MIPS_VERSION __mips
200 | #elif defined(__MIPS_ISA4__)
201 | #define TPP_MIPS_VERSION 4
202 | #elif defined(__MIPS_ISA3__)
203 | #define TPP_MIPS_VERSION 3
204 | #elif defined(__MIPS_ISA2__)
205 | #define TPP_MIPS_VERSION 2
206 | #elif defined(_MIPS_ISA)
207 | #if defined(_MIPS_ISA_MIPS4) && _MIPS_ISA == _MIPS_ISA_MIPS4
208 | #define TPP_MIPS_VERSION 4
209 | #elif defined(_MIPS_ISA_MIPS3) && _MIPS_ISA == _MIPS_ISA_MIPS3
210 | #define TPP_MIPS_VERSION 3
211 | #elif defined(_MIPS_ISA_MIPS2) && _MIPS_ISA == _MIPS_ISA_MIPS2
212 | #define TPP_MIPS_VERSION 2
213 | #else
214 | #define TPP_MIPS_VERSION 1
215 | #endif
216 | #elif defined(__mips__)
217 | #define TPP_MIPS_VERSION __mips__
218 | #elif defined(__MIPS__)
219 | #define TPP_MIPS_VERSION 1
220 | #endif
221 |
222 | #ifdef TPP_MIPS_VERSION
223 | PREDEFINED_MACRO_IF(__mips__, HAS(EXT_CPU_MACROS), TPP_PP_STR(TPP_MIPS_VERSION))
224 | PREDEFINED_MACRO_IF(__mips, HAS(EXT_CPU_MACROS), TPP_PP_STR(TPP_MIPS_VERSION))
225 | #undef TPP_MIPS_VERSION
226 | #endif /* TPP_MIPS_VERSION */
227 |
228 | #ifdef _M_PPC
229 | #define TPP_POWERPC_VERSION _M_PPC
230 | #elif defined(__ppc604__)
231 | #define TPP_POWERPC_VERSION 604
232 | #elif defined(__ppc603__)
233 | #define TPP_POWERPC_VERSION 603
234 | #elif defined(__ppc601__)
235 | #define TPP_POWERPC_VERSION 601
236 | #elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) || \
237 | defined(__POWERPC__) || defined(__ppc__) || defined(__ppc64__) || \
238 | defined(__PPC__) || defined(__PPC64__) || defined(_ARCH_PPC) || \
239 | defined(_ARCH_PPC64) || defined(__PPCGECKO__) || defined(__PPCBROADWAY__) || \
240 | defined(_XENON) || defined(__ppc)
241 | #if defined(_ARCH_620)
242 | #define TPP_POWERPC_VERSION 620
243 | #elif defined(_ARCH_604)
244 | #define TPP_POWERPC_VERSION 604
245 | #elif defined(_ARCH_603)
246 | #define TPP_POWERPC_VERSION 603
247 | #elif defined(_ARCH_601)
248 | #define TPP_POWERPC_VERSION 601
249 | #elif defined(_ARCH_450)
250 | #define TPP_POWERPC_VERSION 450
251 | #else
252 | #define TPP_POWERPC_VERSION 440
253 | #endif
254 | #endif
255 |
256 | #ifdef TPP_POWERPC_VERSION
257 | PREDEFINED_MACRO_IF(__powerpc__, HAS(EXT_CPU_MACROS),
258 | TPP_PP_STR(TPP_POWERPC_VERSION))
259 | PREDEFINED_KWDMACRO_IF(TPP_PP_CAT3(KWD___ppc, TPP_POWERPC_VERSION, __),
260 | "__ppc" TPP_PP_STR(TPP_POWERPC_VERSION) "__",
261 | HAS(EXT_CPU_MACROS), "1")
262 | #undef TPP_POWERPC_VERSION
263 | #endif /* TPP_POWERPC_VERSION */
264 |
265 | #ifdef pyr
266 | PREDEFINED_MACRO_IF(pyr, HAS(EXT_CPU_MACROS), TPP_PP_STR(pyr))
267 | #endif /* pyr */
268 |
269 |
270 | #if defined(__sparc_v9__) || defined(__sparcv9)
271 | #define TPP_SPARC_VERSION 9
272 | #elif defined(__sparc_v8__) || defined(__sparcv8)
273 | #define TPP_SPARC_VERSION 8
274 | #elif defined(__sparc__) || defined(__sparc)
275 | #define TPP_SPARC_VERSION 1
276 | #endif
277 |
278 | #ifdef TPP_SPARC_VERSION
279 | PREDEFINED_MACRO_IF(__sparc__, HAS(EXT_CPU_MACROS), TPP_PP_STR(TPP_SPARC_VERSION))
280 | #if TPP_SPARC_VERSION == 9
281 | PREDEFINED_MACRO_IF(__sparc_v9__, HAS(EXT_CPU_MACROS), "1")
282 | #elif TPP_SPARC_VERSION == 8
283 | PREDEFINED_MACRO_IF(__sparc_v8__, HAS(EXT_CPU_MACROS), "1")
284 | #endif
285 | #undef TPP_SPARC_VERSION
286 | #endif /* TPP_SPARC_VERSION */
287 |
288 | #if defined(__SH5__) || defined(__sh5__)
289 | #define TPP_SUPERH_VERSION 5
290 | #elif defined(__SH4__) || defined(__sh4__)
291 | #define TPP_SUPERH_VERSION 4
292 | #elif defined(__SH3__) || defined(__sh3__)
293 | #define TPP_SUPERH_VERSION 3
294 | #elif defined(__SH2__) || defined(__sh2__)
295 | #define TPP_SUPERH_VERSION 2
296 | #elif defined(__SH1__) || defined(__sh1__) || defined(__sh__)
297 | #define TPP_SUPERH_VERSION 1
298 | #endif
299 |
300 | #ifdef TPP_SUPERH_VERSION
301 | PREDEFINED_MACRO_IF(__sh__, HAS(EXT_CPU_MACROS), TPP_PP_STR(TPP_SUPERH_VERSION))
302 | PREDEFINED_KWDMACRO_IF(TPP_PP_CAT3(KWD___sh, TPP_SUPERH_VERSION, __),
303 | "__sh" TPP_PP_STR(TPP_SUPERH_VERSION) "__",
304 | HAS(EXT_CPU_MACROS), "1")
305 | #undef TPP_SUPERH_VERSION
306 | #endif /* TPP_SUPERH_VERSION */
307 |
308 | #if defined(__s390x__) || defined(__zarch__) || defined(__SYSC_ZARCH__)
309 | PREDEFINED_MACRO_IF(__s390x__, HAS(EXT_CPU_MACROS), "1")
310 | #endif /* __s390x__ || __zarch__ || __SYSC_ZARCH__ */
311 | #if defined(__370__) || defined(__THW_370__) || defined(__s390__)
312 | PREDEFINED_MACRO_IF(__370__, HAS(EXT_CPU_MACROS), "1")
313 | #endif /* __370__ || __THW_370__ || __s390__ */
314 |
315 | /* System-specific predefined macros. */
316 | #ifdef __APPLE__
317 | PREDEFINED_MACRO_IF(__APPLE__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__APPLE__))
318 | #endif /* __APPLE__ */
319 | #ifdef __MACH__
320 | PREDEFINED_MACRO_IF(__MACH__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__MACH__))
321 | #endif /* __MACH__ */
322 | #ifdef __ANDROID__
323 | PREDEFINED_MACRO_IF(__ANDROID__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__ANDROID__))
324 | #elif defined(__ANDROID)
325 | PREDEFINED_MACRO_IF(__ANDROID__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__ANDROID))
326 | #elif defined(__android__)
327 | PREDEFINED_MACRO_IF(__ANDROID__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__android__))
328 | #elif defined(__android)
329 | PREDEFINED_MACRO_IF(__ANDROID__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__android))
330 | #endif
331 | #ifdef __amigaos__
332 | PREDEFINED_MACRO_IF(__amigaos__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__amigaos__))
333 | #elif defined(AMIGA)
334 | PREDEFINED_MACRO_IF(__amigaos__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(AMIGA))
335 | #endif
336 | #if defined(__bg__) || defined(__bgq__) || defined(__THW_BLUEGENE__) || defined(__TOS_BGQ__)
337 | PREDEFINED_MACRO_IF(__bg__, HAS(EXT_SYSTEM_MACROS), "1")
338 | #endif /* __bg__ || __bgq__ || __THW_BLUEGENE__ || __TOS_BGQ__ */
339 | #ifdef __bgq__
340 | PREDEFINED_MACRO_IF(__bgq__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__bgq__))
341 | #elif defined(__TOS_BGQ__)
342 | PREDEFINED_MACRO_IF(__bgq__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__TOS_BGQ__))
343 | #endif
344 | #ifdef __FreeBSD__
345 | PREDEFINED_MACRO_IF(__FreeBSD__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__FreeBSD__))
346 | #endif /* __FreeBSD__ */
347 | #ifdef __NetBSD__
348 | PREDEFINED_MACRO_IF(__NetBSD__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__NetBSD__))
349 | #endif /* __NetBSD__ */
350 | #ifdef __OpenBSD__
351 | PREDEFINED_MACRO_IF(__OpenBSD__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__OpenBSD__))
352 | #endif /* __OpenBSD__ */
353 | #ifdef __bsdi__
354 | PREDEFINED_MACRO_IF(__bsdi__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__bsdi__))
355 | #endif /* __bsdi__ */
356 | #ifdef __CYGWIN__
357 | #define TPP_PLATFORM_NOT_WINDOWS
358 | PREDEFINED_MACRO_IF(__CYGWIN__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__CYGWIN__))
359 | #elif defined(__MINGW32__)
360 | #define TPP_PLATFORM_NOT_WINDOWS
361 | PREDEFINED_MACRO_IF(__MINGW32__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__MINGW32__))
362 | PREDEFINED_MACRO_IF(__CYGWIN__, HAS(EXT_SYSTEM_MACROS), "1") /* Prefer cygwin! */
363 | #endif
364 | #ifdef DGUX
365 | PREDEFINED_MACRO_IF(__dgux__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(DGUX))
366 | #elif defined(__DGUX__)
367 | PREDEFINED_MACRO_IF(__dgux__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__DGUX__))
368 | #elif defined(__dgux__)
369 | PREDEFINED_MACRO_IF(__dgux__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__dgux__))
370 | #endif
371 | #ifdef __DragonFly__
372 | PREDEFINED_MACRO_IF(__DragonFly__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__DragonFly__))
373 | #endif /* __DragonFly__ */
374 | #ifdef __ECOS
375 | PREDEFINED_MACRO_IF(__ECOS, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__ECOS))
376 | #endif /* __ECOS */
377 | #ifdef __EMX__
378 | PREDEFINED_MACRO_IF(__EMX__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__EMX__))
379 | #endif /* __EMX__ */
380 | #ifdef __hiuxmpp
381 | PREDEFINED_MACRO_IF(__hiuxmpp, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__hiuxmpp))
382 | #endif /* __hiuxmpp */
383 | #ifdef _hpux
384 | PREDEFINED_MACRO_IF(__hpux, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(_hpux))
385 | #elif defined(hpux)
386 | PREDEFINED_MACRO_IF(__hpux, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(hpux))
387 | #elif defined(__hpux)
388 | PREDEFINED_MACRO_IF(__hpux, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__hpux))
389 | #endif
390 | #ifdef sgi
391 | PREDEFINED_MACRO_IF(__sgi, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(sgi))
392 | #elif defined(__sgi)
393 | PREDEFINED_MACRO_IF(__sgi, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__sgi))
394 | #endif
395 | #if defined(__linux__) || defined(__linux) || defined(linux)
396 | PREDEFINED_MACRO_IF(__linux__, HAS(EXT_SYSTEM_MACROS), "1")
397 | #endif /* __linux__ || __linux || linux */
398 | #ifdef __Lynx__
399 | PREDEFINED_MACRO_IF(__Lynx__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__Lynx__))
400 | #endif /* __Lynx__ */
401 | #ifdef __OS9000
402 | PREDEFINED_MACRO_IF(__OS9000, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__OS9000))
403 | #elif defined(_OSK)
404 | PREDEFINED_MACRO_IF(__OS9000, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(_OSK))
405 | #endif
406 | #ifdef __minix
407 | PREDEFINED_MACRO_IF(__minix, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__minix))
408 | #endif /* __minix */
409 | #ifdef __MORPHOS__
410 | PREDEFINED_MACRO_IF(__MORPHOS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__MORPHOS__))
411 | #endif /* __MORPHOS__ */
412 | #ifdef __mpeix
413 | PREDEFINED_MACRO_IF(__mpeix, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__mpeix))
414 | #elif defined(mpeix)
415 | PREDEFINED_MACRO_IF(__mpeix, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(mpeix))
416 | #endif
417 | #ifdef __MSDOS__
418 | PREDEFINED_MACRO_IF(__MSDOS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__MSDOS__))
419 | #elif defined(MSDOS)
420 | PREDEFINED_MACRO_IF(__MSDOS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(MSDOS))
421 | #elif defined(_MSDOS)
422 | PREDEFINED_MACRO_IF(__MSDOS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(_MSDOS))
423 | #elif defined(__DOS__)
424 | PREDEFINED_MACRO_IF(__MSDOS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__DOS__))
425 | #endif
426 | #ifdef __TANDEM
427 | PREDEFINED_MACRO_IF(__TANDEM, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__TANDEM))
428 | #endif /* __TANDEM */
429 | #ifdef __MACOS__
430 | PREDEFINED_MACRO_IF(__MACOS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__MACOS__))
431 | #endif /* __MACOS__ */
432 | #ifdef __MACOSX__
433 | PREDEFINED_MACRO_IF(__MACOSX__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__MACOSX__))
434 | #endif /* __MACOSX__ */
435 | #ifdef __nucleus__
436 | PREDEFINED_MACRO_IF(__nucleus__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__nucleus__))
437 | #endif /* __nucleus__ */
438 | #ifdef OS2
439 | PREDEFINED_MACRO_IF(__OS2__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(OS2))
440 | #elif defined(_OS2)
441 | PREDEFINED_MACRO_IF(__OS2__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(_OS2))
442 | #elif defined(__OS2__)
443 | PREDEFINED_MACRO_IF(__OS2__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__OS2__))
444 | #elif defined(__TOS_OS2__)
445 | PREDEFINED_MACRO_IF(__OS2__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__TOS_OS2__))
446 | #endif
447 | #ifdef __palmos__
448 | PREDEFINED_MACRO_IF(__palmos__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__palmos__))
449 | #endif /* __palmos__ */
450 | #ifdef EPLAN9
451 | PREDEFINED_MACRO_IF(EPLAN9, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(EPLAN9))
452 | #endif /* EPLAN9 */
453 | #ifdef __QNX__
454 | PREDEFINED_MACRO_IF(__QNX__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__QNX__))
455 | #endif /* __QNX__ */
456 | #ifdef __QNXNTO__
457 | PREDEFINED_MACRO_IF(__QNXNTO__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__QNXNTO__))
458 | #endif /* __QNXNTO__ */
459 | #ifdef sinux
460 | PREDEFINED_MACRO_IF(sinux, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(sinux))
461 | #endif /* sinux */
462 | #ifdef sun
463 | PREDEFINED_MACRO_IF(__sun, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(sun))
464 | #elif defined(__sun)
465 | PREDEFINED_MACRO_IF(__sun, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__sun))
466 | #endif
467 | #ifdef __VOS__
468 | PREDEFINED_MACRO_IF(__VOS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__VOS__))
469 | #endif /* __VOS__ */
470 | #if defined(__sysv__) || defined(__SVR4) || \
471 | defined(__svr4__) || defined(_SYSTYPE_SVR4)
472 | PREDEFINED_MACRO_IF(__sysv__, HAS(EXT_SYSTEM_MACROS), "1")
473 | PREDEFINED_MACRO_IF(__svr4__, HAS(EXT_SYSTEM_MACROS), "1")
474 | #endif
475 | #ifdef __SYLLABLE__
476 | PREDEFINED_MACRO_IF(__SYLLABLE__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__SYLLABLE__))
477 | #endif /* __SYLLABLE__ */
478 | #ifdef __SYMBIAN32__
479 | PREDEFINED_MACRO_IF(__SYMBIAN32__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__SYMBIAN32__))
480 | #endif /* __SYMBIAN32__ */
481 | #ifdef __osf__
482 | PREDEFINED_MACRO_IF(__osf__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__osf__))
483 | #elif defined(__osf)
484 | PREDEFINED_MACRO_IF(__osf__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__osf))
485 | #endif
486 | #ifdef __ultrix__
487 | PREDEFINED_MACRO_IF(__ultrix__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__ultrix__))
488 | #elif defined(__ultrix)
489 | PREDEFINED_MACRO_IF(__ultrix__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__ultrix))
490 | #elif defined(ultrix)
491 | PREDEFINED_MACRO_IF(__ultrix__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(ultrix))
492 | #elif (defined(__unix__) || defined(__unix) || defined(unix)) && \
493 | (defined(__vax__) || defined(__vax) || defined(vax))
494 | PREDEFINED_MACRO_IF(__ultrix__, HAS(EXT_SYSTEM_MACROS), "1")
495 | #endif
496 | #ifdef _UNICOS
497 | PREDEFINED_MACRO_IF(_UNICOS, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(_UNICOS))
498 | #endif /* _UNICOS */
499 | #ifdef __crayx1
500 | PREDEFINED_MACRO_IF(__crayx1, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__crayx1))
501 | #elif defined(_CRAY)
502 | PREDEFINED_MACRO_IF(__crayx1, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(_CRAY))
503 | #endif
504 | #if defined(__unix__)
505 | PREDEFINED_MACRO_IF(__unix__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__unix__))
506 | #elif defined(__unix)
507 | PREDEFINED_MACRO_IF(__unix__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__unix))
508 | #elif defined(unix)
509 | PREDEFINED_MACRO_IF(__unix__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(unix))
510 | #elif defined(__ANDROID__) || defined(__ANDROID) || \
511 | defined(__android__) || defined(__android) || \
512 | defined(__linux__) || defined(__linux) || defined(linux) || \
513 | defined(__MACOS__) || defined(__MACOSX__) || defined(__POSIX__)
514 | PREDEFINED_MACRO_IF(__unix__, HAS(EXT_SYSTEM_MACROS), "1")
515 | #endif
516 | #ifdef __VMS
517 | PREDEFINED_MACRO_IF(__VMS, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__VMS))
518 | #elif defined(VMS)
519 | PREDEFINED_MACRO_IF(__VMS, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(VMS))
520 | #endif
521 | #ifdef __VMS_VER
522 | PREDEFINED_MACRO_IF(__VMS_VER, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__VMS_VER))
523 | #endif /* __VMS_VER */
524 | #ifdef __vxworks
525 | PREDEFINED_MACRO_IF(__vxworks, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__vxworks))
526 | #elif defined(__VXWORKS__)
527 | PREDEFINED_MACRO_IF(__vxworks, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__VXWORKS__))
528 | #endif
529 | #ifndef TPP_PLATFORM_NOT_WINDOWS
530 | #ifdef __WINDOWS__
531 | #define TPP_PLATFORM_WINDOWS
532 | PREDEFINED_MACRO_IF(__WINDOWS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__WINDOWS__))
533 | #elif defined(_WIN16) || defined(WIN16) || \
534 | defined(_WIN32) || defined(WIN32) || \
535 | defined(_WIN64) || defined(WIN64) || \
536 | defined(__WIN32__) || defined(__TOS_WIN__)
537 | #define TPP_PLATFORM_WINDOWS
538 | PREDEFINED_MACRO_IF(__WINDOWS__, HAS(EXT_SYSTEM_MACROS), "1")
539 | #elif defined(_WIN32_WCE) || defined(WIN32_WCE)
540 | PREDEFINED_MACRO_IF(__WINDOWS__, HAS(EXT_SYSTEM_MACROS), "1")
541 | #endif
542 | #ifdef _WIN32
543 | PREDEFINED_MACRO_IF(_WIN32, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(_WIN32))
544 | #elif defined(WIN32)
545 | PREDEFINED_MACRO_IF(_WIN32, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(WIN32))
546 | #elif defined(__WIN32__)
547 | PREDEFINED_MACRO_IF(_WIN32, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__WIN32__))
548 | #elif defined(TPP_PLATFORM_WINDOWS) && __SIZEOF_POINTER__ >= 4
549 | PREDEFINED_MACRO_IF(_WIN32, HAS(EXT_SYSTEM_MACROS), "1")
550 | #endif
551 | #ifdef _WIN64
552 | PREDEFINED_MACRO_IF(_WIN64, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(_WIN64))
553 | #elif defined(WIN64)
554 | PREDEFINED_MACRO_IF(_WIN64, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(WIN64))
555 | #elif defined(TPP_PLATFORM_WINDOWS) && __SIZEOF_POINTER__ == 8
556 | PREDEFINED_MACRO_IF(_WIN64, HAS(EXT_SYSTEM_MACROS), "1")
557 | #endif
558 | #ifdef _WIN16
559 | PREDEFINED_MACRO_IF(_WIN16, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(_WIN16))
560 | #elif defined(WIN16)
561 | PREDEFINED_MACRO_IF(_WIN16, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(WIN16))
562 | #elif defined(TPP_PLATFORM_WINDOWS) && __SIZEOF_POINTER__ == 2
563 | PREDEFINED_MACRO_IF(_WIN16, HAS(EXT_SYSTEM_MACROS), "1")
564 | #endif
565 | #ifdef _WIN32_WCE
566 | PREDEFINED_MACRO_IF(_WIN32_WCE, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(_WIN32_WCE))
567 | #elif defined(WIN32_WCE)
568 | PREDEFINED_MACRO_IF(_WIN32_WCE, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(WIN32_WCE))
569 | #endif
570 | #ifdef TPP_PLATFORM_WINDOWS
571 | #undef TPP_PLATFORM_WINDOWS
572 | #endif /* TPP_PLATFORM_WINDOWS */
573 | #endif /* !TPP_PLATFORM_NOT_WINDOWS */
574 | #ifdef __MVS__
575 | PREDEFINED_MACRO_IF(__MVS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__MVS__))
576 | #ifdef __HOS_MVS__
577 | PREDEFINED_MACRO_IF(__HOS_MVS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__HOS_MVS__))
578 | #else
579 | PREDEFINED_MACRO_IF(__HOS_MVS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__MVS__))
580 | #endif
581 | #elif defined(__HOS_MVS__)
582 | PREDEFINED_MACRO_IF(__MVS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__HOS_MVS__))
583 | PREDEFINED_MACRO_IF(__HOS_MVS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__HOS_MVS__))
584 | #endif
585 | #ifdef __TOS_MVS__
586 | PREDEFINED_MACRO_IF(__TOS_MVS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__TOS_MVS__))
587 | #endif /* __TOS_MVS__ */
588 | #ifdef __KOS__ /* ~smirks~ */
589 | PREDEFINED_MACRO_IF(__KOS__, HAS(EXT_SYSTEM_MACROS), TPP_PP_STR(__KOS__))
590 | #endif /* __KOS__ */
591 |
592 |
593 | /* Utility predefined macros. */
594 | #ifndef TPP_UTILITY_MACROS_DEFINED
595 | #define TPP_UTILITY_MACROS_DEFINED
596 | #ifndef TPP_MSCV_OR_GCC
597 | #ifdef _MSC_VER
598 | #define TPP_MSCV_OR_GCC(msvc, gcc) msvc
599 | #else /* _MSC_VER */
600 | #define TPP_MSCV_OR_GCC(msvc, gcc) gcc
601 | #endif /* !_MSC_VER */
602 | #endif /* !TPP_MSCV_OR_GCC */
603 | #ifndef __INT8_TYPE__
604 | #define __INT8_TYPE__ TPP_MSCV_OR_GCC(__int8, signed char)
605 | #endif /* !__INT8_TYPE__ */
606 | #ifndef __UINT8_TYPE__
607 | #define __UINT8_TYPE__ unsigned TPP_MSCV_OR_GCC(__int8, char)
608 | #endif /* !__UINT8_TYPE__ */
609 | #ifndef __INT16_TYPE__
610 | #define __INT16_TYPE__ TPP_MSCV_OR_GCC(__int16, short)
611 | #endif /* !__INT16_TYPE__ */
612 | #ifndef __UINT16_TYPE__
613 | #define __UINT16_TYPE__ unsigned TPP_MSCV_OR_GCC(__int16, short)
614 | #endif /* !__UINT16_TYPE__ */
615 | #ifndef __INT32_TYPE__
616 | #define __INT32_TYPE__ TPP_MSCV_OR_GCC(__int32, int)
617 | #endif /* !__INT32_TYPE__ */
618 | #ifndef __UINT32_TYPE__
619 | #define __UINT32_TYPE__ unsigned TPP_MSCV_OR_GCC(__int32, int)
620 | #endif /* !__UINT32_TYPE__ */
621 | #ifndef __INT64_TYPE__
622 | #define __INT64_TYPE__ TPP_MSCV_OR_GCC(__int64, long long)
623 | #endif /* !__INT64_TYPE__ */
624 | #ifndef __UINT64_TYPE__
625 | #define __UINT64_TYPE__ unsigned TPP_MSCV_OR_GCC(__int64, long long)
626 | #endif /* !__UINT64_TYPE__ */
627 | #define TPP_MUL8_1 8
628 | #define TPP_MUL8_2 16
629 | #define TPP_MUL8_4 32
630 | #define TPP_MUL8_8 64
631 | #define TPP_MUL8_16 128
632 | #define TPP_MUL8(x) TPP_PRIVATE_PP_CAT2(TPP_MUL8_, x)
633 | #define TPP_INTTYPE_1 __INT8_TYPE__
634 | #define TPP_INTTYPE_2 __INT16_TYPE__
635 | #define TPP_INTTYPE_4 __INT32_TYPE__
636 | #define TPP_INTTYPE_8 __INT64_TYPE__
637 | #define TPP_UINTTYPE_1 __UINT8_TYPE__
638 | #define TPP_UINTTYPE_2 __UINT16_TYPE__
639 | #define TPP_UINTTYPE_4 __UINT32_TYPE__
640 | #define TPP_UINTTYPE_8 __UINT64_TYPE__
641 | #define TPP_INTTYPE(n) TPP_PRIVATE_PP_CAT2(TPP_INTTYPE_, n)
642 | #define TPP_UINTTYPE(n) TPP_PRIVATE_PP_CAT2(TPP_UINTTYPE_, n)
643 | #ifndef __SIZEOF_INT__
644 | #define __SIZEOF_INT__ 4
645 | #endif /* !__SIZEOF_INT__ */
646 | #ifndef __SIZEOF_LONG__
647 | #if defined(_WIN16) || defined(WIN16) || \
648 | defined(_WIN32) || defined(WIN32) || \
649 | defined(_WIN64) || defined(WIN64)
650 | #define __SIZEOF_LONG__ 4
651 | #else
652 | #define __SIZEOF_LONG__ __SIZEOF_POINTER__
653 | #endif
654 | #endif
655 | #ifndef __SIZEOF_LONG_LONG__
656 | #define __SIZEOF_LONG_LONG__ 8
657 | #endif /* __SIZEOF_LONG_LONG__ */
658 | #ifndef __SIZEOF_SHORT__
659 | #define __SIZEOF_SHORT__ 2
660 | #endif /* __SIZEOF_SHORT__ */
661 | #ifndef __SIZEOF_FLOAT__
662 | #define __SIZEOF_FLOAT__ 4
663 | #endif /* __SIZEOF_FLOAT__ */
664 | #ifndef __SIZEOF_DOUBLE__
665 | #define __SIZEOF_DOUBLE__ 8
666 | #endif /* __SIZEOF_DOUBLE__ */
667 | #ifndef __SIZEOF_LONG_DOUBLE__
668 | #ifdef _MSC_VER
669 | #define __SIZEOF_LONG_DOUBLE__ 8
670 | #elif defined(__C67__) || defined(__i386__) || \
671 | defined(__i386) || defined(i386)
672 | #define __SIZEOF_LONG_DOUBLE__ 12
673 | #elif defined(__X86_64__)
674 | #define __SIZEOF_LONG_DOUBLE__ 16
675 | #else
676 | #define __SIZEOF_LONG_DOUBLE__ 8
677 | #endif
678 | #endif /* !__SIZEOF_LONG_DOUBLE__ */
679 | #ifndef __SIZEOF_SIZE_T__
680 | #define __SIZEOF_SIZE_T__ __SIZEOF_POINTER__
681 | #endif /* !__SIZEOF_SIZE_T__ */
682 | #ifndef __SIZEOF_WCHAR_T__
683 | #if defined(_WIN16) || defined(WIN16) || \
684 | defined(_WIN32) || defined(WIN32) || \
685 | defined(_WIN64) || defined(WIN64)
686 | #define __SIZEOF_WCHAR_T__ 2
687 | #else
688 | #define __SIZEOF_WCHAR_T__ 4
689 | #endif
690 | #endif /* !__SIZEOF_WCHAR_T__ */
691 | #ifndef __SIZEOF_WINT_T__
692 | #define __SIZEOF_WINT_T__ __SIZEOF_INT__
693 | #endif /* !__SIZEOF_WINT_T__ */
694 | #ifndef __SIZEOF_PTRDIFF_T__
695 | #define __SIZEOF_PTRDIFF_T__ __SIZEOF_POINTER__
696 | #endif /* !__SIZEOF_PTRDIFF_T__ */
697 | #ifndef __SCHAR_WIDTH__
698 | #define __SCHAR_WIDTH__ 8
699 | #endif /* !__SCHAR_WIDTH__ */
700 | #ifndef __SHRT_WIDTH__
701 | #define __SHRT_WIDTH__ TPP_MUL8(__SIZEOF_SHORT__)
702 | #endif /* !__SHRT_WIDTH__ */
703 | #ifndef __INT_WIDTH__
704 | #define __INT_WIDTH__ TPP_MUL8(__SIZEOF_INT__)
705 | #endif /* !__INT_WIDTH__ */
706 | #ifndef __LONG_WIDTH__
707 | #define __LONG_WIDTH__ TPP_MUL8(__SIZEOF_LONG__)
708 | #endif /* !__LONG_WIDTH__ */
709 | #ifndef __LONG_LONG_WIDTH__
710 | #define __LONG_LONG_WIDTH__ TPP_MUL8(__SIZEOF_LONG_LONG__)
711 | #endif /* !__LONG_LONG_WIDTH__ */
712 | #ifndef __PTRDIFF_WIDTH__
713 | #define __PTRDIFF_WIDTH__ TPP_MUL8(__SIZEOF_PTRDIFF_T__)
714 | #endif /* !__PTRDIFF_WIDTH__ */
715 | #ifndef __SIG_ATOMIC_WIDTH__
716 | #define __SIG_ATOMIC_WIDTH__ TPP_MUL8(__SIZEOF_INT__)
717 | #endif /* !__SIG_ATOMIC_WIDTH__ */
718 | #ifndef __SIZE_WIDTH__
719 | #define __SIZE_WIDTH__ TPP_MUL8(__SIZEOF_SIZE_T__)
720 | #endif /* !__SIZE_WIDTH__ */
721 | #ifndef __WCHAR_WIDTH__
722 | #define __WCHAR_WIDTH__ TPP_MUL8(__SIZEOF_WCHAR_T__)
723 | #endif /* !__WCHAR_WIDTH__ */
724 | #ifndef __WINT_WIDTH__
725 | #define __WINT_WIDTH__ TPP_MUL8(__SIZEOF_WINT_T__)
726 | #endif /* !__WINT_WIDTH__ */
727 | #ifndef __INT_LEAST8_WIDTH__
728 | #define __INT_LEAST8_WIDTH__ 8
729 | #endif /* !__INT_LEAST8_WIDTH__ */
730 | #ifndef __INT_LEAST16_WIDTH__
731 | #define __INT_LEAST16_WIDTH__ 16
732 | #endif /* !__INT_LEAST16_WIDTH__ */
733 | #ifndef __INT_LEAST32_WIDTH__
734 | #define __INT_LEAST32_WIDTH__ 32
735 | #endif /* !__INT_LEAST32_WIDTH__ */
736 | #ifndef __INT_LEAST64_WIDTH__
737 | #define __INT_LEAST64_WIDTH__ 64
738 | #endif /* !__INT_LEAST64_WIDTH__ */
739 | #ifndef __INT_FAST8_WIDTH__
740 | #define __INT_FAST8_WIDTH__ 8
741 | #endif /* !__INT_FAST8_WIDTH__ */
742 | #ifndef __INT_FAST16_WIDTH__
743 | #define __INT_FAST16_WIDTH__ 16
744 | #endif /* !__INT_FAST16_WIDTH__ */
745 | #ifndef __INT_FAST32_WIDTH__
746 | #define __INT_FAST32_WIDTH__ 32
747 | #endif /* !__INT_FAST32_WIDTH__ */
748 | #ifndef __INT_FAST64_WIDTH__
749 | #define __INT_FAST64_WIDTH__ 64
750 | #endif /* !__INT_FAST64_WIDTH__ */
751 | #ifndef __INTPTR_WIDTH__
752 | #define __INTPTR_WIDTH__ TPP_MUL8(__SIZEOF_POINTER__)
753 | #endif /* !__INTPTR_WIDTH__ */
754 | #ifndef __INTMAX_WIDTH__
755 | #define __INTMAX_WIDTH__ 64
756 | #endif /* !__INTMAX_WIDTH__ */
757 |
758 | #ifndef __SIZE_TYPE__
759 | #define __SIZE_TYPE__ TPP_UINTTYPE(__SIZEOF_POINTER__)
760 | #endif /* !__SIZE_TYPE__ */
761 | #ifndef __PTRDIFF_TYPE__
762 | #define __PTRDIFF_TYPE__ TPP_INTTYPE(__SIZEOF_POINTER__)
763 | #endif /* !__PTRDIFF_TYPE__ */
764 | #ifndef __WCHAR_TYPE__
765 | #define __WCHAR_TYPE__ wchar_t
766 | #endif /* !__WCHAR_TYPE__ */
767 | #ifndef __WINT_TYPE__
768 | #define __WINT_TYPE__ int
769 | #endif /* !__WINT_TYPE__ */
770 | #ifndef __INTMAX_TYPE__
771 | #define __INTMAX_TYPE__ __INT64_TYPE__
772 | #endif /* !__INTMAX_TYPE__ */
773 | #ifndef __UINTMAX_TYPE__
774 | #define __UINTMAX_TYPE__ __UINT64_TYPE__
775 | #endif /* !__UINTMAX_TYPE__ */
776 | #ifndef __SIG_ATOMIC_TYPE__
777 | #define __SIG_ATOMIC_TYPE__ int
778 | #endif /* !__SIG_ATOMIC_TYPE__ */
779 | #ifndef __INT_LEAST8_TYPE__
780 | #define __INT_LEAST8_TYPE__ __INT8_TYPE__
781 | #endif /* !__INT_LEAST8_TYPE__ */
782 | #ifndef __INT_LEAST16_TYPE__
783 | #define __INT_LEAST16_TYPE__ __INT16_TYPE__
784 | #endif /* !__INT_LEAST16_TYPE__ */
785 | #ifndef __INT_LEAST32_TYPE__
786 | #define __INT_LEAST32_TYPE__ __INT32_TYPE__
787 | #endif /* !__INT_LEAST32_TYPE__ */
788 | #ifndef __INT_LEAST64_TYPE__
789 | #define __INT_LEAST64_TYPE__ __INT64_TYPE__
790 | #endif /* !__INT_LEAST64_TYPE__ */
791 | #ifndef __UINT_LEAST8_TYPE__
792 | #define __UINT_LEAST8_TYPE__ __UINT8_TYPE__
793 | #endif /* !__UINT_LEAST8_TYPE__ */
794 | #ifndef __UINT_LEAST16_TYPE__
795 | #define __UINT_LEAST16_TYPE__ __UINT16_TYPE__
796 | #endif /* !__UINT_LEAST16_TYPE__ */
797 | #ifndef __UINT_LEAST32_TYPE__
798 | #define __UINT_LEAST32_TYPE__ __UINT32_TYPE__
799 | #endif /* !__UINT_LEAST32_TYPE__ */
800 | #ifndef __UINT_LEAST64_TYPE__
801 | #define __UINT_LEAST64_TYPE__ __UINT64_TYPE__
802 | #endif /* !__UINT_LEAST64_TYPE__ */
803 | #ifndef __INT_FAST8_TYPE__
804 | #define __INT_FAST8_TYPE__ __INT8_TYPE__
805 | #endif /* !__INT_FAST8_TYPE__ */
806 | #ifndef __INT_FAST16_TYPE__
807 | #define __INT_FAST16_TYPE__ __INT16_TYPE__
808 | #endif /* !__INT_FAST16_TYPE__ */
809 | #ifndef __INT_FAST32_TYPE__
810 | #define __INT_FAST32_TYPE__ __INT32_TYPE__
811 | #endif /* !__INT_FAST32_TYPE__ */
812 | #ifndef __INT_FAST64_TYPE__
813 | #define __INT_FAST64_TYPE__ __INT64_TYPE__
814 | #endif /* !__INT_FAST64_TYPE__ */
815 | #ifndef __UINT_FAST8_TYPE__
816 | #define __UINT_FAST8_TYPE__ __UINT8_TYPE__
817 | #endif /* !__UINT_FAST8_TYPE__ */
818 | #ifndef __UINT_FAST16_TYPE__
819 | #define __UINT_FAST16_TYPE__ __UINT16_TYPE__
820 | #endif /* !__UINT_FAST16_TYPE__ */
821 | #ifndef __UINT_FAST32_TYPE__
822 | #define __UINT_FAST32_TYPE__ __UINT32_TYPE__
823 | #endif /* !__UINT_FAST32_TYPE__ */
824 | #ifndef __UINT_FAST64_TYPE__
825 | #define __UINT_FAST64_TYPE__ __UINT64_TYPE__
826 | #endif /* !__UINT_FAST64_TYPE__ */
827 | #ifndef __INTPTR_TYPE__
828 | #define __INTPTR_TYPE__ __PTRDIFF_TYPE__
829 | #endif /* !__INTPTR_TYPE__ */
830 | #ifndef __UINTPTR_TYPE__
831 | #define __UINTPTR_TYPE__ __SIZE_TYPE__
832 | #endif /* !__UINTPTR_TYPE__ */
833 | #endif /* !TPP_UTILITY_MACROS_DEFINED */
834 |
835 | #if (defined(__LP64__) || defined(_LP64)) || \
836 | (__SIZEOF_INT__ == 4 && __SIZEOF_LONG__ == 8 && __SIZEOF_POINTER__ == 8)
837 | PREDEFINED_MACRO_IF(__LP64__, HAS(EXT_SYSTEM_MACROS), "1")
838 | #endif
839 |
840 | PREDEFINED_MACRO_IF(__BYTE_ORDER__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(TPP_BYTEORDER))
841 | #ifdef __FLOAT_WORD_ORDER__
842 | PREDEFINED_MACRO_IF(__FLOAT_WORD_ORDER__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__FLOAT_WORD_ORDER__))
843 | #else /* __FLOAT_WORD_ORDER__ */
844 | PREDEFINED_MACRO_IF(__FLOAT_WORD_ORDER__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(TPP_BYTEORDER))
845 | #endif /* !__FLOAT_WORD_ORDER__ */
846 | PREDEFINED_MACRO_IF(__ORDER_LITTLE_ENDIAN__, HAS(EXT_UTILITY_MACROS), "1234")
847 | PREDEFINED_MACRO_IF(__ORDER_BIG_ENDIAN__, HAS(EXT_UTILITY_MACROS), "4321")
848 | PREDEFINED_MACRO_IF(__ORDER_PDP_ENDIAN__, HAS(EXT_UTILITY_MACROS), "3412")
849 |
850 | PREDEFINED_MACRO_IF(__SIZEOF_INT__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_INT__))
851 | PREDEFINED_MACRO_IF(__SIZEOF_LONG__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_LONG__))
852 | PREDEFINED_MACRO_IF(__SIZEOF_LONG_LONG__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_LONG_LONG__))
853 | PREDEFINED_MACRO_IF(__SIZEOF_SHORT__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_SHORT__))
854 | PREDEFINED_MACRO_IF(__SIZEOF_POINTER__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_POINTER__))
855 | PREDEFINED_MACRO_IF(__SIZEOF_FLOAT__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_FLOAT__))
856 | PREDEFINED_MACRO_IF(__SIZEOF_DOUBLE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_DOUBLE__))
857 | PREDEFINED_MACRO_IF(__SIZEOF_LONG_DOUBLE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_LONG_DOUBLE__))
858 | PREDEFINED_MACRO_IF(__SIZEOF_SIZE_T__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_SIZE_T__))
859 | PREDEFINED_MACRO_IF(__SIZEOF_WCHAR_T__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_WCHAR_T__))
860 | PREDEFINED_MACRO_IF(__SIZEOF_WINT_T__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_WINT_T__))
861 | PREDEFINED_MACRO_IF(__SIZEOF_PTRDIFF_T__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZEOF_PTRDIFF_T__))
862 |
863 | PREDEFINED_MACRO_IF(__SCHAR_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SCHAR_WIDTH__))
864 | PREDEFINED_MACRO_IF(__SHRT_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SHRT_WIDTH__))
865 | PREDEFINED_MACRO_IF(__INT_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_WIDTH__))
866 | PREDEFINED_MACRO_IF(__LONG_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__LONG_WIDTH__))
867 | PREDEFINED_MACRO_IF(__LONG_LONG_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__LONG_LONG_WIDTH__))
868 | PREDEFINED_MACRO_IF(__PTRDIFF_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__PTRDIFF_WIDTH__))
869 | PREDEFINED_MACRO_IF(__SIG_ATOMIC_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIG_ATOMIC_WIDTH__))
870 | PREDEFINED_MACRO_IF(__SIZE_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZE_WIDTH__))
871 | PREDEFINED_MACRO_IF(__WCHAR_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__WCHAR_WIDTH__))
872 | PREDEFINED_MACRO_IF(__WINT_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__WINT_WIDTH__))
873 | PREDEFINED_MACRO_IF(__INT_LEAST8_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_LEAST8_WIDTH__))
874 | PREDEFINED_MACRO_IF(__INT_LEAST16_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_LEAST16_WIDTH__))
875 | PREDEFINED_MACRO_IF(__INT_LEAST32_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_LEAST32_WIDTH__))
876 | PREDEFINED_MACRO_IF(__INT_LEAST64_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_LEAST64_WIDTH__))
877 | PREDEFINED_MACRO_IF(__INT_FAST8_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_FAST8_WIDTH__))
878 | PREDEFINED_MACRO_IF(__INT_FAST16_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_FAST16_WIDTH__))
879 | PREDEFINED_MACRO_IF(__INT_FAST32_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_FAST32_WIDTH__))
880 | PREDEFINED_MACRO_IF(__INT_FAST64_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_FAST64_WIDTH__))
881 | PREDEFINED_MACRO_IF(__INTPTR_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INTPTR_WIDTH__))
882 | PREDEFINED_MACRO_IF(__INTMAX_WIDTH__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INTMAX_WIDTH__))
883 |
884 | PREDEFINED_MACRO_IF(__SIZE_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIZE_TYPE__))
885 | PREDEFINED_MACRO_IF(__PTRDIFF_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__PTRDIFF_TYPE__))
886 | PREDEFINED_MACRO_IF(__WCHAR_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__WCHAR_TYPE__))
887 | PREDEFINED_MACRO_IF(__WINT_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__WINT_TYPE__))
888 | PREDEFINED_MACRO_IF(__INTMAX_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INTMAX_TYPE__))
889 | PREDEFINED_MACRO_IF(__UINTMAX_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINTMAX_TYPE__))
890 | PREDEFINED_MACRO_IF(__SIG_ATOMIC_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__SIG_ATOMIC_TYPE__))
891 | PREDEFINED_MACRO_IF(__INT8_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT8_TYPE__))
892 | PREDEFINED_MACRO_IF(__INT16_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT16_TYPE__))
893 | PREDEFINED_MACRO_IF(__INT32_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT32_TYPE__))
894 | PREDEFINED_MACRO_IF(__INT64_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT64_TYPE__))
895 | PREDEFINED_MACRO_IF(__UINT8_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT8_TYPE__))
896 | PREDEFINED_MACRO_IF(__UINT16_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT16_TYPE__))
897 | PREDEFINED_MACRO_IF(__UINT32_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT32_TYPE__))
898 | PREDEFINED_MACRO_IF(__UINT64_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT64_TYPE__))
899 | PREDEFINED_MACRO_IF(__INT_LEAST8_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_LEAST8_TYPE__))
900 | PREDEFINED_MACRO_IF(__INT_LEAST16_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_LEAST16_TYPE__))
901 | PREDEFINED_MACRO_IF(__INT_LEAST32_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_LEAST32_TYPE__))
902 | PREDEFINED_MACRO_IF(__INT_LEAST64_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_LEAST64_TYPE__))
903 | PREDEFINED_MACRO_IF(__UINT_LEAST8_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT_LEAST8_TYPE__))
904 | PREDEFINED_MACRO_IF(__UINT_LEAST16_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT_LEAST16_TYPE__))
905 | PREDEFINED_MACRO_IF(__UINT_LEAST32_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT_LEAST32_TYPE__))
906 | PREDEFINED_MACRO_IF(__UINT_LEAST64_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT_LEAST64_TYPE__))
907 | PREDEFINED_MACRO_IF(__INT_FAST8_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_FAST8_TYPE__))
908 | PREDEFINED_MACRO_IF(__INT_FAST16_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_FAST16_TYPE__))
909 | PREDEFINED_MACRO_IF(__INT_FAST32_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_FAST32_TYPE__))
910 | PREDEFINED_MACRO_IF(__INT_FAST64_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INT_FAST64_TYPE__))
911 | PREDEFINED_MACRO_IF(__UINT_FAST8_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT_FAST8_TYPE__))
912 | PREDEFINED_MACRO_IF(__UINT_FAST16_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT_FAST16_TYPE__))
913 | PREDEFINED_MACRO_IF(__UINT_FAST32_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT_FAST32_TYPE__))
914 | PREDEFINED_MACRO_IF(__UINT_FAST64_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINT_FAST64_TYPE__))
915 | PREDEFINED_MACRO_IF(__INTPTR_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__INTPTR_TYPE__))
916 | PREDEFINED_MACRO_IF(__UINTPTR_TYPE__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__UINTPTR_TYPE__))
917 |
918 | #ifdef __CHAR_BIT__
919 | PREDEFINED_MACRO_IF(__CHAR_BIT__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__CHAR_BIT__))
920 | #elif defined(CHAR_BIT)
921 | PREDEFINED_MACRO_IF(__CHAR_BIT__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(CHAR_BIT))
922 | #else
923 | PREDEFINED_MACRO_IF(__CHAR_BIT__, HAS(EXT_UTILITY_MACROS), "8")
924 | #endif
925 |
926 | PREDEFINED_MACRO_IF(__SCHAR_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(SCHAR_MAX))
927 | PREDEFINED_MACRO_IF(__WCHAR_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(WCHAR_MAX))
928 | PREDEFINED_MACRO_IF(__SHRT_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(SHRT_MAX))
929 | PREDEFINED_MACRO_IF(__INT_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT_MAX))
930 | PREDEFINED_MACRO_IF(__LONG_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(LONG_MAX))
931 | #ifdef __LONG_LONG_MAX__
932 | PREDEFINED_MACRO_IF(__LONG_LONG_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(__LONG_LONG_MAX__))
933 | #elif defined(LONG_LONG_MAX)
934 | PREDEFINED_MACRO_IF(__LONG_LONG_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(LONG_LONG_MAX))
935 | #else
936 | PREDEFINED_MACRO_IF(__LONG_LONG_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(LLONG_MAX))
937 | #endif
938 | PREDEFINED_MACRO_IF(__WINT_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(WINT_MAX))
939 | PREDEFINED_MACRO_IF(__SIZE_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(SIZE_MAX))
940 | PREDEFINED_MACRO_IF(__PTRDIFF_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(PTRDIFF_MAX))
941 | PREDEFINED_MACRO_IF(__INTMAX_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INTMAX_MAX))
942 | PREDEFINED_MACRO_IF(__UINTMAX_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINTMAX_MAX))
943 | PREDEFINED_MACRO_IF(__SIG_ATOMIC_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(SIG_ATOMIC_MAX))
944 | PREDEFINED_MACRO_IF(__INT8_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT8_MAX))
945 | PREDEFINED_MACRO_IF(__INT16_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT16_MAX))
946 | PREDEFINED_MACRO_IF(__INT32_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT32_MAX))
947 | PREDEFINED_MACRO_IF(__INT64_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT64_MAX))
948 | PREDEFINED_MACRO_IF(__UINT8_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT8_MAX))
949 | PREDEFINED_MACRO_IF(__UINT16_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT16_MAX))
950 | PREDEFINED_MACRO_IF(__UINT32_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT32_MAX))
951 | PREDEFINED_MACRO_IF(__UINT64_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT64_MAX))
952 | PREDEFINED_MACRO_IF(__INT_LEAST8_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT_LEAST8_MAX))
953 | PREDEFINED_MACRO_IF(__INT_LEAST16_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT_LEAST16_MAX))
954 | PREDEFINED_MACRO_IF(__INT_LEAST32_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT_LEAST32_MAX))
955 | PREDEFINED_MACRO_IF(__INT_LEAST64_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT_LEAST64_MAX))
956 | PREDEFINED_MACRO_IF(__UINT_LEAST8_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT_LEAST8_MAX))
957 | PREDEFINED_MACRO_IF(__UINT_LEAST16_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT_LEAST16_MAX))
958 | PREDEFINED_MACRO_IF(__UINT_LEAST32_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT_LEAST32_MAX))
959 | PREDEFINED_MACRO_IF(__UINT_LEAST64_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT_LEAST64_MAX))
960 | PREDEFINED_MACRO_IF(__INT_FAST8_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT_FAST8_MAX))
961 | PREDEFINED_MACRO_IF(__INT_FAST16_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT_FAST16_MAX))
962 | PREDEFINED_MACRO_IF(__INT_FAST32_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT_FAST32_MAX))
963 | PREDEFINED_MACRO_IF(__INT_FAST64_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INT_FAST64_MAX))
964 | PREDEFINED_MACRO_IF(__UINT_FAST8_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT_FAST8_MAX))
965 | PREDEFINED_MACRO_IF(__UINT_FAST16_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT_FAST16_MAX))
966 | PREDEFINED_MACRO_IF(__UINT_FAST32_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT_FAST32_MAX))
967 | PREDEFINED_MACRO_IF(__UINT_FAST64_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINT_FAST64_MAX))
968 | PREDEFINED_MACRO_IF(__INTPTR_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(INTPTR_MAX))
969 | PREDEFINED_MACRO_IF(__UINTPTR_MAX__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(UINTPTR_MAX))
970 | PREDEFINED_MACRO_IF(__WCHAR_MIN__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(WCHAR_MIN))
971 | PREDEFINED_MACRO_IF(__WINT_MIN__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(WINT_MIN))
972 | PREDEFINED_MACRO_IF(__SIG_ATOMIC_MIN__, HAS(EXT_UTILITY_MACROS), TPP_PP_STR(SIG_ATOMIC_MIN))
973 |
974 | DEF_M_IF(__INT8_C, HAS(EXT_UTILITY_MACROS))
975 | DEF_M_IF(__INT16_C, HAS(EXT_UTILITY_MACROS))
976 | DEF_M_IF(__INT32_C, HAS(EXT_UTILITY_MACROS))
977 | DEF_M_IF(__INT64_C, HAS(EXT_UTILITY_MACROS))
978 | DEF_M_IF(__UINT8_C, HAS(EXT_UTILITY_MACROS))
979 | DEF_M_IF(__UINT16_C, HAS(EXT_UTILITY_MACROS))
980 | DEF_M_IF(__UINT32_C, HAS(EXT_UTILITY_MACROS))
981 | DEF_M_IF(__UINT64_C, HAS(EXT_UTILITY_MACROS))
982 | DEF_M_IF(__INTMAX_C, HAS(EXT_UTILITY_MACROS))
983 | DEF_M_IF(__UINTMAX_C, HAS(EXT_UTILITY_MACROS))
984 |
985 | PREDEFINED_MACRO_IF(__CHAR_UNSIGNED__,
986 | HAS(EXT_UTILITY_MACROS) && (TPPLexer_Current->l_flags & TPPLEXER_FLAG_CHAR_UNSIGNED), "1")
987 | PREDEFINED_MACRO_IF(__WCHAR_UNSIGNED__, HAS(EXT_UTILITY_MACROS), "1") /* xxx: flag? */
988 |
989 | #undef TPP_PP_CAT3
990 | #undef TPP_PP_CAT2
991 | #undef TPP_PRIVATE_PP_CAT3
992 | #undef TPP_PRIVATE_PP_CAT2
993 |
--------------------------------------------------------------------------------
/test/_runall.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd "$(dirname "$(readlink -f "$0")")/.."
4 | TPP="$(pwd)/bin/tpp"
5 | if [[ -f "${TPP}.exe" ]]; then TPP="${TPP}.exe"; fi
6 | TPP="$TPP -P -Werror"
7 |
8 | # testFile
9 | testFile() {
10 | echo "Running: $TPP -fno-spc -fno-lf $1"
11 | $TPP -fno-spc -fno-lf "$1" || {
12 | error="$?"
13 | echo "Command failed: '$TPP -fno-spc -fno-lf $1' -> '$error'"
14 | exit $error
15 | }
16 | echo "Running: $TPP $1"
17 | $TPP "$1" > /dev/null || {
18 | error="$?"
19 | echo "Command failed: '$TPP $1' -> '$error'"
20 | exit $error
21 | }
22 | }
23 |
24 | cd "test"
25 | for file in *.h; do
26 | testFile "$file"
27 | done
28 |
29 | # This test requires some special care as it relates to relative includes
30 | cd inner
31 | testFile "test.h"
32 | cd ..
33 |
--------------------------------------------------------------------------------
/test/arguments_as_macro.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #define args 10,20,30
23 | #define func(a,b,c) a+b+c
24 |
25 | #pragma warning("-Wmacros")
26 | #if !__has_warning("-Wmacros")
27 | #error "Should now be enabled"
28 | #endif
29 | #pragma warning("-Wsup-macros")
30 | #if __has_warning("-Wmacros")
31 | #error "Should now be suppressed (once)"
32 | #endif
33 |
34 | /* E0105("-Wmacros"): Not enough enough arguments for `func' */
35 | /* NOTE: Expands to:
36 | * >> [func][(][args][)]
37 | * >> [args][+][][+][]
38 | * >> [10][,][20][,][30][+][+] */
39 | TEST_EXPANDS(func(args), "10,20,30++")
40 |
41 | #if !__has_warning("-Wmacros")
42 | #error "Should have been triggered"
43 | #endif
44 |
45 |
--------------------------------------------------------------------------------
/test/clone_linefeed.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // Copy Line-feeds
23 |
24 | #define clone(...) __VA_ARGS__ __VA_ARGS__
25 | TEST_EXPANDS(
26 | clone({
27 | int x = 42;
28 | })
29 | , "{\n int x = 42;\n} {\n int x = 42;\n}")
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/test/count_tokens.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | TEST_EXPANDS(__TPP_COUNT_TOKENS(""), "0")
23 | TEST_EXPANDS(__TPP_COUNT_TOKENS("foo"), "1")
24 | TEST_EXPANDS(__TPP_COUNT_TOKENS("foo+"), "2")
25 | TEST_EXPANDS(__TPP_COUNT_TOKENS("foo[]"), "3")
26 |
--------------------------------------------------------------------------------
/test/cxx_comments_in_macro.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #define foo(a) [a] // Comment
23 |
24 | #define expand2(x) x
25 | #define expand(x) expand2(x)
26 |
27 | //FIXME:TEST_EXPANDS(expand(foo(10)), "[10]")
28 |
29 |
--------------------------------------------------------------------------------
/test/define_directives.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #define define undef
23 |
24 | TEST_EXPANDS(FOOBAR, "FOOBAR")
25 | #define FOOBAR 42
26 | TEST_EXPANDS(FOOBAR, "42")
27 | TEST_EXPANDS(define FOOBAR 42, "undef 42 42")
28 | #undef FOOBAR
29 | #undef define
30 | TEST_EXPANDS(define FOOBAR 42, "define FOOBAR 42")
31 |
32 |
--------------------------------------------------------------------------------
/test/directives_in_macros.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | /* Preprocessor blocks within macro arguments */
23 |
24 | TEST_EXPANDS(
25 | #if 0
26 | Stuff in the middle
27 | #endif
28 | , "")
29 |
30 | TEST_EXPANDS(
31 | #if 1
32 | Stuff in the middle
33 | #endif
34 | , "Stuff in the middle")
35 |
36 | #define NARGS(...) __VA_NARGS__
37 |
38 | TEST_EXPANDS(NARGS(
39 | #if 0
40 | a
41 | #endif
42 | ), "1")
43 |
44 | TEST_EXPANDS(NARGS(
45 | #if 0
46 | a
47 | #endif
48 | b
49 | ), "1")
50 |
51 | TEST_EXPANDS(NARGS(
52 | b
53 | #if 0
54 | a
55 | #endif
56 | ), "1")
57 |
58 | TEST_EXPANDS(NARGS(
59 | #if 1
60 | a
61 | #endif
62 | ), "1")
63 |
64 | #define EAT(...) __pragma(tpp_exec(#__VA_ARGS__))
65 | #define EXPAND_HIDDEN(a, b) EAT(a, b)
66 |
67 | PRAGMA_WARNING_PUSH_SUPPRESS("syntax")
68 | EXPAND_HIDDEN(
69 | a
70 | #if 0 /* E0032("-Wsyntax"): #if without #endif */
71 | ,
72 | PRAGMA_WARNING_POP_SUPPRESS("syntax")
73 | PRAGMA_WARNING_PUSH_SUPPRESS("syntax") /* Supress again for 2nd syntax error */
74 | #endif /* E0033("-Wsyntax"): #endif without #if */
75 | b
76 | )
77 | PRAGMA_WARNING_POP_SUPPRESS("syntax")
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/test/directives_start_of_line.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // ISO/IEC 9899:201x - 6.10 - 8
23 |
24 | #define EMPTY
25 | TEST_EXPANDS(
26 | EMPTY # include // Expands to [#][include][<][file][.][h][>]
27 | , "# include ")
28 |
29 | #undef EMPTY
30 | TEST_EXPANDS(
31 | EMPTY # include // Expands to [EMPTY][#][include][<][file][.][h][>]
32 | , "EMPTY # include ")
33 |
34 |
--------------------------------------------------------------------------------
/test/double_counter.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 |
23 | /* Make sure that macro-arguments who's representation differs
24 | * every time they are expanded (such as __COUNTER__) are only
25 | * expanded _ONCE_ when used multiple times within the same
26 | * function-like macro */
27 | #define SAME(x) TEST_ASSERT(x == x)
28 | SAME(__COUNTER__)
29 |
30 | /* Still make sure that `__COUNTER__' changes every time, though... */
31 | TEST_ASSERT(__COUNTER__ != __COUNTER__)
32 |
--------------------------------------------------------------------------------
/test/glue.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #if 0
23 | #define hash_hash # ## #
24 | #else
25 | // NOTE: NON-Standard:
26 | // - TPP only allows macro function
27 | // arguments as operands for the ## operator:
28 | // ##
29 | // - and must both be a keyword (or number, if __TPP_VERSION__ >= 102)
30 | // - or must be a macro function argument
31 | #define GLUE(a,b) a ## b
32 | #define hash_hash GLUE(#,#)
33 | #endif
34 | #define mkstr(a) # a
35 | #define in_between(a) mkstr(a)
36 | #define join(c, d) in_between(c hash_hash d)
37 |
38 | TEST_EXPANDS(char p[] = join(x, y);, "char p[] = \"x ## y\";")
39 |
40 |
41 |
--------------------------------------------------------------------------------
/test/has_include.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #define DOUBLE_ASSERT(x) TEST_ASSERT(x) TEST_ASSERT(x)
23 |
24 | TEST_ASSERT(__has_include("has_include.h"))
25 | TEST_ASSERT(__has_include("has_include.h"))
26 | TEST_ASSERT(!__has_include("NOPE"))
27 | TEST_ASSERT(!__has_include("./NOPE.h"))
28 | TEST_ASSERT(__has_include("./has_include.h"))
29 | TEST_ASSERT(__has_include("../test/has_include.h"))
30 | TEST_ASSERT(__has_include("does_exist/../has_include.h"))
31 | DOUBLE_ASSERT(!__has_include("./NOPE.h"))
32 | DOUBLE_ASSERT(__has_include("./has_include.h"))
33 |
--------------------------------------------------------------------------------
/test/include/def.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 |
21 | #define ITS_A_SECRET "no it isn't"
22 |
23 |
--------------------------------------------------------------------------------
/test/include/test.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 |
21 | #define TEST_STR2(...) #__VA_ARGS__
22 | #define TEST_STR(...) TEST_STR2(__VA_ARGS__)
23 | #ifndef __pragma
24 | #define __pragma(...) _Pragma(TEST_STR2(__VA_ARGS__))
25 | #endif /* !__pragma */
26 | #define TEST_PRINT(...) __pragma(message(__VA_ARGS__))
27 |
28 | #define _TEST_ASSERT_0(msg) __pragma(error(__FILE__ "(" TEST_STR(__LINE__) ") : Assertion failed: '" msg "'"))
29 | #define _TEST_ASSERT_1(msg) /* Success */
30 | #define _TEST_ASSERT2(expr, msg) _TEST_ASSERT_##expr(msg)
31 | #define _TEST_ASSERT(expr, msg) _TEST_ASSERT2(expr, msg)
32 | #define TEST_ASSERT(expr) _TEST_ASSERT(__TPP_EVAL(!!(expr)), #expr)
33 |
34 | #define TEST_EXPANDS(text, to) \
35 | TEST_PRINT("\tTesting: expands: " #to) \
36 | _TEST_ASSERT(__TPP_EVAL(TEST_STR2(text) == to), "\n\tWanted: " #to "\n\tGot: " TEST_STR(TEST_STR2(text)))
37 |
38 | #define PRAGMA_WARNING_PUSH_SUPPRESS(name) \
39 | __pragma(warning(push, "-W" name)) \
40 | TEST_ASSERT(__has_warning("-W" name)) \
41 | __pragma(warning("-Wsup-" name)) \
42 | TEST_ASSERT(!__has_warning("-W" name))
43 | #define PRAGMA_WARNING_POP_SUPPRESS(name) \
44 | TEST_ASSERT(__has_warning("-W" name)) \
45 | __pragma(warning(pop))
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/test/include_path.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #pragma once
23 |
24 | #ifdef WAS_HERE
25 | #error "Shouldn't have gotten here more than once!"
26 | #endif
27 | #define WAS_HERE
28 |
29 | /* include ourselves with some really abstract path.
30 | * #pragma once will prevent infinite recursion */
31 | #include "include_path.h"
32 | #include "./include_path.h"
33 |
34 | //FIXME:#include "./../test/include_path.h"
35 | //FIXME:#include "./../test/include_path.h"
36 | //FIXME:#include "./../test/./missing_folder/../include_path.h"
37 |
--------------------------------------------------------------------------------
/test/inner/test.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 |
21 | #ifdef ITS_A_SECRET
22 | #error "How?"
23 | #endif
24 |
25 | #include "../../test/include/def.h"
26 |
27 | #ifndef ITS_A_SECRET
28 | #error "Wrong file included?"
29 | #endif
30 | #undef ITS_A_SECRET
31 |
32 | #include "./../../test/include/def.h"
33 |
34 | #ifndef ITS_A_SECRET
35 | #error "Wrong file included?"
36 | #endif
37 |
--------------------------------------------------------------------------------
/test/macro-argument-whitespace.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | /* Test the effects of the "macro-argument-whitespace" extension. */
23 |
24 | #define STR1(x) #x
25 | #pragma extension(push, "-fmacro-argument-whitespace")
26 | #define STR2(x) #x
27 | #pragma extension(pop)
28 |
29 | TEST_EXPANDS(STR1(foo), "\"foo\"")
30 | TEST_EXPANDS(STR1( foo ), "\"foo\"")
31 | TEST_EXPANDS(STR2(foo), "\"foo\"")
32 | TEST_EXPANDS(STR2( foo ), "\" foo \"")
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/test/macro_call_conv.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // Macro calling conventions
23 |
24 | #define angle +x-
25 | #define brace{x} +x-
26 | #define bracket[x] +x-
27 | #define paren(x) +x- // Original (Unchanged)
28 |
29 | TEST_EXPANDS(angle<<>>, "+<>-")
30 | //angle<<<>> // ERROR: EOF in macro argument list
31 | TEST_EXPANDS(angle<{<}>, "+{<}-")
32 | TEST_EXPANDS(angle<[<]>, "+[<]-")
33 | TEST_EXPANDS(angle<(<)>, "+(<)-")
34 | TEST_EXPANDS(angle<{>}>, "+{>}-")
35 | TEST_EXPANDS(angle<[>]>, "+[>]-")
36 | TEST_EXPANDS(angle<(>)>, "+(>)-")
37 | //brace{<{>} // ERROR: EOF in macro argument list
38 | //brace{{{}} // ERROR: EOF in macro argument list
39 | TEST_EXPANDS(brace{[{]}, "+[{]-")
40 | TEST_EXPANDS(brace{({)}, "+({)-")
41 | TEST_EXPANDS(brace{[}]}, "+[}]-")
42 | TEST_EXPANDS(brace{(})}, "+(})-")
43 | //bracket[<[>] // ERROR: EOF in macro argument list
44 | //bracket[{[}] // ERROR: EOF in macro argument list
45 | //bracket[[[]] // ERROR: EOF in macro argument list
46 | TEST_EXPANDS(bracket[([)], "+([)-")
47 | TEST_EXPANDS(bracket[(])], "+(])-")
48 | //paren(<(>) // ERROR: EOF in macro argument list
49 | //paren({(}) // ERROR: EOF in macro argument list
50 | //paren([(]) // ERROR: EOF in macro argument list
51 | //paren((()) // ERROR: EOF in macro argument list
52 |
53 | #define map_node struct{K key; T value;}
54 | #define point struct{T x; T y;}
55 | TEST_EXPANDS(point> x;, "struct{struct{int x; int y;} x; struct{int x; int y;} y;} x;")
56 | TEST_EXPANDS((map_node e;), "(struct{std::string key; int value;} e;)")
57 |
58 | #define __TPP_ARGS(...) (__VA_ARGS__))
59 | #define static_cast<...> ((__VA_ARGS__)__TPP_ARGS
60 |
61 | TEST_EXPANDS(int x = static_cast(100l);, "int x = ((int)(100l));")
62 |
63 |
--------------------------------------------------------------------------------
/test/macro_escape_lf.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // Test 18: Macros with escaped line feeds
23 |
24 | #define macro \
25 | code... \
26 | /**/
27 | #define func(a,b,c) \
28 | a + b + c \
29 | /**/
30 |
31 | TEST_EXPANDS(macro,"code...")
32 | TEST_EXPANDS(func(10,20,30),"10 + 20 + 30")
33 |
34 |
35 |
--------------------------------------------------------------------------------
/test/null_directive.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #
23 | #
24 | #
25 | # /* Some Null directives */
26 | # // Some Null directives
27 | #
28 | #
29 | #
30 |
31 | #
32 | #! Also this type of NULL-directive (for Hash-Bang compatibility)
33 | #
34 |
35 |
--------------------------------------------------------------------------------
/test/pound_xclaim.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #define STR(x) #x
23 | #define WARP0(x) STR(x)
24 | #define WARP1(x) STR(#!x)
25 |
26 | #define FOO 42
27 |
28 | TEST_EXPANDS(WARP0(FOO), "\"42\"")
29 | TEST_EXPANDS(WARP1(FOO), "\"FOO\"")
30 |
31 |
--------------------------------------------------------------------------------
/test/prevent_macro_expansion.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // Prevent macro expansion
23 |
24 | #define PREVENT_EXP_KWD
25 | #define PREVENT_EXP_FNC()
26 | #define min(a,b) ((a) < (b) ? (a) : (b))
27 |
28 | TEST_EXPANDS(int min PREVENT_EXP_KWD (int,int);, "int min (int,int);")
29 | TEST_EXPANDS(int min PREVENT_EXP_FNC() (int,int);, "int min (int,int);")
30 |
31 | TEST_EXPANDS(int min(int,int);, "int ((int) < (int) ? (int) : (int));")
32 |
--------------------------------------------------------------------------------
/test/push_pop_macro.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // #pragma push_macro
23 |
24 | TEST_EXPANDS(int *a = new int();, "int *a = new int();")
25 | #define new __debug_new
26 | TEST_EXPANDS(int *b = new int();, "int *b = __debug_new int();")
27 | #pragma push_macro("new")
28 | #undef new
29 | #define new __alt_default_new
30 | TEST_EXPANDS(int *c = new int();, "int *c = __alt_default_new int();")
31 | #pragma pop_macro("new")
32 | TEST_EXPANDS(int *d = new int();, "int *d = __debug_new int();")
33 | TEST_EXPANDS(int *e = new int();, "int *e = __debug_new int();")
34 | #undef new
35 | TEST_EXPANDS(int *f = new int();, "int *f = new int();")
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/test/quotes_in_error.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | TEST_EXPANDS(BEFORE, "BEFORE")
23 |
24 | #if 0
25 |
26 | #error An incomplete " in a disabled #error directive
27 | #error An incomplete ' in a disabled #error directive
28 | #error An incomplete """ in a disabled #error directive
29 | #error An incomplete ''' in a disabled #error directive
30 |
31 | #else
32 |
33 | #pragma warning(push, "-Wno-user") /* Hide warnings */
34 | #warning An incomplete " in an enabled #warning directive
35 | #warning An incomplete " in an enabled #warning directive
36 | #warning An incomplete " in an enabled #warning directive
37 | #warning An incomplete ' in an enabled #warning directive
38 | #warning An incomplete ' in an enabled #warning directive
39 | #warning An incomplete ' in an enabled #warning directive
40 | #warning An incomplete ' in an enabled #warning directive
41 | #pragma warning(pop)
42 |
43 | #endif
44 |
45 | TEST_EXPANDS(AFTER, "AFTER")
46 |
--------------------------------------------------------------------------------
/test/self_redef.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #define REDEF(m, b) __pragma(tpp_exec("#undef " #m "\n#define " #m " " #b))
23 | #define Word w1
24 | #define w1 REDEF(Word, w2)Hello
25 | #define w2 REDEF(Word, w3)There
26 | #define w3 REDEF(Word, w4)Good
27 | #define w4 REDEF(Word, w1)Sir!
28 |
29 | TEST_EXPANDS(Word Word Word Word, "Hello There Good Sir!")
30 | TEST_EXPANDS(Word, "Hello")
31 | TEST_EXPANDS(Word, "There")
32 | TEST_EXPANDS(Word, "Good")
33 | TEST_EXPANDS(Word, "Sir!")
34 | TEST_EXPANDS(Word Word, "Hello There")
35 | TEST_EXPANDS(Word Word, "Good Sir!")
36 |
37 |
38 |
--------------------------------------------------------------------------------
/test/stdc_6.10.3.5_5.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // ISO/IEC 9899:201x - 6.10.3.5 - 5
23 |
24 | #define x 3
25 | #define f(a) f(x * (a))
26 | #undef x
27 | #define x 2
28 | #define g f
29 | #define z z[0]
30 | #define h g(~
31 | #define m(a) a(w)
32 | #define w 0,1
33 | #define t(a) a
34 | #define p() int
35 | #define q(x) x
36 | #define r(x,y) x ## y
37 | #define str(x) # x
38 |
39 | /* z gets expanded multiple times (see "pp_fixme.h") */
40 | TEST_EXPANDS(f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);,
41 | "f(2 * (y+1)) + f(2 * (f(2 * (z[0][0][0])))) % f(2 * (2 * (0))) + t(1);")
42 |
43 | /* EOF in macro argument list (see "pp_unsupported.h") */
44 | //TEST_EXPANDS(g(x+(3,4)-w) | h 5) & m, "f(2 * (2+(3,4)-0,1)) | f(2 * (~)) 5")
45 |
46 | TEST_EXPANDS((f)^m(m);, "(f)^m(0,1);")
47 |
48 | TEST_EXPANDS((p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };),
49 | "(int i[] = { 1, 23, 4, 5, };)")
50 | TEST_EXPANDS((char c[2][6] = { str(hello), str() };),
51 | "(char c[2][6] = { \"hello\", \"\" };)")
52 |
53 |
--------------------------------------------------------------------------------
/test/stdc_6.10.3.5_6.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | /* ISO/IEC 9899:201x - 6.10.3.5 - 6 */
23 |
24 |
25 | #define str(s) # s
26 | #define xstr(s) str(s)
27 | #define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \
28 | x##s,x##t)
29 | #define INCFILE(n) vers ## n
30 | #define glue(a, b) a ## b
31 | #define xglue(a, b) glue(a, b)
32 | #define HIGHLOW "hello"
33 | #define LOW LOW ", world"
34 | TEST_EXPANDS(debug(1, 2);, "printf(\"x\" \"1\" \"= %d, x\" \"2\" \"= %s\", \\\nx1,x2);")
35 | TEST_EXPANDS(fputs(str(strncmp("abc\0d", "abc", '\4') // this goes away
36 | == 0) str(: @\n), s);,
37 | "fputs(\"strncmp(\\\"abc\\\\0d\\\", \\\"abc\\\", "
38 | "\\\'\\\\4\\\') // this goes away\\n== 0\" \": @\\\\n\", s);")
39 |
40 | #pragma warning(push)
41 | #pragma warning(disable:15) /* File not found */
42 | TEST_EXPANDS(xstr(INCFILE(2).h), "\"vers2.h\"")
43 | #include xstr(INCFILE(2).h)
44 | #pragma warning(pop)
45 |
46 | TEST_EXPANDS(glue(HIGH, LOW);, "\"hello\";")
47 | TEST_EXPANDS(xglue(HIGH, LOW), "\"hello\" \", world\"")
48 |
49 |
50 |
--------------------------------------------------------------------------------
/test/stdc_6.10.3.5_7.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // ISO/IEC 9899:201x - 6.10.3.5 - 7
23 |
24 | #define t(x,y,z) x ## y ## z
25 | TEST_EXPANDS((int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), t(10,,), t(,11,), t(,,12), t(,,) };),
26 | "(int j[] = { 123, 45, 67, 89, 10, 11, 12, };)")
27 |
28 |
29 |
--------------------------------------------------------------------------------
/test/stdc_6.10.3.5_9.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // ISO/IEC 9899:201x - 6.10.3.5 - 9
23 |
24 | #define debug(...) fprintf(stderr, __VA_ARGS__)
25 | #define debug2(...) fprintf(stderr, ##__VA_ARGS__)
26 | #define showlist(...) puts(#__VA_ARGS__)
27 | #define report(test, ...) ((test)?puts(#test):\
28 | printf(__VA_ARGS__))
29 | TEST_EXPANDS(debug();, "fprintf(stderr, );")
30 | TEST_EXPANDS(debug2();, "fprintf(stderr);")
31 | TEST_EXPANDS(debug("Flag");, "fprintf(stderr, \"Flag\");")
32 | TEST_EXPANDS(debug2("Flag");, "fprintf(stderr,\"Flag\");")
33 | TEST_EXPANDS(debug("X = %d\n", x);, "fprintf(stderr, \"X = %d\\n\", x);")
34 | TEST_EXPANDS(showlist(The first, second, and third items.);, "puts(\"The first, second, and third items.\");")
35 | TEST_EXPANDS(report(x>y, "x is %d but y is %d", x, y);, "((x>y)?puts(\"x>y\"): printf(\"x is %d but y is %d\", x, y));")
36 |
37 |
--------------------------------------------------------------------------------
/test/stdc_6.10.3_5+6.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // ISO/IEC 9899:201x - 6.10.3 - 5 + 6
23 |
24 | // ISO/IEC 9899:201x - 6.10.3 - 5
25 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
26 | #define VARARGS(__VA_ARGS__) __VA_ARGS__ /* Warning: __VA_ARGS__ used as argument name */
27 | PRAGMA_WARNING_POP_SUPPRESS("macros")
28 | TEST_EXPANDS(VARARGS(foo), "foo")
29 | #undef VARARGS
30 |
31 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
32 | #define VARARGS(__VA_COMMA__) __VA_COMMA__ /* Warning: __VA_COMMA__ used as argument name */
33 | PRAGMA_WARNING_POP_SUPPRESS("macros")
34 | TEST_EXPANDS(VARARGS(foo), "foo")
35 | #undef VARARGS
36 |
37 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
38 | #define VARARGS(__VA_OPT__) __VA_OPT__ /* Warning: __VA_OPT__ used as argument name */
39 | PRAGMA_WARNING_POP_SUPPRESS("macros")
40 | TEST_EXPANDS(VARARGS(foo), "foo")
41 | #undef VARARGS
42 |
43 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
44 | #define VARARGS(__VA_NARGS__) __VA_NARGS__ /* Warning: __VA_NARGS__ used as argument name */
45 | PRAGMA_WARNING_POP_SUPPRESS("macros")
46 | TEST_EXPANDS(VARARGS(foo), "foo")
47 | #undef VARARGS
48 |
49 | // ISO/IEC 9899:201x - 6.10.3 - 6
50 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
51 | #define ARG_NAMES(a,b,c,a) a+b+c+a /* Warning: Parameter name "a" reused */
52 | PRAGMA_WARNING_POP_SUPPRESS("macros")
53 | TEST_EXPANDS(ARG_NAMES(10,20,30), "10+20+30+10")
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/test/strings_in_expressions.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | /* TPP Allows for use of strings in #if directives (as well as `__TPP_EVAL') */
23 | TEST_EXPANDS(__TPP_EVAL('F'), "70")
24 | TEST_EXPANDS(__TPP_EVAL("FOO"[0]), "70")
25 | TEST_EXPANDS(__TPP_EVAL("FOO"[0:]), "\"FOO\"")
26 | TEST_EXPANDS(__TPP_EVAL("FOO"[1:]), "\"OO\"")
27 | TEST_EXPANDS(__TPP_EVAL("FOO"[0:1]), "\"F\"")
28 | TEST_EXPANDS(__TPP_EVAL("FOO"[0:2]), "\"FO\"")
29 | TEST_EXPANDS(__TPP_EVAL("FOO"[0:-1]), "\"FO\"")
30 | TEST_EXPANDS(__TPP_EVAL("FOO"[:-1]), "\"FO\"")
31 | TEST_EXPANDS(__TPP_EVAL("FOO"[1:-1]), "\"O\"")
32 | TEST_EXPANDS(__TPP_EVAL("FOO" == "BAR"), "0")
33 | TEST_EXPANDS(__TPP_EVAL("FOO" != "BAR"), "1")
34 | TEST_EXPANDS(__TPP_EVAL("FOO" == "FOO"), "1")
35 | TEST_EXPANDS(__TPP_EVAL("FOO" == "foo"), "0")
36 |
37 | /* TPP Also allows for use of GCC-style __builtin_* functions
38 | * in #if directives. (and therefor also in `__TPP_EVAL') */
39 | TEST_EXPANDS(__TPP_EVAL(__builtin_strcmp("FOO", "foo") < 0), "1")
40 | TEST_EXPANDS(__TPP_EVAL(__builtin_strcmp("FOO", "foo") > 0), "0")
41 | TEST_EXPANDS(__TPP_EVAL(__builtin_strcmp("foo", "FOO") < 0), "0")
42 | TEST_EXPANDS(__TPP_EVAL(__builtin_strcmp("foo", "FOO") > 0), "1")
43 | TEST_EXPANDS(__TPP_EVAL(__builtin_strcasecmp("FOO", "foo")), "0")
44 |
45 | TEST_EXPANDS(__TPP_EVAL(__builtin_ffs(0x123)), "1")
46 | TEST_EXPANDS(__TPP_EVAL(__builtin_ffs(0x100)), "9")
47 |
48 | /* Multi-char character literals. */
49 | TEST_EXPANDS(__TPP_EVAL('a'), "97")
50 | TEST_EXPANDS(__TPP_EVAL('ab'), "25185")
51 | TEST_EXPANDS(__TPP_EVAL('abc'), "6513249")
52 |
53 |
54 | #define CAT2(a, b) a##b
55 | #define CAT(a, b) CAT2(a, b)
56 | #define ISLESS_0 more than
57 | #define ISLESS_1 less than
58 | #define SELECT(n) CAT(ISLESS_, __TPP_EVAL(n < 10))
59 | TEST_EXPANDS(SELECT(7), "less than")
60 | TEST_EXPANDS(SELECT(10), "more than")
61 |
62 | TEST_EXPANDS(__TPP_STR_PACK(0x48, 0x65, 0x6c, 0x6c, 0x6f), "\"Hello\"")
63 |
--------------------------------------------------------------------------------
/test/tpp_exec.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | /* TPP Includes a builtin `#pragma tpp_exec("foo")' that can be used
23 | * to run preprocessor text whilst discarding all produced output.
24 | *
25 | * Using this, macros are able to (re-)define other macros, or even
26 | * themselves! */
27 |
28 |
29 | /* Use __pragma(tpp_exec()) to delete a macro while it's being expanded.
30 | * This used to fail due to a problem relating to recursive parenthesis
31 | * tracking failing to skip the trailing `)' in `__pragma(tpp_exec(...))' */
32 | #define foo(x) x
33 | TEST_EXPANDS(foo(10 __pragma(tpp_exec("#undef foo")) 20), "10 20")
34 | TEST_EXPANDS(foo(10 __pragma(tpp_exec("#undef foo")) 20), "foo(10 20)")
35 | TEST_EXPANDS(foo(10 __pragma(tpp_exec("#undef foo")) 20), "foo(10 20)")
36 | TEST_EXPANDS(foo(10 __pragma(tpp_exec("#undef foo")) 20), "foo(10 20)")
37 |
38 | #define foo(x) x
39 | TEST_EXPANDS(foo(10 _Pragma("tpp_exec(\"#undef foo\")") 20), "10 20")
40 | TEST_EXPANDS(foo(10 _Pragma("tpp_exec(\"#undef foo\")") 20), "foo(10 20)")
41 | TEST_EXPANDS(foo(10 _Pragma("tpp_exec(\"#undef foo\")") 20), "foo(10 20)")
42 | TEST_EXPANDS(foo(10 _Pragma("tpp_exec(\"#undef foo\")") 20), "foo(10 20)")
43 |
44 |
45 | #define HACK_COUNTER_VALUE 0
46 | #define STR2(x) #x
47 | #define STR(x) STR2(x)
48 | #define HACK_COUNTER \
49 | HACK_COUNTER_VALUE \
50 | __pragma(tpp_exec( \
51 | "#undef HACK_COUNTER_VALUE\n" \
52 | "#define HACK_COUNTER_VALUE " STR(__TPP_EVAL(HACK_COUNTER_VALUE + 1)) "\n" \
53 | ))
54 |
55 | TEST_EXPANDS(HACK_COUNTER_VALUE, "0")
56 | TEST_EXPANDS(HACK_COUNTER_VALUE, "0")
57 | TEST_EXPANDS(HACK_COUNTER, "0")
58 | TEST_EXPANDS(HACK_COUNTER, "1")
59 | TEST_EXPANDS(HACK_COUNTER, "2")
60 | TEST_EXPANDS(HACK_COUNTER, "3")
61 | TEST_EXPANDS(HACK_COUNTER_VALUE, "4")
62 |
63 | /* When `HACK_COUNTER' isn't actually expanded, then the tpp_exec
64 | * code mustn't get executed (since it's skipped in its entirety).
65 | * Assert this fact! */
66 | #define HIDE(x)
67 | HIDE(HACK_COUNTER)
68 | HIDE(HACK_COUNTER)
69 | HIDE(HACK_COUNTER)
70 |
71 | TEST_EXPANDS(HACK_COUNTER_VALUE, "4")
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/test/traditional_macros.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #define CAT(a,b) a ## b
23 | #define STR(x) #x
24 |
25 | /* Enabling "-ftraditional-macro" alters macro definitions
26 | * to follow more ~traditional~ expansion rules. */
27 | #pragma extension(push, "-ftraditional-macro")
28 | #define T_CAT(a, b) a/**/b
29 | #define T_STR(x) "x"
30 | #pragma extension(pop)
31 |
32 | #define N_CAT(a, b) a/**/b
33 | #define N_STR(x) "x"
34 |
35 | TEST_EXPANDS(CAT(10, 20), "1020")
36 | TEST_EXPANDS(STR(10), "\"10\"")
37 | TEST_EXPANDS(T_CAT(10, 20), "1020")
38 | TEST_EXPANDS(T_STR(10), "\"10\"")
39 | TEST_EXPANDS(N_CAT(10, 20), "10/**/20")
40 | TEST_EXPANDS(N_STR(10), "\"x\"")
41 |
--------------------------------------------------------------------------------
/test/undef_current_macro.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | /* This used to cause TPP to crash, but has since been fixed */
23 | #define foo(x) x
24 | foo(__pragma(tpp_exec("#undef foo\n")))
25 |
--------------------------------------------------------------------------------
/test/undef_macro_cexpr.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // #undef macro in constant expression
23 |
24 | #pragma warning("-Wundef")
25 |
26 | #undef FOOBAR
27 | PRAGMA_WARNING_PUSH_SUPPRESS("undef")
28 | #if FOOBAR // WARNING: Unexpected token "FOOBAR" replaced with "0"
29 | #endif
30 | PRAGMA_WARNING_POP_SUPPRESS("undef")
31 |
32 | #if defined(FOOBAR2) && never // Shouldn't result in a warning
33 | #endif
34 | #if 0 && ladidadida // Shouldn't result in a warning
35 | #endif
36 |
37 |
38 |
--------------------------------------------------------------------------------
/test/user_error.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | /* Both #warning and #error directives should produce -Wuser warnings.
23 | * Note that despite the name, `#error' still produces a warning, only
24 | * that this warning is normally set-up to be fatal, whilst #warning
25 | * is normally set-up to be non-fatal. */
26 | PRAGMA_WARNING_PUSH_SUPPRESS("user")
27 | #warning User Warning
28 | PRAGMA_WARNING_POP_SUPPRESS("user")
29 |
30 | PRAGMA_WARNING_PUSH_SUPPRESS("user")
31 | #error User Error
32 | PRAGMA_WARNING_POP_SUPPRESS("user")
33 |
34 |
--------------------------------------------------------------------------------
/test/varargs_empty.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #define foo(a, ...) a(__VA_ARGS__)
23 |
24 | TEST_EXPANDS(foo(), "()")
25 | TEST_EXPANDS(foo( ), "()")
26 | TEST_EXPANDS(foo(func), "func()")
27 | TEST_EXPANDS(foo(func,), "func()")
28 | TEST_EXPANDS(foo(func, ), "func()")
29 | TEST_EXPANDS(foo(func,b), "func(b)")
30 | TEST_EXPANDS(foo(func, b ), "func(b)")
31 |
32 |
--------------------------------------------------------------------------------
/test/varargs_named.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // named_va_args
23 |
24 | #define named_varargs(args...) args
25 | TEST_EXPANDS(named_varargs(),"")
26 | TEST_EXPANDS(named_varargs(,),",")
27 | TEST_EXPANDS(named_varargs(10),"10")
28 | TEST_EXPANDS(named_varargs(10,20),"10,20")
29 |
--------------------------------------------------------------------------------
/test/varargs_va_comma.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | // Function-style macro calling and argument count
23 |
24 | #define arg0() -
25 | #define arg1(a) a
26 | #define arg2(a,b) a##b
27 | #define varg0(...) __VA_ARGS__
28 | #define varg1(a,...) a##__VA_ARGS__
29 | #define varg2(a,b,...) a##b##__VA_ARGS__
30 | #define vcarg0(...) __VA_COMMA__ __VA_ARGS__ __VA_COMMA__
31 | #define vcarg1(a,...) __VA_COMMA__ a##__VA_ARGS__ __VA_COMMA__
32 | #define vcarg2(a,b,...) __VA_COMMA__ a##b##__VA_ARGS__ __VA_COMMA__
33 |
34 | // NOTE: Space tokens [ ] are not included in the expansion comments
35 | TEST_EXPANDS(arg0(),"-") // OK
36 |
37 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
38 | TEST_EXPANDS(arg0(a),"-") // WARNING: Invalid argument count (expected 0)
39 | PRAGMA_WARNING_POP_SUPPRESS("macros")
40 |
41 | TEST_EXPANDS(arg1(),"") // OK
42 | TEST_EXPANDS(arg1(a),"a") // OK
43 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
44 | TEST_EXPANDS(arg1(a,b),"a,b") // WARNING: Invalid argument count (expected 1)
45 | PRAGMA_WARNING_POP_SUPPRESS("macros")
46 |
47 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
48 | TEST_EXPANDS(arg1(,),",") // WARNING: Invalid argument count (expected 1)
49 | PRAGMA_WARNING_POP_SUPPRESS("macros")
50 |
51 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
52 | TEST_EXPANDS(arg2(a),"a") // WARNING: Invalid argument count (expected 2)
53 | PRAGMA_WARNING_POP_SUPPRESS("macros")
54 |
55 | TEST_EXPANDS(arg2(a,),"a") // OK
56 | TEST_EXPANDS(arg2(,),"") // OK
57 | TEST_EXPANDS(arg2(a,b),"ab") // OK
58 |
59 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
60 | TEST_EXPANDS(arg2(,,),",") // WARNING: Invalid argument count (expected 2)
61 | PRAGMA_WARNING_POP_SUPPRESS("macros")
62 |
63 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
64 | TEST_EXPANDS(arg2(a,b,c),"ab,c") // WARNING: Invalid argument count (expected 2)
65 | PRAGMA_WARNING_POP_SUPPRESS("macros")
66 |
67 | TEST_EXPANDS(varg0(),"") // OK
68 | TEST_EXPANDS(varg0(a),"a") // OK
69 | TEST_EXPANDS(varg0(a,),"a,") // OK
70 | TEST_EXPANDS(varg0(,),",") // OK
71 | TEST_EXPANDS(varg0(a,b),"a,b") // OK
72 | TEST_EXPANDS(vcarg0(),"") // OK
73 | TEST_EXPANDS(vcarg0(a),", a ,") // OK
74 | TEST_EXPANDS(vcarg0(a,),", a, ,") // OK
75 | TEST_EXPANDS(vcarg0(,),", , ,") // OK
76 | TEST_EXPANDS(vcarg0(a,b),", a,b ,") // OK
77 | TEST_EXPANDS(varg1(),"") // OK
78 | TEST_EXPANDS(varg1(a),"a") // OK
79 | TEST_EXPANDS(varg1(a,),"a") // OK
80 | TEST_EXPANDS(varg1(,),"") // OK
81 | TEST_EXPANDS(varg1(a,b),"ab") // OK
82 | TEST_EXPANDS(vcarg1(),"") // OK
83 | TEST_EXPANDS(vcarg1(a),"a") // OK
84 | TEST_EXPANDS(vcarg1(a,),"a") // OK
85 | TEST_EXPANDS(vcarg1(,),"") // OK
86 | TEST_EXPANDS(vcarg1(a,b),", ab ,") // OK
87 |
88 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
89 | TEST_EXPANDS(varg2(a),"a") // WARNING: Invalid argument count (expected >= 2)
90 | PRAGMA_WARNING_POP_SUPPRESS("macros")
91 |
92 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
93 | TEST_EXPANDS(varg2(),"") // WARNING: Invalid argument count (expected >= 2)
94 | PRAGMA_WARNING_POP_SUPPRESS("macros")
95 |
96 | TEST_EXPANDS(varg2(a,),"a") // OK
97 | TEST_EXPANDS(varg2(,),"") // OK
98 | TEST_EXPANDS(varg2(a,b),"ab") // OK
99 |
100 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
101 | TEST_EXPANDS(vcarg2(),"") // WARNING: Invalid argument count (expected >= 2)
102 | PRAGMA_WARNING_POP_SUPPRESS("macros")
103 |
104 | PRAGMA_WARNING_PUSH_SUPPRESS("macros")
105 | TEST_EXPANDS(vcarg2(a),"a") // WARNING: Invalid argument count (expected >= 2)
106 | PRAGMA_WARNING_POP_SUPPRESS("macros")
107 |
108 | TEST_EXPANDS(vcarg2(a,),"a") // OK
109 | TEST_EXPANDS(vcarg2(,),"") // OK
110 | TEST_EXPANDS(vcarg2(a,b),"ab") // OK
111 |
112 |
--------------------------------------------------------------------------------
/test/varargs_va_nargs.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #define nargs(...) __VA_NARGS__
23 |
24 | /* __VA_NARGS__ expands to the decimal repr of the # of variadic arguments */
25 | TEST_EXPANDS(nargs(), "0")
26 | TEST_EXPANDS(nargs( ), "0")
27 | TEST_EXPANDS(nargs(~), "1")
28 | TEST_EXPANDS(nargs(,), "2")
29 | TEST_EXPANDS(nargs(a,), "2")
30 | TEST_EXPANDS(nargs(a,b), "2")
31 |
32 |
33 | /* Using __VA_NARGS__, you can _very_ easily overload macros by argument count! */
34 | #define myfunc_0() no arguments
35 | #define myfunc_1(a) first argument is
36 | #define myfunc_2(a, b) first argument: ; and second is
37 | #define myfunc(...) myfunc_##__VA_NARGS__(__VA_ARGS__)
38 |
39 | TEST_EXPANDS(myfunc(), "no arguments")
40 | TEST_EXPANDS(myfunc( ), "no arguments")
41 | TEST_EXPANDS(myfunc("Hello"), "first argument is <\"Hello\">")
42 | TEST_EXPANDS(myfunc("Hello", "World"), "first argument: <\"Hello\">; and second is <\"World\">")
43 |
44 | #define nargs1(a, ...) a __VA_NARGS__
45 | TEST_EXPANDS(nargs1(), "0")
46 | TEST_EXPANDS(nargs1( ), "0")
47 | TEST_EXPANDS(nargs1(~), "~ 0")
48 | TEST_EXPANDS(nargs1(,), "0")
49 | TEST_EXPANDS(nargs1(, ), "0")
50 | TEST_EXPANDS(nargs1(a,), "a 0")
51 | TEST_EXPANDS(nargs1(a,b), "a 1")
52 |
53 |
--------------------------------------------------------------------------------
/test/varargs_va_opt.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017-2023 Griefer@Work *
2 | * *
3 | * This software is provided 'as-is', without any express or implied *
4 | * warranty. In no event will the authors be held liable for any damages *
5 | * arising from the use of this software. *
6 | * *
7 | * Permission is granted to anyone to use this software for any purpose, *
8 | * including commercial applications, and to alter it and redistribute it *
9 | * freely, subject to the following restrictions: *
10 | * *
11 | * 1. The origin of this software must not be misrepresented; you must not *
12 | * claim that you wrote the original software. If you use this software *
13 | * in a product, an acknowledgement (see the following) in the product *
14 | * documentation is required: *
15 | * Portions Copyright (c) 2017-2023 Griefer@Work *
16 | * 2. Altered source versions must be plainly marked as such, and must not be *
17 | * misrepresented as being the original software. *
18 | * 3. This notice may not be removed or altered from any source distribution. *
19 | */
20 | #include "include/test.h"
21 |
22 | #define foo(...) a __VA_OPT__ (b) c
23 |
24 | TEST_EXPANDS(foo(), "a c")
25 | TEST_EXPANDS(foo( ), "a c")
26 | TEST_EXPANDS(foo(a), "a b c")
27 |
28 |
--------------------------------------------------------------------------------