|
5 | 5 |
|
6 | 6 | #include <iostream> |
7 | 7 | #include <mutex> |
| 8 | +#include <format> |
| 9 | +#include "logger.hpp" |
8 | 10 | #include "optimizer/optimizerModuleBase.hpp" |
9 | 11 | #include "optimizer/optimizer.h" |
10 | 12 | #include "scriptSerializer.hpp" |
|
15 | 17 | #include "parser/preprocessor/default.h" |
16 | 18 | #include "parser/sqf/parser.tab.hh" |
17 | 19 | #include "runtime/d_string.h" |
| 20 | +#include "runtime/logging.h" |
18 | 21 |
|
19 | 22 | std::once_flag commandMapInitFlag; |
20 | 23 |
|
@@ -61,10 +64,70 @@ void ScriptCompiler::init() |
61 | 64 | const ::sqf::runtime::diagnostics::diag_info dinf, |
62 | 65 | const ::sqf::runtime::fileio::pathinfo location, |
63 | 66 | const std::string& data) -> std::string |
64 | | - { |
65 | | - ignoreCurrentFile = true; |
66 | | - return {}; // string return type is wrong, isn't used for anything |
67 | | - } }); |
| 67 | + { |
| 68 | + if (ignoreCurrentFile) |
| 69 | + return {}; |
| 70 | + |
| 71 | + GLogger.Log(LogLevel::Verbose, std::format("File '{}' skipped because it uses pragma ASC_ignoreFile", location.virtual_)); |
| 72 | + |
| 73 | + ignoreCurrentFile = true; |
| 74 | + return {}; // string return type is wrong, isn't used for anything |
| 75 | + } }); |
| 76 | + |
| 77 | + // Handle macros that must be resolved at game start time and cannot be precompiled |
| 78 | + auto runtimeMacroCallback = [this](const sqf::runtime::parser::macro& m, |
| 79 | + const ::sqf::runtime::diagnostics::diag_info dinf, |
| 80 | + const ::sqf::runtime::fileio::pathinfo location, |
| 81 | + const std::vector<std::string>& params, |
| 82 | + ::sqf::runtime::runtime& runtime) -> std::string |
| 83 | + { |
| 84 | + if (ignoreCurrentFile) |
| 85 | + return {}; |
| 86 | + |
| 87 | + GLogger.Log(LogLevel::Verbose, std::format("File '{}' skipped because it uses runtime-only macro '{}'", location.virtual_, m.name())); |
| 88 | + |
| 89 | + ignoreCurrentFile = true; |
| 90 | + return {}; |
| 91 | + }; |
| 92 | + |
| 93 | + // https://community.bistudio.com/wiki/PreProcessor_Commands#has_include |
| 94 | + for (auto& it : { |
| 95 | + "__has_include", |
| 96 | + "__DATE_ARR__", |
| 97 | + "__DATE_STR__", |
| 98 | + "__DATE_STR_ISO8601__", |
| 99 | + "__TIME__", |
| 100 | + "__TIME_UTC__", |
| 101 | + "__DAY__", |
| 102 | + "__MONTH__", |
| 103 | + "__YEAR__", |
| 104 | + "__TIMESTAMP_UTC__", |
| 105 | + |
| 106 | + // We could support these, shouldn't make a different, random number is random |
| 107 | + "__RAND_INT8__", |
| 108 | + "__RAND_INT16__", |
| 109 | + "__RAND_INT32__", |
| 110 | + "__RAND_INT64__", |
| 111 | + "__RAND_UINT8__", |
| 112 | + "__RAND_UINT16__", |
| 113 | + "__RAND_UINT32__", |
| 114 | + "__RAND_UINT64__" |
| 115 | + // SQF-VM supports these, but it sets wrong values. We want runtime ones. |
| 116 | + "__GAME_VER__", |
| 117 | + "__GAME_VER_MAJ__", |
| 118 | + "__GAME_VER_MIN__", |
| 119 | + "__GAME_BUILD__", |
| 120 | + |
| 121 | + "__A3_DIAG__", |
| 122 | + "__A3_DEBUG__", |
| 123 | + "__A3_EXPERIMENTAL__", |
| 124 | + "__A3_PROFILING__" |
| 125 | + }) |
| 126 | + addMacro({ it, runtimeMacroCallback }); |
| 127 | + |
| 128 | + addMacro({ "__ARMA__", "1" }); // Only A3 has bytecode |
| 129 | + addMacro({ "__ARMA3__", "1" }); // Only A3 has bytecode |
| 130 | + |
68 | 131 | } |
69 | 132 |
|
70 | 133 | ScriptCompiler::ScriptCompiler(const std::vector<std::filesystem::path>& includePaths) { |
@@ -116,7 +179,6 @@ CompiledCodeData ScriptCompiler::compileScript(std::filesystem::path physicalPat |
116 | 179 |
|
117 | 180 | if (ignoreCurrentFile) |
118 | 181 | { |
119 | | - std::cout << "File " << physicalPath.generic_string() << " skipped due to ASC_ignoreFile pragma\n"; |
120 | 182 | ignoreCurrentFile = false; |
121 | 183 | return CompiledCodeData(); |
122 | 184 | } |
|
0 commit comments