Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# User files
*.user

# Prerequisites
*.d

Expand Down
51 changes: 49 additions & 2 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def buildStepDocker() {
def split_job_name = env.JOB_NAME.split(/\/{1}/);
def fixed_job_name = split_job_name[1].replace('%2F',' ');

def customImage = docker.image("mcr.microsoft.com/dotnet/sdk:9.0");
def customImage = docker.image("mcr.microsoft.com/dotnet/sdk:10.0");
customImage.pull();

try {
Expand Down Expand Up @@ -138,6 +138,53 @@ def buildStepDocker() {
}
}
}

stage("Run tests...") {
customImage.inside("-u 0") {
dir("bindings/dotnet/") {
try{
sh("dotnet test -c Debug -r linux-x64 --logger \"trx;LogFileName=../../Testing/unit_tests.xml\"");
sh("dotnet test -c Debug -r linux-x64 /p:CollectCoverage=true /p:CoverletOutputFormat=opencover");
sh("chmod 777 -R .");
} catch(err) {
currentBuild.result = 'FAILURE'
sh("chmod 777 -R .");
discordSend(description: "Testing Failed: ${fixed_job_name} #${env.BUILD_NUMBER}", footer: "", link: env.BUILD_URL, result: currentBuild.currentResult, title: "[${split_job_name[0]}] Tests Failed: ${fixed_job_name} #${env.BUILD_NUMBER}", webhookURL: env.GS2EMU_WEBHOOK);
notify('Build failed')
}

archiveArtifacts (
artifacts: 'Testing/**.xml',
fingerprint: true
)

/* TODO: Enable when codecov is added to GS2Compiler project
withCredentials([string(credentialsId: 'PREAGONAL_GS2ENGINE_CODECOV_TOKEN', variable: 'CODECOV_TOKEN')]) {
sh("curl -s https://codecov.io/bash > codecov && chmod +x codecov && ./codecov -f \"Testing/unit_tests.xml\" -t ${env.CODECOV_TOKEN} && ./codecov -f \"Preagonal.Scripting.GS2Compiler.UnitTests/coverage.opencover.xml\" -t ${env.CODECOV_TOKEN}")
}
*/

stage("Xunit") {
xunit (
testTimeMargin: '3000',
thresholdMode: 1,
thresholds: [
skipped(failureThreshold: '1000'),
failed(failureThreshold: '0')
],
tools: [MSTest(
pattern: 'Testing/**.xml',
deleteOutputFiles: true,
failIfNotNew: false,
skipNoTestFiles: true,
stopProcessingIfError: true
)],
skipPublishingChecks: false
);
}
}
}
}

