Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 11 additions & 28 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
PROJECT_NAME: Caprica
CMAKE_ARGS: "-DCHAMPOLLION_USE_STATIC_RUNTIME:BOOL=TRUE -DENABLE_STATIC_RUNTIME:BOOL=TRUE -DCMAKE_INSTALL_PREFIX:STRING=build/extern -DVCPKG_TARGET_TRIPLET:STRING=x64-windows-static -DCMAKE_TOOLCHAIN_FILE:STRING=C:/vcpkg/scripts/buildsystems/vcpkg.cmake"

jobs:
build:
Expand All @@ -23,40 +22,24 @@ jobs:

steps:
- uses: actions/checkout@v3

- name: Setup vcpkg
working-directory: c:/
run: |
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
bootstrap-vcpkg.bat
vcpkg.exe integrate install
- uses: lukka/get-cmake@latest

- name: Cache vcpkg packages
uses: actions/cache@v3
with:
path: ${{github.workspace}}/build/vcpkg_installed
key: ${{ runner.os }}-vcpkg-${{ hashFiles('${{github.workspace}}/vcpkg.json') }}
restore-keys: |
${{ runner.os }}-vcpkg-${{ hashFiles('${{github.workspace}}/vcpkg.json') }}
${{ runner.os }}-vcpkg-

- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCAPRICA_USE_STATIC_RUNTIME:BOOL=TRUE -DENABLE_STATIC_RUNTIME:BOOL=TRUE -DCMAKE_INSTALL_PREFIX:STRING=build/extern -DVCPKG_TARGET_TRIPLET:STRING=x64-windows-static -DCMAKE_TOOLCHAIN_FILE:STRING=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Setup vcpkg (without building packages)
uses: lukka/run-vcpkg@v11

- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Run CMake in accordance with CMakePreset.json and run vcpkg
uses: lukka/run-cmake@v10
with:
configurePreset: build-release-msvc
buildPreset: release-msvc

- name: Upload a Build Artifact
uses: actions/upload-artifact@v3.1.2
uses: actions/upload-artifact@v4
with:
# Artifact name
name: ${{ env.PROJECT_NAME }}
# A file, directory or wildcard pattern that describes what to upload
path: build/Caprica/Release/Caprica.exe
path: build/extern/Caprica/Caprica.exe
# The desired behavior if no files are found using the provided path.
retention-days: 90

Expand All @@ -69,7 +52,7 @@ jobs:
needs: build
steps:
- name: Download artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: ${{ env.PROJECT_NAME }}
path: artifacts/${{ env.PROJECT_NAME }}
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ Caprica/INSTALL.vcxproj.filters
Caprica/cmake_install.cmake

x64/
/out/install/x64-Debug/bin
/CMakeSettings.json
106 changes: 106 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
{
"version": 8,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21,
"patch": 0
},
"configurePresets": [
{
"name": "base",
"hidden": true,
"cacheVariables": {
"CAPRICA_USE_STATIC_RUNTIME": {
"type": "BOOL",
"value": "TRUE"
},
"ENABLE_STATIC_RUNTIME": {
"type": "BOOL",
"value": "TRUE"
},
"CMAKE_CXX_FLAGS": "$env{CPP_COMPILER}"
}
},
{
"name": "vcpkg",
"hidden": true,
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
"VCPKG_TARGET_TRIPLET": "x64-windows-static"
}
},
{
"name": "x64",
"hidden": true,
"architecture": {
"value": "x64",
"strategy": "external"
}
},
{
"name": "msvc",
"hidden": true,
"environment": {
"CPP_COMPILER": "/permissive- /Zc:preprocessor /EHsc $penv{CXXFLAGS}"
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"intelliSenseMode": "windows-msvc-x64",
"enableMicrosoftCodeAnalysis": true,
"enableClangTidyCodeAnalysis": true
}
}
},
{
"name": "build-release-msvc",
"inherits": [
"base",
"vcpkg",
"x64",
"msvc"
],
"displayName": "Release",
"description": "Optimized release Build.",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/extern",
"cacheVariables": {
"CMAKE_BUILD_TYPE": {
"type": "STRING",
"value": "RelWithDebInfo"
}
}
},
{
"name": "build-debug-msvc",
"inherits": [
"base",
"vcpkg",
"x64",
"msvc"
],
"displayName": "Debug",
"description": "Debug build for testing.",
"binaryDir": "${sourceDir}/build/debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": {
"type": "STRING",
"value": "Debug"
}
}
}
],
"buildPresets": [
{
"name": "release-msvc",
"displayName": "Release (MSVC)",
"configurePreset": "build-release-msvc",
"description": "Optimized release Build."
},
{
"name": "debug-msvc",
"displayName": "Debug (MSVC)",
"configurePreset": "build-debug-msvc",
"description": "Debug build for local testing."
}
]
}
2 changes: 1 addition & 1 deletion Caprica/common/CapricaInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ PCompInputFile::PCompInputFile(const std::filesystem::path& _path,
bool isFolder,
const std::filesystem::path& _cwd)
: IInputFile(_path, noRecurse, _cwd) {
isFolder = isFolder;
this->isFolder = isFolder;
}

