mirror of
https://github.com/open-goal/jak-project.git
synced 2025-02-17 04:27:57 +00:00
Move duplicated utilities to the common util folder and remove NEXT_DIR
(#29)
* move things to the common library and remove next_dir * fix for windows * one last windows fix * last fix for real this time * debug listener test * fix listener threading bug
This commit is contained in:
parent
8cbcb36687
commit
de5aa7e5e4
@ -1,3 +1,4 @@
|
||||
add_library(common_util
|
||||
SHARED
|
||||
FileUtil.cpp)
|
||||
FileUtil.cpp
|
||||
Timer.cpp)
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include "FileUtil.h"
|
||||
#include <iostream>
|
||||
#include <stdio.h> /* defines FILENAME_MAX */
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
@ -8,7 +11,7 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
std::string FileUtil::GetProjectPath() {
|
||||
std::string file_util::get_project_path() {
|
||||
#ifdef _WIN32
|
||||
char buffer[FILENAME_MAX];
|
||||
GetModuleFileNameA(NULL, buffer, FILENAME_MAX);
|
||||
@ -16,20 +19,21 @@ std::string FileUtil::GetProjectPath() {
|
||||
"\\jak-project\\"); // Strip file path down to \jak-project\ directory
|
||||
return std::string(buffer).substr(
|
||||
0, pos + 12); // + 12 to include "\jak-project" in the returned filepath
|
||||
#else // do Linux stuff
|
||||
#else
|
||||
// do Linux stuff
|
||||
char buffer[FILENAME_MAX];
|
||||
readlink("/proc/self/exe", buffer,
|
||||
FILENAME_MAX); // /proc/self acts like a "virtual folder" containing information about
|
||||
// the current process
|
||||
std::string::size_type pos = std::string(buffer).find_last_of(
|
||||
std::string::size_type pos = std::string(buffer).rfind(
|
||||
"/jak-project/"); // Strip file path down to /jak-project/ directory
|
||||
return std::string(buffer).substr(
|
||||
0, pos + 12); // + 12 to include "/jak-project" in the returned filepath
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string FileUtil::get_file_path(const std::vector<std::string>& input) {
|
||||
std::string currentPath = FileUtil::GetProjectPath();
|
||||
std::string file_util::get_file_path(const std::vector<std::string>& input) {
|
||||
std::string currentPath = file_util::get_project_path();
|
||||
char dirSeparator;
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -39,9 +43,64 @@ std::string FileUtil::get_file_path(const std::vector<std::string>& input) {
|
||||
#endif
|
||||
|
||||
std::string filePath = currentPath;
|
||||
for (int i = 0; i < input.size(); i++) {
|
||||
for (int i = 0; i < int(input.size()); i++) {
|
||||
filePath = filePath + dirSeparator + input[i];
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
void file_util::write_binary_file(const std::string& name, void* data, size_t size) {
|
||||
FILE* fp = fopen(name.c_str(), "wb");
|
||||
if (!fp) {
|
||||
throw std::runtime_error("couldn't open file " + name);
|
||||
}
|
||||
|
||||
if (fwrite(data, size, 1, fp) != 1) {
|
||||
throw std::runtime_error("couldn't write file " + name);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void file_util::write_text_file(const std::string& file_name, const std::string& text) {
|
||||
FILE* fp = fopen(file_name.c_str(), "w");
|
||||
if (!fp) {
|
||||
printf("Failed to fopen %s\n", file_name.c_str());
|
||||
throw std::runtime_error("Failed to open file");
|
||||
}
|
||||
fprintf(fp, "%s\n", text.c_str());
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> file_util::read_binary_file(const std::string& filename) {
|
||||
auto fp = fopen(filename.c_str(), "rb");
|
||||
if (!fp)
|
||||
throw std::runtime_error("File " + filename + " cannot be opened");
|
||||
fseek(fp, 0, SEEK_END);
|
||||
auto len = ftell(fp);
|
||||
rewind(fp);
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
data.resize(len);
|
||||
|
||||
if (fread(data.data(), len, 1, fp) != 1) {
|
||||
throw std::runtime_error("File " + filename + " cannot be read");
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::string file_util::read_text_file(const std::string& path) {
|
||||
std::ifstream file(path);
|
||||
if (!file.good()) {
|
||||
throw std::runtime_error("couldn't open " + path);
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << file.rdbuf();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool file_util::is_printable_char(char c) {
|
||||
return c >= ' ' && c <= '~';
|
||||
}
|
@ -2,7 +2,12 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace FileUtil {
|
||||
std::string GetProjectPath();
|
||||
namespace file_util {
|
||||
std::string get_project_path();
|
||||
std::string get_file_path(const std::vector<std::string>& input);
|
||||
} // namespace FileUtil
|
||||
void write_binary_file(const std::string& name, void* data, size_t size);
|
||||
void write_text_file(const std::string& file_name, const std::string& text);
|
||||
std::vector<uint8_t> read_binary_file(const std::string& filename);
|
||||
std::string read_text_file(const std::string& path);
|
||||
bool is_printable_char(char c);
|
||||
} // namespace file_util
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef JAK1_MATCHPARAM_H
|
||||
#define JAK1_MATCHPARAM_H
|
||||
|
||||
namespace util {
|
||||
template <typename T>
|
||||
struct MatchParam {
|
||||
MatchParam() { is_wildcard = true; }
|
||||
@ -18,6 +17,5 @@ struct MatchParam {
|
||||
bool operator==(const T& other) const { return is_wildcard || (value == other); }
|
||||
bool operator!=(const T& other) const { return !(*this == other); }
|
||||
};
|
||||
} // namespace util
|
||||
|
||||
#endif // JAK1_MATCHPARAM_H
|
@ -12,7 +12,6 @@ add_executable(decompiler
|
||||
util/FileIO.cpp
|
||||
config.cpp
|
||||
util/LispPrint.cpp
|
||||
util/Timer.cpp
|
||||
Function/BasicBlocks.cpp
|
||||
Disasm/InstructionMatching.cpp
|
||||
TypeSystem/GoalType.cpp
|
||||
@ -22,4 +21,5 @@ add_executable(decompiler
|
||||
TypeSystem/TypeSpec.cpp Function/CfgVtx.cpp Function/CfgVtx.h)
|
||||
|
||||
target_link_libraries(decompiler
|
||||
minilzo)
|
||||
minilzo
|
||||
common_util)
|
@ -2,23 +2,7 @@
|
||||
#define JAK_DISASSEMBLER_INSTRUCTIONMATCHING_H
|
||||
|
||||
#include "Instruction.h"
|
||||
|
||||
template <typename T>
|
||||
struct MatchParam {
|
||||
MatchParam() { is_wildcard = true; }
|
||||
|
||||
// intentionally not explicit so you don't have to put MatchParam<whatever>(blah) everywhere
|
||||
MatchParam(T x) {
|
||||
value = x;
|
||||
is_wildcard = false;
|
||||
}
|
||||
|
||||
T value;
|
||||
bool is_wildcard = true;
|
||||
|
||||
bool operator==(const T& other) { return is_wildcard || (value == other); }
|
||||
bool operator!=(const T& other) { return !(*this == other); }
|
||||
};
|
||||
#include "common/util/MatchParam.h"
|
||||
|
||||
bool is_no_link_gpr_store(const Instruction& instr,
|
||||
MatchParam<int> size,
|
||||
|
@ -13,9 +13,10 @@
|
||||
#include "LinkedObjectFileCreation.h"
|
||||
#include "decompiler/config.h"
|
||||
#include "third-party/minilzo/minilzo.h"
|
||||
#include "decompiler/util/BinaryReader.h"
|
||||
#include "common/util/BinaryReader.h"
|
||||
#include "decompiler/util/FileIO.h"
|
||||
#include "decompiler/util/Timer.h"
|
||||
#include "common/util/Timer.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
#include "decompiler/Function/BasicBlocks.h"
|
||||
|
||||
/*!
|
||||
@ -142,7 +143,7 @@ constexpr int MAX_CHUNK_SIZE = 0x8000;
|
||||
* Load the objects stored in the given DGO into the ObjectFileDB
|
||||
*/
|
||||
void ObjectFileDB::get_objs_from_dgo(const std::string& filename) {
|
||||
auto dgo_data = read_binary_file(filename);
|
||||
auto dgo_data = file_util::read_binary_file(filename);
|
||||
stats.total_dgo_bytes += dgo_data.size();
|
||||
|
||||
const char jak2_header[] = "oZlB";
|
||||
@ -415,7 +416,7 @@ void ObjectFileDB::write_object_file_words(const std::string& output_dir, bool d
|
||||
auto file_text = obj.linked_data.print_words();
|
||||
auto file_name = combine_path(output_dir, obj.record.to_unique_name() + ".txt");
|
||||
total_bytes += file_text.size();
|
||||
write_text_file(file_name, file_text);
|
||||
file_util::write_text_file(file_name, file_text);
|
||||
total_files++;
|
||||
}
|
||||
});
|
||||
@ -442,7 +443,7 @@ void ObjectFileDB::write_disassembly(const std::string& output_dir,
|
||||
auto file_text = obj.linked_data.print_disassembly();
|
||||
auto file_name = combine_path(output_dir, obj.record.to_unique_name() + ".func");
|
||||
total_bytes += file_text.size();
|
||||
write_text_file(file_name, file_text);
|
||||
file_util::write_text_file(file_name, file_text);
|
||||
total_files++;
|
||||
}
|
||||
});
|
||||
@ -517,7 +518,7 @@ void ObjectFileDB::find_and_write_scripts(const std::string& output_dir) {
|
||||
});
|
||||
|
||||
auto file_name = combine_path(output_dir, "all_scripts.lisp");
|
||||
write_text_file(file_name, all_scripts);
|
||||
file_util::write_text_file(file_name, all_scripts);
|
||||
|
||||
printf("Found scripts:\n");
|
||||
printf(" total %.3f ms\n", timer.getMs());
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "config.h"
|
||||
#include "third-party/json.hpp"
|
||||
#include "util/FileIO.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
Config gConfig;
|
||||
|
||||
@ -9,7 +10,7 @@ Config& get_config() {
|
||||
}
|
||||
|
||||
void set_config(const std::string& path_to_config_file) {
|
||||
auto config_str = read_text_file(path_to_config_file);
|
||||
auto config_str = file_util::read_text_file(path_to_config_file);
|
||||
// to ignore comments in json, which may be useful
|
||||
auto cfg = nlohmann::json::parse(config_str, nullptr, true, true);
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "config.h"
|
||||
#include "util/FileIO.h"
|
||||
#include "TypeSystem/TypeInfo.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
printf("Jak Disassembler\n");
|
||||
@ -26,8 +27,8 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
ObjectFileDB db(dgos);
|
||||
write_text_file(combine_path(out_folder, "dgo.txt"), db.generate_dgo_listing());
|
||||
write_text_file(combine_path(out_folder, "obj.txt"), db.generate_obj_listing());
|
||||
file_util::write_text_file(combine_path(out_folder, "dgo.txt"), db.generate_dgo_listing());
|
||||
file_util::write_text_file(combine_path(out_folder, "obj.txt"), db.generate_obj_listing());
|
||||
|
||||
db.process_link_data();
|
||||
db.find_code();
|
||||
|
@ -3,35 +3,10 @@
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
|
||||
std::string read_text_file(const std::string& path) {
|
||||
std::ifstream file(path);
|
||||
std::stringstream ss;
|
||||
ss << file.rdbuf();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string combine_path(const std::string& parent, const std::string& child) {
|
||||
return parent + "/" + child;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> read_binary_file(const std::string& filename) {
|
||||
auto fp = fopen(filename.c_str(), "rb");
|
||||
if (!fp)
|
||||
throw std::runtime_error("File " + filename + " cannot be opened");
|
||||
fseek(fp, 0, SEEK_END);
|
||||
auto len = ftell(fp);
|
||||
rewind(fp);
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
data.resize(len);
|
||||
|
||||
if (fread(data.data(), len, 1, fp) != 1) {
|
||||
throw std::runtime_error("File " + filename + " cannot be read");
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::string base_name(const std::string& filename) {
|
||||
size_t pos = 0;
|
||||
assert(!filename.empty());
|
||||
@ -70,13 +45,3 @@ uint32_t crc32(const uint8_t* data, size_t size) {
|
||||
uint32_t crc32(const std::vector<uint8_t>& data) {
|
||||
return crc32(data.data(), data.size());
|
||||
}
|
||||
|
||||
void write_text_file(const std::string& file_name, const std::string& text) {
|
||||
FILE* fp = fopen(file_name.c_str(), "w");
|
||||
if (!fp) {
|
||||
printf("Failed to fopen %s\n", file_name.c_str());
|
||||
throw std::runtime_error("Failed to open file");
|
||||
}
|
||||
fprintf(fp, "%s\n", text.c_str());
|
||||
fclose(fp);
|
||||
}
|
@ -4,12 +4,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
std::string read_text_file(const std::string& path);
|
||||
std::string combine_path(const std::string& parent, const std::string& child);
|
||||
std::vector<uint8_t> read_binary_file(const std::string& filename);
|
||||
std::string base_name(const std::string& filename);
|
||||
void write_text_file(const std::string& file_name, const std::string& text);
|
||||
|
||||
void init_crc();
|
||||
uint32_t crc32(const uint8_t* data, size_t size);
|
||||
uint32_t crc32(const std::vector<uint8_t>& data);
|
||||
|
@ -78,8 +78,8 @@ add_library(runtime ${RUNTIME_SOURCE})
|
||||
|
||||
IF (WIN32)
|
||||
# set stuff for windows
|
||||
target_link_libraries(gk cross_sockets mman)
|
||||
target_link_libraries(gk cross_sockets mman common_util)
|
||||
ELSE()
|
||||
# set stuff for other systems
|
||||
target_link_libraries(gk cross_sockets pthread)
|
||||
target_link_libraries(gk cross_sockets pthread common_util)
|
||||
ENDIF()
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "game/sce/iop.h"
|
||||
#include "isocommon.h"
|
||||
#include "overlord.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
using namespace iop;
|
||||
|
||||
@ -71,25 +72,15 @@ void fake_iso_init_globals() {
|
||||
read_in_progress = false;
|
||||
}
|
||||
|
||||
//! will hold prefix for the source folder.
|
||||
static const char* next_dir = nullptr;
|
||||
static const char* fake_iso_path = nullptr;
|
||||
|
||||
/*!
|
||||
* Initialize the file system.
|
||||
*/
|
||||
int FS_Init(u8* buffer) {
|
||||
(void)buffer;
|
||||
// get path to next/. Will be set in the gk.sh launch script.
|
||||
next_dir = std::getenv("NEXT_DIR");
|
||||
assert(next_dir);
|
||||
|
||||
// get path to next/data/fake_iso.txt, the map file.
|
||||
char fakeiso_path[512];
|
||||
strcpy(fakeiso_path, next_dir);
|
||||
fake_iso_path = std::getenv("FAKE_ISO_PATH");
|
||||
assert(fake_iso_path);
|
||||
strcat(fakeiso_path, fake_iso_path);
|
||||
strcpy(fakeiso_path, file_util::get_file_path({"game", "fake_iso.txt"}).c_str());
|
||||
|
||||
// open the map.
|
||||
FILE* fp = fopen(fakeiso_path, "r");
|
||||
@ -197,7 +188,7 @@ FileRecord* FS_FindIN(const char* iso_name) {
|
||||
static const char* get_file_path(FileRecord* fr) {
|
||||
assert(fr->location < fake_iso_entry_count);
|
||||
static char path_buffer[1024];
|
||||
strcpy(path_buffer, next_dir);
|
||||
strcpy(path_buffer, file_util::get_project_path().c_str());
|
||||
strcat(path_buffer, "/");
|
||||
strcat(path_buffer, fake_iso_entries[fr->location].file_path);
|
||||
return path_buffer;
|
||||
|
2
gc.sh
2
gc.sh
@ -3,6 +3,4 @@
|
||||
# Directory of this script
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
export NEXT_DIR=$DIR
|
||||
export FAKE_ISO_PATH=/game/fake_iso.txt
|
||||
$DIR/build/goalc/goalc "$@"
|
2
gk.sh
2
gk.sh
@ -3,6 +3,4 @@
|
||||
# Directory of this script
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
export NEXT_DIR=$DIR
|
||||
export FAKE_ISO_PATH=/game/fake_iso.txt
|
||||
$DIR/build/game/gk "$@"
|
||||
|
@ -1,4 +1,3 @@
|
||||
add_subdirectory(util)
|
||||
add_subdirectory(goos)
|
||||
add_subdirectory(listener)
|
||||
|
||||
@ -28,10 +27,10 @@ add_library(compiler
|
||||
add_executable(goalc main.cpp)
|
||||
|
||||
IF (WIN32)
|
||||
target_link_libraries(compiler util goos type_system listener mman)
|
||||
target_link_libraries(compiler goos type_system listener mman common_util)
|
||||
|
||||
ELSE ()
|
||||
target_link_libraries(compiler util goos type_system listener)
|
||||
target_link_libraries(compiler goos type_system listener common_util)
|
||||
ENDIF ()
|
||||
|
||||
target_link_libraries(goalc util goos compiler type_system)
|
||||
target_link_libraries(goalc goos compiler type_system)
|
||||
|
@ -15,7 +15,7 @@ Compiler::Compiler() {
|
||||
m_none = std::make_unique<None>(m_ts.make_typespec("none"));
|
||||
|
||||
// todo - compile library
|
||||
Object library_code = m_goos.reader.read_from_file("goal_src/goal-lib.gc");
|
||||
Object library_code = m_goos.reader.read_from_file({"goal_src", "goal-lib.gc"});
|
||||
compile_object_file("goal-lib", library_code, false);
|
||||
}
|
||||
|
||||
@ -178,7 +178,7 @@ std::vector<std::string> Compiler::run_test(const std::string& source_code) {
|
||||
}
|
||||
}
|
||||
|
||||
auto code = m_goos.reader.read_from_file(source_code);
|
||||
auto code = m_goos.reader.read_from_file({source_code});
|
||||
auto compiled = compile_object_file("test-code", code, true);
|
||||
color_object_file(compiled);
|
||||
auto data = codegen_object_file(compiled);
|
||||
|
@ -48,9 +48,8 @@ class Compiler {
|
||||
void va_check(
|
||||
const goos::Object& form,
|
||||
const goos::Arguments& args,
|
||||
const std::vector<util::MatchParam<goos::ObjectType>>& unnamed,
|
||||
const std::unordered_map<std::string, std::pair<bool, util::MatchParam<goos::ObjectType>>>&
|
||||
named);
|
||||
const std::vector<MatchParam<goos::ObjectType>>& unnamed,
|
||||
const std::unordered_map<std::string, std::pair<bool, MatchParam<goos::ObjectType>>>& named);
|
||||
std::string as_string(const goos::Object& o);
|
||||
std::string symbol_string(const goos::Object& o);
|
||||
const goos::Object& pair_car(const goos::Object& o);
|
||||
|
@ -37,9 +37,8 @@ goos::Arguments Compiler::get_va(const goos::Object& form, const goos::Object& r
|
||||
void Compiler::va_check(
|
||||
const goos::Object& form,
|
||||
const goos::Arguments& args,
|
||||
const std::vector<util::MatchParam<goos::ObjectType>>& unnamed,
|
||||
const std::unordered_map<std::string, std::pair<bool, util::MatchParam<goos::ObjectType>>>&
|
||||
named) {
|
||||
const std::vector<MatchParam<goos::ObjectType>>& unnamed,
|
||||
const std::unordered_map<std::string, std::pair<bool, MatchParam<goos::ObjectType>>>& named) {
|
||||
assert(args.rest.empty());
|
||||
if (unnamed.size() != args.unnamed.size()) {
|
||||
throw_compile_error(form, "Got " + std::to_string(args.unnamed.size()) +
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "goalc/compiler/Compiler.h"
|
||||
#include "goalc/compiler/IR.h"
|
||||
#include "goalc/util/Timer.h"
|
||||
#include "goalc/util/file_io.h"
|
||||
#include "common/util/Timer.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
Val* Compiler::compile_exit(const goos::Object& form, const goos::Object& rest, Env* env) {
|
||||
(void)env;
|
||||
@ -59,7 +59,7 @@ Val* Compiler::compile_asm_file(const goos::Object& form, const goos::Object& re
|
||||
});
|
||||
|
||||
Timer reader_timer;
|
||||
auto code = m_goos.reader.read_from_file(filename);
|
||||
auto code = m_goos.reader.read_from_file({filename});
|
||||
timing.emplace_back("read", reader_timer.getMs());
|
||||
|
||||
Timer compile_timer;
|
||||
@ -95,7 +95,7 @@ Val* Compiler::compile_asm_file(const goos::Object& form, const goos::Object& re
|
||||
// auto output_dir = as_string(get_constant_or_error(form, "*compiler-output-path*"));
|
||||
// todo, change extension based on v3/v4
|
||||
auto output_name = m_goos.reader.get_source_dir() + "/out/" + obj_file_name + ".o";
|
||||
util::write_binary_file(output_name, (void*)data.data(), data.size());
|
||||
file_util::write_binary_file(output_name, (void*)data.data(), data.size());
|
||||
}
|
||||
} else {
|
||||
if (load) {
|
||||
|
@ -1,2 +1,2 @@
|
||||
add_library(goos SHARED Object.cpp TextDB.cpp Reader.cpp Interpreter.cpp InterpreterEval.cpp)
|
||||
target_link_libraries(goos util)
|
||||
target_link_libraries(goos common_util)
|
@ -379,8 +379,8 @@ ArgumentSpec Interpreter::parse_arg_spec(const Object& form, Object& rest) {
|
||||
void Interpreter::vararg_check(
|
||||
const Object& form,
|
||||
const Arguments& args,
|
||||
const std::vector<util::MatchParam<ObjectType>>& unnamed,
|
||||
const std::unordered_map<std::string, std::pair<bool, util::MatchParam<ObjectType>>>& named) {
|
||||
const std::vector<MatchParam<ObjectType>>& unnamed,
|
||||
const std::unordered_map<std::string, std::pair<bool, MatchParam<ObjectType>>>& named) {
|
||||
assert(args.rest.empty());
|
||||
if (unnamed.size() != args.unnamed.size()) {
|
||||
throw_eval_error(form, "Got " + std::to_string(args.unnamed.size()) +
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <memory>
|
||||
#include "Object.h"
|
||||
#include "Reader.h"
|
||||
#include "goalc/util/MatchParam.h"
|
||||
#include "common/util/MatchParam.h"
|
||||
|
||||
namespace goos {
|
||||
class Interpreter {
|
||||
@ -53,8 +53,8 @@ class Interpreter {
|
||||
void vararg_check(
|
||||
const Object& form,
|
||||
const Arguments& args,
|
||||
const std::vector<util::MatchParam<ObjectType>>& unnamed,
|
||||
const std::unordered_map<std::string, std::pair<bool, util::MatchParam<ObjectType>>>& named);
|
||||
const std::vector<MatchParam<ObjectType>>& unnamed,
|
||||
const std::unordered_map<std::string, std::pair<bool, MatchParam<ObjectType>>>& named);
|
||||
|
||||
Object eval_pair(const Object& o, const std::shared_ptr<EnvironmentObject>& env);
|
||||
void eval_args(Arguments* args, const std::shared_ptr<EnvironmentObject>& env);
|
||||
|
@ -66,7 +66,7 @@ Object Interpreter::eval_read_file(const Object& form,
|
||||
vararg_check(form, args, {ObjectType::STRING}, {});
|
||||
|
||||
try {
|
||||
return reader.read_from_file(args.unnamed.at(0).as_string()->data);
|
||||
return reader.read_from_file({args.unnamed.at(0).as_string()->data});
|
||||
} catch (std::runtime_error& e) {
|
||||
throw_eval_error(form, std::string("reader error inside of read-file:\n") + e.what());
|
||||
}
|
||||
@ -84,7 +84,7 @@ Object Interpreter::eval_load_file(const Object& form,
|
||||
|
||||
Object o;
|
||||
try {
|
||||
o = reader.read_from_file(args.unnamed.at(0).as_string()->data);
|
||||
o = reader.read_from_file({args.unnamed.at(0).as_string()->data});
|
||||
} catch (std::runtime_error& e) {
|
||||
throw_eval_error(form, std::string("reader error inside of load-file:\n") + e.what());
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "Object.h"
|
||||
#include "goalc/util/text_util.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
namespace goos {
|
||||
|
||||
@ -53,7 +53,7 @@ std::string fixed_to_string(FloatType x) {
|
||||
template <>
|
||||
std::string fixed_to_string(char x) {
|
||||
char buff[256];
|
||||
if (util::is_printable_char(x) && x != ' ') {
|
||||
if (file_util::is_printable_char(x) && x != ' ') {
|
||||
// can print directly
|
||||
sprintf(buff, "#\\%c", x);
|
||||
return {buff};
|
||||
|
@ -11,8 +11,7 @@
|
||||
|
||||
#include "Reader.h"
|
||||
#include "third-party/linenoise.h"
|
||||
#include "goalc/util/file_io.h"
|
||||
#include "goalc/util/text_util.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
namespace goos {
|
||||
|
||||
@ -98,15 +97,6 @@ Reader::Reader() {
|
||||
for (const char* c = bonus; *c; c++) {
|
||||
valid_symbols_chars[(int)*c] = true;
|
||||
}
|
||||
|
||||
// find the source directory
|
||||
auto result = std::getenv("NEXT_DIR");
|
||||
if (!result) {
|
||||
throw std::runtime_error(
|
||||
"Environment variable NEXT_DIR is not set. Please set this to point to next/");
|
||||
}
|
||||
|
||||
source_dir = result;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -147,8 +137,8 @@ Object Reader::read_from_string(const std::string& str) {
|
||||
/*!
|
||||
* Read a file
|
||||
*/
|
||||
Object Reader::read_from_file(const std::string& filename) {
|
||||
auto textFrag = std::make_shared<FileText>(util::combine_path(get_source_dir(), filename));
|
||||
Object Reader::read_from_file(const std::vector<std::string>& file_path) {
|
||||
auto textFrag = std::make_shared<FileText>(file_util::get_file_path(file_path));
|
||||
db.insert(textFrag);
|
||||
|
||||
auto result = internal_read(textFrag);
|
||||
@ -670,7 +660,7 @@ bool Reader::try_token_as_integer(const Token& tok, Object& obj) {
|
||||
|
||||
bool Reader::try_token_as_char(const Token& tok, Object& obj) {
|
||||
if (tok.text.size() >= 3 && tok.text[0] == '#' && tok.text[1] == '\\') {
|
||||
if (tok.text.size() == 3 && util::is_printable_char(tok.text[2]) && tok.text[2] != ' ') {
|
||||
if (tok.text.size() == 3 && file_util::is_printable_char(tok.text[2]) && tok.text[2] != ' ') {
|
||||
obj = Object::make_char(tok.text[2]);
|
||||
return true;
|
||||
}
|
||||
@ -705,6 +695,6 @@ void Reader::throw_reader_error(TextStream& here, const std::string& err, int se
|
||||
* Get the source directory of the current project.
|
||||
*/
|
||||
std::string Reader::get_source_dir() {
|
||||
return source_dir;
|
||||
return file_util::get_project_path();
|
||||
}
|
||||
} // namespace goos
|
||||
|
@ -70,7 +70,7 @@ class Reader {
|
||||
Reader();
|
||||
Object read_from_string(const std::string& str);
|
||||
Object read_from_stdin(const std::string& prompt_name);
|
||||
Object read_from_file(const std::string& filename);
|
||||
Object read_from_file(const std::vector<std::string>& file_path);
|
||||
|
||||
std::string get_source_dir();
|
||||
|
||||
@ -97,7 +97,6 @@ class Reader {
|
||||
|
||||
char valid_symbols_chars[256];
|
||||
|
||||
std::string source_dir;
|
||||
std::unordered_map<std::string, std::string> reader_macros;
|
||||
};
|
||||
} // namespace goos
|
||||
|
@ -11,7 +11,7 @@
|
||||
* (+ 1 (+ a b)) ; compute the sum
|
||||
*/
|
||||
|
||||
#include "goalc/util/file_io.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
#include "TextDB.h"
|
||||
|
||||
@ -79,7 +79,7 @@ std::pair<int, int> SourceText::get_containing_line(int offset) {
|
||||
* Read text from a file.
|
||||
*/
|
||||
FileText::FileText(std::string filename_) : filename(std::move(filename_)) {
|
||||
text = util::read_text_file(filename);
|
||||
text = file_util::read_text_file(filename);
|
||||
build_offsets();
|
||||
}
|
||||
|
||||
|
@ -151,8 +151,8 @@ bool Listener::connect_to_target(int n_tries, const std::string& ip, int port) {
|
||||
printf("Got version %d.%d", version_buffer[0], version_buffer[1]);
|
||||
if (version_buffer[0] == GOAL_VERSION_MAJOR && version_buffer[1] == GOAL_VERSION_MINOR) {
|
||||
printf(" OK!\n");
|
||||
rcv_thread = std::thread(&Listener::receive_func, this);
|
||||
m_connected = true;
|
||||
rcv_thread = std::thread(&Listener::receive_func, this);
|
||||
receive_thread_running = true;
|
||||
return true;
|
||||
} else {
|
||||
@ -189,10 +189,9 @@ void Listener::receive_func() {
|
||||
}
|
||||
|
||||
ListenerMessageHeader* hdr = (ListenerMessageHeader*)buff;
|
||||
// if(debug_listener) {
|
||||
// printf("[T -> L] received %d bytes, kind %d\n",
|
||||
// hdr->deci2_hdr.len, hdr->msg_kind);
|
||||
// }
|
||||
if (debug_listener) {
|
||||
printf("[T -> L] received %d bytes, kind %d\n", hdr->deci2_header.len, int(hdr->msg_kind));
|
||||
}
|
||||
|
||||
switch (hdr->msg_kind) {
|
||||
case ListenerMessageKind::MSG_ACK:
|
||||
|
@ -1 +0,0 @@
|
||||
add_library(util SHARED text_util.cpp file_io.cpp Timer.cpp)
|
@ -1,54 +0,0 @@
|
||||
#include "Timer.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#define MS_PER_SEC 1000ULL // MS = milliseconds
|
||||
#define US_PER_MS 1000ULL // US = microseconds
|
||||
#define HNS_PER_US 10ULL // HNS = hundred-nanoseconds (e.g., 1 hns = 100 ns)
|
||||
#define NS_PER_US 1000ULL
|
||||
|
||||
#define HNS_PER_SEC (MS_PER_SEC * US_PER_MS * HNS_PER_US)
|
||||
#define NS_PER_HNS (100ULL) // NS = nanoseconds
|
||||
#define NS_PER_SEC (MS_PER_SEC * US_PER_MS * NS_PER_US)
|
||||
|
||||
int Timer::clock_gettime_monotonic(struct timespec* tv) {
|
||||
static LARGE_INTEGER ticksPerSec;
|
||||
LARGE_INTEGER ticks;
|
||||
double seconds;
|
||||
|
||||
if (!ticksPerSec.QuadPart) {
|
||||
QueryPerformanceFrequency(&ticksPerSec);
|
||||
if (!ticksPerSec.QuadPart) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
QueryPerformanceCounter(&ticks);
|
||||
|
||||
seconds = (double)ticks.QuadPart / (double)ticksPerSec.QuadPart;
|
||||
tv->tv_sec = (time_t)seconds;
|
||||
tv->tv_nsec = (long)((ULONGLONG)(seconds * NS_PER_SEC) % NS_PER_SEC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Timer::start() {
|
||||
#ifdef __linux__
|
||||
clock_gettime(CLOCK_MONOTONIC, &_startTime);
|
||||
#elif _WIN32
|
||||
clock_gettime_monotonic(&_startTime);
|
||||
#endif
|
||||
}
|
||||
|
||||
int64_t Timer::getNs() {
|
||||
struct timespec now = {};
|
||||
#ifdef __linux__
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
#elif _WIN32
|
||||
clock_gettime_monotonic(&now);
|
||||
#endif
|
||||
return (int64_t)(now.tv_nsec - _startTime.tv_nsec) +
|
||||
1000000000 * (now.tv_sec - _startTime.tv_sec);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
#ifndef JAK_V2_TIMER_H
|
||||
#define JAK_V2_TIMER_H
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
|
||||
/*!
|
||||
* Timer for measuring time elapsed with clock_monotonic
|
||||
*/
|
||||
class Timer {
|
||||
public:
|
||||
/*!
|
||||
* Construct and start timer
|
||||
*/
|
||||
explicit Timer() { start(); }
|
||||
|
||||
#ifdef _WIN32
|
||||
int clock_gettime_monotonic(struct timespec* tv);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Start the timer
|
||||
*/
|
||||
void start();
|
||||
|
||||
/*!
|
||||
* Get milliseconds elapsed
|
||||
*/
|
||||
double getMs() { return (double)getNs() / 1.e6; }
|
||||
|
||||
double getUs() { return (double)getNs() / 1.e3; }
|
||||
|
||||
/*!
|
||||
* Get nanoseconds elapsed
|
||||
*/
|
||||
int64_t getNs();
|
||||
|
||||
/*!
|
||||
* Get seconds elapsed
|
||||
*/
|
||||
double getSeconds() { return (double)getNs() / 1.e9; }
|
||||
|
||||
struct timespec _startTime = {};
|
||||
};
|
||||
|
||||
#endif // JAK_V2_TIMER_H
|
@ -1,45 +0,0 @@
|
||||
#include "file_io.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
|
||||
namespace util {
|
||||
std::string read_text_file(const std::string& path) {
|
||||
std::ifstream file(path);
|
||||
if (!file.good()) {
|
||||
throw std::runtime_error("couldn't open " + path);
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << file.rdbuf();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string combine_path(const std::string& parent, const std::string& child) {
|
||||
return parent + "/" + child;
|
||||
}
|
||||
|
||||
std::string combine_path(std::vector<std::string> path) {
|
||||
if (path.empty()) {
|
||||
return {};
|
||||
}
|
||||
std::string result = path.front();
|
||||
for (size_t i = 1; i < path.size(); i++) {
|
||||
result = combine_path(result, path.at(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void write_binary_file(const std::string& name, void* data, size_t size) {
|
||||
FILE* fp = fopen(name.c_str(), "wb");
|
||||
if (!fp) {
|
||||
throw std::runtime_error("couldn't open file " + name);
|
||||
}
|
||||
|
||||
if (fwrite(data, size, 1, fp) != 1) {
|
||||
throw std::runtime_error("couldn't write file " + name);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
} // namespace util
|
@ -1,14 +0,0 @@
|
||||
#ifndef JAK1_FILE_IO_H
|
||||
#define JAK1_FILE_IO_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace util {
|
||||
std::string read_text_file(const std::string& path);
|
||||
std::string combine_path(const std::string& parent, const std::string& child);
|
||||
std::string combine_path(std::vector<std::string> path);
|
||||
void write_binary_file(const std::string& name, void* data, size_t size);
|
||||
} // namespace util
|
||||
|
||||
#endif // JAK1_FILE_IO_H
|
@ -1,16 +0,0 @@
|
||||
/*!
|
||||
* @file text_util.cpp
|
||||
* Utilities for dealing with text.
|
||||
*/
|
||||
|
||||
#include "text_util.h"
|
||||
|
||||
namespace util {
|
||||
/*!
|
||||
* Is c printable? Is true for letters, numbers, symbols, space, false for everything else.
|
||||
* Note: newline/tab is not considered printable.
|
||||
*/
|
||||
bool is_printable_char(char c) {
|
||||
return c >= ' ' && c <= '~';
|
||||
}
|
||||
} // namespace util
|
@ -1,13 +0,0 @@
|
||||
/*!
|
||||
* @file text_util.h
|
||||
* Utilities for dealing with text.
|
||||
*/
|
||||
|
||||
#ifndef JAK1_TEXT_UTIL_H
|
||||
#define JAK1_TEXT_UTIL_H
|
||||
|
||||
namespace util {
|
||||
bool is_printable_char(char c);
|
||||
}
|
||||
|
||||
#endif // JAK1_TEXT_UTIL_H
|
@ -3,8 +3,6 @@
|
||||
# Directory of this script
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
export NEXT_DIR=$DIR
|
||||
export FAKE_ISO_PATH=/game/fake_iso.txt
|
||||
cd $DIR/build/test
|
||||
make init
|
||||
make gcov
|
||||
|
2
test.sh
2
test.sh
@ -3,6 +3,4 @@
|
||||
# Directory of this script
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
export NEXT_DIR=$DIR
|
||||
export FAKE_ISO_PATH=/game/fake_iso.txt
|
||||
$DIR/build/test/goalc-test --gtest_color=yes "$@"
|
||||
|
@ -22,9 +22,9 @@ IF (WIN32)
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
|
||||
# TODO - split out these declarations for platform specific includes
|
||||
target_link_libraries(goalc-test cross_sockets listener mman goos util common_util runtime compiler type_system gtest)
|
||||
target_link_libraries(goalc-test cross_sockets listener mman goos common_util runtime compiler type_system gtest)
|
||||
ELSE()
|
||||
target_link_libraries(goalc-test cross_sockets goos util common_util listener runtime compiler type_system gtest)
|
||||
target_link_libraries(goalc-test cross_sockets goos common_util listener runtime compiler type_system gtest)
|
||||
ENDIF()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND CODE_COVERAGE)
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
TEST(FileUtil, valid_path) {
|
||||
std::vector<std::string> test = {"cabbage", "banana", "apple"};
|
||||
std::string sampleString = FileUtil::get_file_path(test);
|
||||
std::string sampleString = file_util::get_file_path(test);
|
||||
// std::cout << sampleString << std::endl;
|
||||
|
||||
EXPECT_TRUE(true);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "goalc/goos/Reader.h"
|
||||
#include "goalc/util/file_io.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
using namespace goos;
|
||||
|
||||
@ -316,16 +316,16 @@ TEST(GoosReader, TopLevel) {
|
||||
|
||||
TEST(GoosReader, FromFile) {
|
||||
Reader reader;
|
||||
auto result = reader.read_from_file(util::combine_path({"test", "test_reader_file0.gc"})).print();
|
||||
auto result = reader.read_from_file({"test", "test_reader_file0.gc"}).print();
|
||||
EXPECT_TRUE(result == "(top-level (1 2 3 4))");
|
||||
}
|
||||
|
||||
TEST(GoosReader, TextDb) {
|
||||
// very specific to this particular test file, but whatever.
|
||||
Reader reader;
|
||||
auto file_path = util::combine_path({"test", "test_reader_file0.gc"});
|
||||
auto result = reader.read_from_file(file_path).as_pair()->cdr.as_pair()->car;
|
||||
std::string expected = "text from " + util::combine_path(reader.get_source_dir(), file_path) +
|
||||
auto result =
|
||||
reader.read_from_file({"test", "test_reader_file0.gc"}).as_pair()->cdr.as_pair()->car;
|
||||
std::string expected = "text from " + file_util::get_file_path({"test", "test_reader_file0.gc"}) +
|
||||
", line: 5\n(1 2 3 4)\n";
|
||||
EXPECT_EQ(expected, reader.db.get_info_for(result));
|
||||
}
|
||||
|
@ -3,7 +3,5 @@
|
||||
# Directory of this script
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
export NEXT_DIR=$DIR
|
||||
export FAKE_ISO_PATH=/game/fake_iso.txt
|
||||
cd $DIR/build/
|
||||
make goalc-test_coverage
|
||||
|
Loading…
x
Reference in New Issue
Block a user