Skip to content

Commit

Permalink
Added detection of runtime macros
Browse files Browse the repository at this point in the history
Added logger
Switched to C++20
Fixes #6
  • Loading branch information
dedmen committed Feb 13, 2024
1 parent 5005623 commit f2ea896
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 10 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ message("COMPILER USED: '${CMAKE_CXX_COMPILER_ID}'")

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/release")

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ Create `sqfc.json` in current working directory
"workerThreads": 8,
"rootPathMappings": [
["T:/", "\\"]
]
],
"logging": {
"verbose": false
}
}
```
16 changes: 16 additions & 0 deletions src/logger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "logger.hpp"
#include <mutex>
#include <iostream>


std::mutex loggerMutex;

void LoggerBogger::Log(LogLevel level, const std::string& msg)
{
if (level == LogLevel::Verbose && !m_EnableVerbose)
return;

std::lock_guard m(loggerMutex);

std::cout << msg.c_str() << "\n";
}
22 changes: 22 additions & 0 deletions src/logger.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once
#include <string>

enum class LogLevel
{
Normal,
Verbose
};

class LoggerBogger // Weird name because SQF-VM also has class Logger, without namespace (most of its stuff is in namespace, just not that)
{
public:
//#TODO in-place formatting, vsnprintf
//#TODO multithreading queue instead of locking

//! This function might be hit by multiple threads
void Log(LogLevel level, const std::string& msg);

bool m_EnableVerbose = false;
};

inline LoggerBogger GLogger;
12 changes: 10 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <json.hpp>
#include "luaHandler.hpp"
#include "logger.hpp"

std::queue<std::filesystem::path> tasks;
std::mutex taskMutex;
Expand Down Expand Up @@ -149,8 +150,6 @@ int main(int argc, char* argv[]) {
return 0; //#TODO return real error state if any script failed
}



if (!std::filesystem::exists("sqfc.json")) {
std::cout << "Missing sqfc.json in current working directory" << "\n";
return 1;
Expand Down Expand Up @@ -205,6 +204,15 @@ int main(int argc, char* argv[]) {
}
}

// Logging


if (auto loggingConfig = json["logging"]; !loggingConfig.is_null())
{
if (auto verboseCfg = loggingConfig["verbose"]; verboseCfg.is_boolean())
GLogger.m_EnableVerbose = verboseCfg;
}



// Setup workers
Expand Down
72 changes: 67 additions & 5 deletions src/scriptCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include <iostream>
#include <mutex>
#include <format>
#include "logger.hpp"
#include "optimizer/optimizerModuleBase.hpp"
#include "optimizer/optimizer.h"
#include "scriptSerializer.hpp"
Expand All @@ -15,6 +17,7 @@
#include "parser/preprocessor/default.h"
#include "parser/sqf/parser.tab.hh"
#include "runtime/d_string.h"
#include "runtime/logging.h"

std::once_flag commandMapInitFlag;

Expand Down Expand Up @@ -61,10 +64,70 @@ void ScriptCompiler::init()
const ::sqf::runtime::diagnostics::diag_info dinf,
const ::sqf::runtime::fileio::pathinfo location,
const std::string& data) -> std::string
{
ignoreCurrentFile = true;
return {}; // string return type is wrong, isn't used for anything
} });
{
if (ignoreCurrentFile)
return {};

GLogger.Log(LogLevel::Verbose, std::format("File '{}' skipped because it uses pragma ASC_ignoreFile", location.virtual_));

ignoreCurrentFile = true;
return {}; // string return type is wrong, isn't used for anything
} });

// Handle macros that must be resolved at game start time and cannot be precompiled
auto runtimeMacroCallback = [this](const sqf::runtime::parser::macro& m,
const ::sqf::runtime::diagnostics::diag_info dinf,
const ::sqf::runtime::fileio::pathinfo location,
const std::vector<std::string>& params,
::sqf::runtime::runtime& runtime) -> std::string
{
if (ignoreCurrentFile)
return {};

GLogger.Log(LogLevel::Verbose, std::format("File '{}' skipped because it uses runtime-only macro '{}'", location.virtual_, m.name()));

ignoreCurrentFile = true;
return {};
};

// https://community.bistudio.com/wiki/PreProcessor_Commands#has_include
for (auto& it : {
"__has_include",
"__DATE_ARR__",
"__DATE_STR__",
"__DATE_STR_ISO8601__",
"__TIME__",
"__TIME_UTC__",
"__DAY__",
"__MONTH__",
"__YEAR__",
"__TIMESTAMP_UTC__",

// We could support these, shouldn't make a different, random number is random
"__RAND_INT8__",
"__RAND_INT16__",
"__RAND_INT32__",
"__RAND_INT64__",
"__RAND_UINT8__",
"__RAND_UINT16__",
"__RAND_UINT32__",
"__RAND_UINT64__"
// SQF-VM supports these, but it sets wrong values. We want runtime ones.
"__GAME_VER__",
"__GAME_VER_MAJ__",
"__GAME_VER_MIN__",
"__GAME_BUILD__",

"__A3_DIAG__",
"__A3_DEBUG__",
"__A3_EXPERIMENTAL__",
"__A3_PROFILING__"
})
addMacro({ it, runtimeMacroCallback });

addMacro({ "__ARMA__", "1" }); // Only A3 has bytecode
addMacro({ "__ARMA3__", "1" }); // Only A3 has bytecode

}

ScriptCompiler::ScriptCompiler(const std::vector<std::filesystem::path>& includePaths) {
Expand Down Expand Up @@ -116,7 +179,6 @@ CompiledCodeData ScriptCompiler::compileScript(std::filesystem::path physicalPat

if (ignoreCurrentFile)
{
std::cout << "File " << physicalPath.generic_string() << " skipped due to ASC_ignoreFile pragma\n";
ignoreCurrentFile = false;
return CompiledCodeData();
}
Expand Down
3 changes: 2 additions & 1 deletion src/scriptSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,10 @@ void ScriptSerializer::compiledToBinaryCompressed(const CompiledCodeData& code,

template<typename CharT, typename TraitsT = std::char_traits<CharT> >
class vectorwrapbuf : public std::basic_streambuf<CharT, TraitsT> {
using base = std::basic_streambuf<CharT, TraitsT>;
public:
vectorwrapbuf(std::vector<CharT>& vec) {
setg(vec.data(), vec.data(), vec.data() + vec.size());
base::setg(vec.data(), vec.data(), vec.data() + vec.size());
}
};

Expand Down

0 comments on commit f2ea896

Please sign in to comment.