bool PCompInputFile::resolve() {
Expand Down
7 changes: 7 additions & 0 deletions Caprica/common/CapricaReportingContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ struct CapricaReportingContext final {
identifier_ref,
parentName)

// Not a base game warning, but some ubiquitous libraries fall prey to this.
DEFINE_WARNING_A1(1006,
Strict_Keyword_Identifiers,
"'{}' is a keyword (e.g. Int, Function) but is used as an identifier.",
identifier_ref,
idName)

// Warnings 2000-2199 are for engine imposed limitations.

DEFINE_WARNING_A2(2001,
Expand Down
6 changes: 5 additions & 1 deletion Caprica/main_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,9 @@ bool parseCommandLineArguments(int argc, char* argv[], caprica::CapricaJobManage
"Ensure values returned from BetaOnly and DebugOnly functions don't escape, as that will cause invalid code generation.")
("disable-implicit-conversion-from-none", po::bool_switch()->default_value(false),
"Disable implicit conversion from None in most situations where the use of None likely wasn't the author's intention.")
("skyrim-allow-unknown-events-on-non-native-class", po::value<bool>(&conf::Skyrim::skyrimAllowUnknownEventsOnNonNativeClass)->default_value(false),
("disable-keywords-as-identifiers", po::bool_switch()->default_value(false),
"Disable the ability to use some keywords (e.g. Switch, Parent) as identifiers in select cases.")
("skyrim-allow-unknown-events-on-non-native-class", po::value<bool>(&conf::Skyrim::skyrimAllowUnknownEventsOnNonNativeClass)->default_value(true),
"Allow unknown events to be defined on non-native classes. This is encountered with some scripts in the base game having Events that are not present on ObjectReference.");

po::options_description skyrimCompatibilityDesc("Skyrim compatibility (default true with '--game=skyrim')");
Expand Down Expand Up @@ -560,6 +562,8 @@ bool parseCommandLineArguments(int argc, char* argv[], caprica::CapricaJobManage
conf::Warnings::warningsToHandleAsErrors.insert(1002);
} else if (vm["disable-implicit-conversion-from-none"].as<bool>()) {
conf::Warnings::warningsToHandleAsErrors.insert(1003);
} else if (vm["disable-keywords-as-identifiers"].as<bool>()) {
conf::Warnings::warningsToHandleAsErrors.insert(1006);
}

if (vm.count("disable-warning")) {
Expand Down
3 changes: 2 additions & 1 deletion Caprica/papyrus/PapyrusCompilationContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ std::string_view findScriptName(const std::string_view& data, const std::string_
next = data.size() - 1;
auto line = data.substr(last, next - last);
auto begin = line.find_first_not_of(" \t");
if (strnicmp(line.substr(begin, startstring.size()).data(), startstring.data(), startstring.size()) == 0) {
auto startSize = startstring.size();
if (line.size() > startSize && strnicmp(line.substr(begin, startSize).data(), startstring.data(), startSize) == 0) {
auto first = line.find_first_not_of(" \t", startstring.size() + begin);
return line.substr(first, line.find_first_of(" \t", first) - first);
}
Expand Down
19 changes: 19 additions & 0 deletions Caprica/papyrus/parser/PapyrusLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,25 @@ static const caseless_unordered_identifier_ref_map<TokenType> languageExtensions
{ "to", TokenType::kTo },
};

// keywords which can never pass as identifiers
static const std::unordered_set<TokenType> nonIdentifiersSet {
TokenType::kAuto,
TokenType::kAutoReadOnly,
TokenType::kBool,
TokenType::kConst,
TokenType::kFalse,
TokenType::kFloat,
TokenType::kInt,
TokenType::kNone,
TokenType::kString,
TokenType::kStruct,
TokenType::kVar,
};

const bool keywordCanBeIdentifier(TokenType tp) {
return keywordIsInGame(tp, conf::Papyrus::game, true) && nonIdentifiersSet.find(tp) == nonIdentifiersSet.end();
}

ALWAYS_INLINE
static bool isAsciiAlphaNumeric(int c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9');
Expand Down
1 change: 1 addition & 0 deletions Caprica/papyrus/parser/PapyrusLexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ constexpr TokenType STARFIELD_MAX_KEYWORD = TokenType::kTryGuard;
constexpr bool keywordIsLanguageExtension(TokenType tp) {
return tp >= TokenType::kBreak && tp <= TokenType::kTo;
}
const bool keywordCanBeIdentifier(TokenType tp);
constexpr bool keywordIsInGame(TokenType tp, GameID game, bool includeExtensions = false) {
if (includeExtensions && keywordIsLanguageExtension(tp))
return true;
Expand Down
22 changes: 21 additions & 1 deletion Caprica/papyrus/parser/PapyrusParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ PapyrusFunction* PapyrusParser::parseFunction(

auto param =
alloc->make<PapyrusFunctionParameter>(cur.location, func->parameters.size(), expectConsumePapyrusType());
param->name = expectConsumeIdentRef();
param->name = expectConsumeKeywordOrIdentRef();
if (maybeConsume(TokenType::Equal))
param->defaultValue = expectConsumePapyrusValue();
func->parameters.push_back(param);
Expand Down Expand Up @@ -1176,6 +1176,26 @@ expressions::PapyrusExpression* PapyrusParser::parseFuncOrIdExpression(PapyrusFu
}
}

identifier_ref PapyrusParser::expectConsumeKeywordOrIdentRef() {
if (!keywordCanBeIdentifier(cur.type)) {
reportingContext.fatal(cur.location,
"Syntax error! Expected valid identifier, got '{}'.",
cur.prettyString());
}

identifier_ref finalId;

if (cur.type != TokenType::Identifier) {
const identifier_ref typeIdentifier = identifier_ref(PapyrusLexer::Token::prettyTokenType(cur.type));
reportingContext.warning_W1006_Strict_Keyword_Identifiers(cur.location, typeIdentifier);
finalId = typeIdentifier;
} else {
finalId = cur.val.s;
}
consume();
return finalId;
}

PapyrusType PapyrusParser::expectConsumePapyrusType() {
PapyrusType tp = PapyrusType::Default();
switch (cur.type) {
Expand Down
1 change: 1 addition & 0 deletions Caprica/papyrus/parser/PapyrusParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct PapyrusParser final : private PapyrusLexer {

PapyrusType expectConsumePapyrusType();
PapyrusValue expectConsumePapyrusValue();
identifier_ref expectConsumeKeywordOrIdentRef();
PapyrusUserFlags maybeConsumeUserFlags(CapricaUserFlagsDefinition::ValidLocations location);

ALWAYS_INLINE
Expand Down
27 changes: 27 additions & 0 deletions vcpkg-configuration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"default-registry": {
"kind": "git",
"repository": "https://github.com/Microsoft/vcpkg",
"baseline": "3508985146f1b1d248c67ead13f8f54be5b4f5da"
},
"registries": [
{
"kind": "git",
"repository": "https://github.com/microsoft/vcpkg",
"baseline": "caa7579a1c48e2ca770f6ccf98cb03db95642631",
"packages": [ "boost*", "boost-*" ]
},
{
"kind": "git",
"repository": "https://github.com/microsoft/vcpkg",
"baseline": "7ef729383ab801504035a4445b6dbca18c8865c8",
"packages": [ "boost-modular-build-helper" ]
},
{
"kind": "git",
"repository": "https://github.com/microsoft/vcpkg",
"baseline": "4cb4a5c5ddcb9de0c83c85837ee6974c8333f032",
"packages": [ "fmt" ]
}
]
}
21 changes: 0 additions & 21 deletions vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,6 @@
"dependencies": [
"boost-container"
],
"vcpkg-configuration": {
"default-registry": {
"kind": "git",
"repository": "https://github.com/Microsoft/vcpkg",
"baseline": "4cb4a5c5ddcb9de0c83c85837ee6974c8333f032"
},
"registries": [
{
"kind": "git",
"repository": "https://github.com/microsoft/vcpkg",
"baseline": "7ef729383ab801504035a4445b6dbca18c8865c8",
"packages": [ "boost-modular-build-helper" ]
},
{
"kind": "git",
"repository": "https://github.com/microsoft/vcpkg",
"baseline": "caa7579a1c48e2ca770f6ccf98cb03db95642631",
"packages": [ "boost*", "boost-*" ]
}
]
},
"features": {
"standalone": {
"description": "Build as a standalone program",
Expand Down
Loading