4 个版本
使用旧的Rust 2015
0.2.3 | 2023年10月15日 |
---|---|
0.2.2 | 2022年12月16日 |
0.2.1 | 2022年11月14日 |
0.2.0 | 2022年10月29日 |
#1859 in 进程宏
在 2 个库中使用 (通过 rat-in-a-tube)
37KB
123 行
Rat In a Tube
RIAT是Halo:Combat Evolved脚本的免费脚本编译器。
要编译,您需要Rust编译器和Cargo。
示例用法
Rat in a Tube 可以在Rust、C和C++中使用。
Rust
RIAT是一个Rust库,因此您可以直接在您的Rust库中使用它。
extern crate rat_in_a_tube;
use rat_in_a_tube::Compiler;
/** Return true if successful. Return false on failure. */
fn compile_scripts_rust(script_file_name: &str, script_data: &[u8]) -> bool {
// Instantiate our instance
let mut compiler = Compiler::new(CompileTarget::HaloCEA);
// Try to compile
match compiler.read_script_data(script_file_name, script_data) {
Ok(_) => (),
Err(e) => {
let file = e.get_file();
let message = e.get_message();
let (line,column) = e.get_position();
eprintln!("Failed to read script data: {file}:{line}:{column}: {message}");
return false;
}
}
let script_data = match compiler.digest_tokens() {
Ok(n) => n,
Err(e) => {
let file = e.get_file();
let message = e.get_message();
let (line,column) = e.get_position();
eprintln!("Failed to compile script data: {file}:{line}:{column}: {message}");
return false;
}
};
// Print information
println!("Script count: {}", script_data.get_scripts().len());
println!("Global count: {}", script_data.get_globals().len());
println!("Node count: {}", script_data.get_nodes().len());
return true;
}
C
RIAT通过riatc包提供了C绑定。您需要使用您选择的工具链链接riatc库,并将riatc的include目录添加到您的include列表中。
#include <riat/riat.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
/* Return 0 if successful. Return a nonzero value if failed. */
int compile_scripts_c(const char *script_file_name, const uint8_t *script_data, size_t script_data_length) {
/* Put variables here */
int result = 0;
RIATCompiledScriptData *compiled_script_data = NULL;
RIATScriptC *scripts = NULL;
RIATGlobalC *globals = NULL;
RIATScriptNodeC *nodes = NULL;
size_t script_count, global_count, node_count;
/* Zero-out error struct. Not required, but calling riat_error_free() on a zeroed out struct is always OK. */
RIATCompileErrorC error;
memset(&error, 0, sizeof(error));
/* Instantiate our instance */
RIATCompiler *compiler = riat_compiler_new(RIAT_HaloCEA);
/* Try to compile */
if(riat_compiler_read_script_data(compiler, script_file_name, script_data, script_data_length, &error) != 0) {
fprintf(stderr, "Failed to read script data: %s:%zu:%zu: %s\n", error.file, error.line, error.column, error.message);
result = 1;
goto CLEANUP;
}
if((compiled_script_data = riat_compiler_compile_script_data(compiler, &error)) == NULL) {
fprintf(stderr, "Failed to compile script data: %s:%zu:%zu: %s\n", error.file, error.line, error.column, error.message);
result = 1;
goto CLEANUP;
}
/* Get the sizes */
script_count = riat_script_data_get_scripts(compiled_script_data, NULL);
global_count = riat_script_data_get_globals(compiled_script_data, NULL);
node_count = riat_script_data_get_nodes(compiled_script_data, NULL);
/* Allocate */
scripts = malloc(sizeof(*scripts) * script_count);
globals = malloc(sizeof(*globals) * global_count);
nodes = malloc(sizeof(*nodes) * node_count);
/* If any of those returned false, we failed */
if(scripts == NULL || globals == NULL || nodes == NULL) {
fprintf(stderr, "Allocation error!\n");
result = 2;
goto CLEANUP;
}
/* Read everything */
riat_script_data_get_scripts(compiled_script_data, scripts);
riat_script_data_get_globals(compiled_script_data, globals);
riat_script_data_get_nodes(compiled_script_data, nodes);
/* Print information */
printf("Script count: %zu\n", script_count);
printf("Global count: %zu\n", global_count);
printf("Node count %zu\n", node_count);
/* Cleanup */
CLEANUP:
riat_error_free(&error);
riat_compiler_free(compiler);
riat_script_data_free(compiled_script_data);
free(scripts);
free(globals);
free(nodes);
/* Done! */
return result;
}
C++
rustc包还包含一个C++头文件。您需要使用您选择的工具链编译riatc库,并将riatc的include目录添加到您的include列表中。
虽然您可以使用C头文件与您的C++库一起使用,但C++头文件通过std::vector等容器提供异常、类型安全和自动内存管理。
#include <riat/riat.hpp>
#include <iostream>
#include <cstdint>
#include <vector>
// Return true if successful. Return false on failure.
bool compile_scripts_cpp(const char *script_file_name, const std::vector<std::uint8_t> &script_data) {
// Instantiate our instance
RIAT::Compiler instance(RIATCompileTarget::RIAT_HaloCEA);
RIAT::CompilerScriptResult result;
// Try to compile
try {
instance.read_script_data(script_data.data(), script_data.size(), script_file_name);
result = instance.compile_scripts();
}
catch(std::exception &e) {
std::cerr << "Error when compiling: " << e.what() << "\n";
return false;
}
// Print information
auto scripts = result.get_scripts();
auto globals = result.get_globals();
auto nodes = result.get_nodes();
std::cout << "Script count:" << scripts.size() << std::endl;
std::cout << "Global count:" << globals.size() << std::endl;
std::cout << "Node count:" << nodes.size() << std::endl;
// Done!
return true;
}
依赖项
~0.6–1.4MB
~32K SLoC