def archive_date = sh (
script: 'date +"-%Y%m%d-%H%M"',
Expand Down Expand Up @@ -266,7 +313,7 @@ killall_jobs();

parallel(branches);

def customImage = docker.image("mcr.microsoft.com/dotnet/sdk:9.0");
def customImage = docker.image("mcr.microsoft.com/dotnet/sdk:10.0");
customImage.pull();

project.builds.each { v ->
Expand Down
157 changes: 76 additions & 81 deletions bindings/c/c_interface.cpp
Original file line number Diff line number Diff line change
@@ -1,92 +1,87 @@
#include "compiler/GS2Context.h"

#ifdef _WIN32
#define DLL_EXPORT __declspec(dllexport)
#define DLL_EXPORT extern "C" __declspec(dllexport)
#else
#define DLL_EXPORT
#define DLL_EXPORT extern "C" __attribute__((visibility("default")))
#endif

extern "C" {
struct Response {
bool Success;
const char *ErrMsg;
unsigned char *ByteCode;
uint32_t ByteCodeSize;
};

DLL_EXPORT void *get_context() {
return new GS2Context();
struct Response {
bool Success;
const char *ErrMsg;
unsigned char *ByteCode;
uint32_t ByteCodeSize;
};

DLL_EXPORT void *get_context() {
return new GS2Context();
}

DLL_EXPORT Response compile_code_no_header(void *context, const char *code) {
Response result{};
result.Success = false;

if (const auto gs2Context = static_cast<GS2Context *>(context); gs2Context != nullptr) {
const std::string script = code;
std::string errMsg;
const auto response = gs2Context->compile(script);

if (!response.errors.empty()) {
errMsg.clear();
for (const auto &err: response.errors)
errMsg.append(err.msg()).append("\n");

const int lenStr = errMsg.length() + 1;
result.ErrMsg = new char[lenStr];
strcpy(const_cast<char *>(result.ErrMsg), errMsg.c_str());

result.ByteCode = nullptr;
result.ByteCodeSize = 0;
} else {
result.ErrMsg = nullptr;
result.ByteCode = new unsigned char[response.bytecode.length()]; // Allocate memory
memcpy(result.ByteCode, response.bytecode.buffer(), response.bytecode.length());
result.ByteCodeSize = response.bytecode.length();
}

DLL_EXPORT Response compile_code_no_header(void *context, const char *code) {
Response result{};
result.Success = false;

auto gs2Context = (GS2Context *) context;

if (gs2Context != nullptr) {
std::string script = code;
std::string errMsg;
auto response = gs2Context->compile(script);

if (!response.errors.empty()) {
errMsg.clear();
for (const auto &err: response.errors)
errMsg.append(err.msg()).append("\n");

int lenStr = errMsg.length() + 1;
result.ErrMsg = new char[lenStr];
strcpy(const_cast<char *>(result.ErrMsg), errMsg.c_str());

result.ByteCode = nullptr;
result.ByteCodeSize = 0;
} else {
result.ErrMsg = nullptr;
result.ByteCode = new unsigned char[response.bytecode.length()]; // Allocate memory
memcpy((void *) result.ByteCode, response.bytecode.buffer(), response.bytecode.length());
result.ByteCodeSize = response.bytecode.length();
}
result.Success = response.success;
}

return result;
result.Success = response.success;
}

return result;
}

DLL_EXPORT Response compile_code(void *context, const char *code, const char *type, const char *name) {
Response result{};
result.Success = false;

if (const auto gs2Context = static_cast<GS2Context *>(context);
gs2Context != nullptr) {
const std::string script = code;
std::string errMsg;
const auto response = gs2Context->compile(script, type, name, true);

if (!response.errors.empty()) {
errMsg.clear();
for (const auto &err: response.errors)
errMsg.append(err.msg()).append("\n");

const int lenStr = errMsg.length() + 1;
result.ErrMsg = new char[lenStr];
strcpy(const_cast<char *>(result.ErrMsg), errMsg.c_str());

result.ByteCode = nullptr;
result.ByteCodeSize = 0;
} else {
result.ErrMsg = nullptr;
result.ByteCode = new unsigned char[response.bytecode.length()]; // Allocate memory
memcpy(result.ByteCode, response.bytecode.buffer(), response.bytecode.length());
result.ByteCodeSize = response.bytecode.length();
}
result.Success = response.success;
}

DLL_EXPORT Response compile_code(void *context, const char *code, const char *type, const char *name) {
Response result{};
result.Success = false;

auto gs2Context = (GS2Context *) context;

if (gs2Context != nullptr) {
std::string script = code;
std::string errMsg;
auto response = gs2Context->compile(script, type, name, true);

if (!response.errors.empty()) {
errMsg.clear();
for (const auto &err: response.errors)
errMsg.append(err.msg()).append("\n");

int lenStr = errMsg.length() + 1;
result.ErrMsg = new char[lenStr];
strcpy(const_cast<char *>(result.ErrMsg), errMsg.c_str());

result.ByteCode = nullptr;
result.ByteCodeSize = 0;
} else {
result.ErrMsg = nullptr;
result.ByteCode = new unsigned char[response.bytecode.length()]; // Allocate memory
memcpy((void *) result.ByteCode, response.bytecode.buffer(), response.bytecode.length());
result.ByteCodeSize = response.bytecode.length();
}
result.Success = response.success;
}

return result;
}
return result;
}

DLL_EXPORT void delete_context(void *context) {
delete (GS2Context *) context;
}
DLL_EXPORT void delete_context(void *context) {
delete static_cast<GS2Context *>(context);
}
13 changes: 6 additions & 7 deletions bindings/dotnet/CompilerResponse.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
namespace Preagonal.Scripting.GS2Compiler
namespace Preagonal.Scripting.GS2Compiler;

public struct CompilerResponse
{
public struct CompilerResponse
{
public bool Success;
public string? ErrMsg;
public byte[] ByteCode;
}
public bool Success;
public string? ErrMsg;
public byte[] ByteCode;
}
54 changes: 28 additions & 26 deletions bindings/dotnet/GS2Compiler.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
using System.Runtime.InteropServices;

namespace Preagonal.Scripting.GS2Compiler
namespace Preagonal.Scripting.GS2Compiler;

public static class Interface
{
public static class Interface
{
[DllImport("gs2compiler", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr get_context();
[DllImport("gs2compiler", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr get_context();

[DllImport("gs2compiler", CallingConvention = CallingConvention.Cdecl)]
private static extern Response compile_code(IntPtr context, string? code, string? type, string? name);
[DllImport("gs2compiler", CallingConvention = CallingConvention.Cdecl)]
private static extern Response compile_code(IntPtr context, string? code, string? type, string? name);

[DllImport("gs2compiler", CallingConvention = CallingConvention.Cdecl)]
private static extern void delete_context(IntPtr context);
[DllImport("gs2compiler", CallingConvention = CallingConvention.Cdecl)]
private static extern Response compile_code_no_header(IntPtr context, string? code);

public static CompilerResponse CompileCode(string? code, string? type = "weapon", string? name = "npc")
{
IntPtr context = get_context();
Response response = compile_code(context, code, type, name);
[DllImport("gs2compiler", CallingConvention = CallingConvention.Cdecl)]
private static extern void delete_context(IntPtr context);

CompilerResponse compilerResponse = new()
{
Success = response.Success,
ErrMsg = response.ErrMsg,
};

if (response.ByteCodeSize > 0)
{
compilerResponse.ByteCode = new byte[response.ByteCodeSize];
Marshal.Copy(response.ByteCode, compilerResponse.ByteCode, 0, (int)response.ByteCodeSize);
}
public static CompilerResponse CompileCode(string? code, string? type = "weapon", string? name = "npc", bool withHeader = true)
{
var context = get_context();
var response = withHeader ? compile_code(context, code, type, name) : compile_code_no_header(context, code);

delete_context(context);
CompilerResponse compilerResponse = new()
{
Success = response.Success,
ErrMsg = response.ErrMsg,
};

return compilerResponse;
if (response.ByteCodeSize > 0)
{
compilerResponse.ByteCode = new byte[response.ByteCodeSize];
Marshal.Copy(response.ByteCode, compilerResponse.ByteCode, 0, (int)response.ByteCodeSize);
}

delete_context(context);

return compilerResponse;
}
}
Loading
Loading