mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 00:57:44 -04: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
|
add_library(common_util
|
||||||
SHARED
|
SHARED
|
||||||
FileUtil.cpp)
|
FileUtil.cpp
|
||||||
|
Timer.cpp)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdio.h> /* defines FILENAME_MAX */
|
#include <stdio.h> /* defines FILENAME_MAX */
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -8,7 +11,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string FileUtil::GetProjectPath() {
|
std::string file_util::get_project_path() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char buffer[FILENAME_MAX];
|
char buffer[FILENAME_MAX];
|
||||||
GetModuleFileNameA(NULL, 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
|
"\\jak-project\\"); // Strip file path down to \jak-project\ directory
|
||||||
return std::string(buffer).substr(
|
return std::string(buffer).substr(
|
||||||
0, pos + 12); // + 12 to include "\jak-project" in the returned filepath
|
0, pos + 12); // + 12 to include "\jak-project" in the returned filepath
|
||||||
#else // do Linux stuff
|
#else
|
||||||
|
// do Linux stuff
|
||||||
char buffer[FILENAME_MAX];
|
char buffer[FILENAME_MAX];
|
||||||
readlink("/proc/self/exe", buffer,
|
readlink("/proc/self/exe", buffer,
|
||||||
FILENAME_MAX); // /proc/self acts like a "virtual folder" containing information about
|
FILENAME_MAX); // /proc/self acts like a "virtual folder" containing information about
|
||||||
// the current process
|
// 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
|
"/jak-project/"); // Strip file path down to /jak-project/ directory
|
||||||
return std::string(buffer).substr(
|
return std::string(buffer).substr(
|
||||||
0, pos + 12); // + 12 to include "/jak-project" in the returned filepath
|
0, pos + 12); // + 12 to include "/jak-project" in the returned filepath
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FileUtil::get_file_path(const std::vector<std::string>& input) {
|
std::string file_util::get_file_path(const std::vector<std::string>& input) {
|
||||||
std::string currentPath = FileUtil::GetProjectPath();
|
std::string currentPath = file_util::get_project_path();
|
||||||
char dirSeparator;
|
char dirSeparator;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -39,9 +43,64 @@ std::string FileUtil::get_file_path(const std::vector<std::string>& input) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string filePath = currentPath;
|
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];
|
filePath = filePath + dirSeparator + input[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return filePath;
|
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 <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace FileUtil {
|
namespace file_util {
|
||||||
std::string GetProjectPath();
|
std::string get_project_path();
|
||||||
std::string get_file_path(const std::vector<std::string>& input);
|
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
|
#ifndef JAK1_MATCHPARAM_H
|
||||||
#define JAK1_MATCHPARAM_H
|
#define JAK1_MATCHPARAM_H
|
||||||
|
|
||||||
namespace util {
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct MatchParam {
|
struct MatchParam {
|
||||||
MatchParam() { is_wildcard = true; }
|
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 is_wildcard || (value == other); }
|
||||||
bool operator!=(const T& other) const { return !(*this == other); }
|
bool operator!=(const T& other) const { return !(*this == other); }
|
||||||
};
|
};
|
||||||
} // namespace util
|
|
||||||
|
|
||||||
#endif // JAK1_MATCHPARAM_H
|
#endif // JAK1_MATCHPARAM_H
|
|
@ -12,7 +12,6 @@ add_executable(decompiler
|
||||||
util/FileIO.cpp
|
util/FileIO.cpp
|
||||||
config.cpp
|
config.cpp
|
||||||
util/LispPrint.cpp
|
util/LispPrint.cpp
|
||||||
util/Timer.cpp
|
|
||||||
Function/BasicBlocks.cpp
|
Function/BasicBlocks.cpp
|
||||||
Disasm/InstructionMatching.cpp
|
Disasm/InstructionMatching.cpp
|
||||||
TypeSystem/GoalType.cpp
|
TypeSystem/GoalType.cpp
|
||||||
|
@ -22,4 +21,5 @@ add_executable(decompiler
|
||||||
TypeSystem/TypeSpec.cpp Function/CfgVtx.cpp Function/CfgVtx.h)
|
TypeSystem/TypeSpec.cpp Function/CfgVtx.cpp Function/CfgVtx.h)
|
||||||
|
|
||||||
target_link_libraries(decompiler
|
target_link_libraries(decompiler
|
||||||
minilzo)
|
minilzo
|
||||||
|
common_util)
|
|
@ -2,23 +2,7 @@
|
||||||
#define JAK_DISASSEMBLER_INSTRUCTIONMATCHING_H
|
#define JAK_DISASSEMBLER_INSTRUCTIONMATCHING_H
|
||||||
|
|
||||||
#include "Instruction.h"
|
#include "Instruction.h"
|
||||||
|
#include "common/util/MatchParam.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); }
|
|
||||||
};
|
|
||||||
|
|
||||||
bool is_no_link_gpr_store(const Instruction& instr,
|
bool is_no_link_gpr_store(const Instruction& instr,
|
||||||
MatchParam<int> size,
|
MatchParam<int> size,
|
||||||
|
|
|
@ -13,9 +13,10 @@
|
||||||
#include "LinkedObjectFileCreation.h"
|
#include "LinkedObjectFileCreation.h"
|
||||||
#include "decompiler/config.h"
|
#include "decompiler/config.h"
|
||||||
#include "third-party/minilzo/minilzo.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/FileIO.h"
|
||||||
#include "decompiler/util/Timer.h"
|
#include "common/util/Timer.h"
|
||||||
|
#include "common/util/FileUtil.h"
|
||||||
#include "decompiler/Function/BasicBlocks.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
|
* Load the objects stored in the given DGO into the ObjectFileDB
|
||||||
*/
|
*/
|
||||||
void ObjectFileDB::get_objs_from_dgo(const std::string& filename) {
|
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();
|
stats.total_dgo_bytes += dgo_data.size();
|
||||||
|
|
||||||
const char jak2_header[] = "oZlB";
|
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_text = obj.linked_data.print_words();
|
||||||
auto file_name = combine_path(output_dir, obj.record.to_unique_name() + ".txt");
|
auto file_name = combine_path(output_dir, obj.record.to_unique_name() + ".txt");
|
||||||
total_bytes += file_text.size();
|
total_bytes += file_text.size();
|
||||||
write_text_file(file_name, file_text);
|
file_util::write_text_file(file_name, file_text);
|
||||||
total_files++;
|
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_text = obj.linked_data.print_disassembly();
|
||||||
auto file_name = combine_path(output_dir, obj.record.to_unique_name() + ".func");
|
auto file_name = combine_path(output_dir, obj.record.to_unique_name() + ".func");
|
||||||
total_bytes += file_text.size();
|
total_bytes += file_text.size();
|
||||||
write_text_file(file_name, file_text);
|
file_util::write_text_file(file_name, file_text);
|
||||||
total_files++;
|
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");
|
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("Found scripts:\n");
|
||||||
printf(" total %.3f ms\n", timer.getMs());
|
printf(" total %.3f ms\n", timer.getMs());
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "third-party/json.hpp"
|
#include "third-party/json.hpp"
|
||||||
#include "util/FileIO.h"
|
#include "util/FileIO.h"
|
||||||
|
#include "common/util/FileUtil.h"
|
||||||
|
|
||||||
Config gConfig;
|
Config gConfig;
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ Config& get_config() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_config(const std::string& path_to_config_file) {
|
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
|
// to ignore comments in json, which may be useful
|
||||||
auto cfg = nlohmann::json::parse(config_str, nullptr, true, true);
|
auto cfg = nlohmann::json::parse(config_str, nullptr, true, true);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "util/FileIO.h"
|
#include "util/FileIO.h"
|
||||||
#include "TypeSystem/TypeInfo.h"
|
#include "TypeSystem/TypeInfo.h"
|
||||||
|
#include "common/util/FileUtil.h"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
printf("Jak Disassembler\n");
|
printf("Jak Disassembler\n");
|
||||||
|
@ -26,8 +27,8 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectFileDB db(dgos);
|
ObjectFileDB db(dgos);
|
||||||
write_text_file(combine_path(out_folder, "dgo.txt"), db.generate_dgo_listing());
|
file_util::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, "obj.txt"), db.generate_obj_listing());
|
||||||
|
|
||||||
db.process_link_data();
|
db.process_link_data();
|
||||||
db.find_code();
|
db.find_code();
|
||||||
|
|
|
@ -3,35 +3,10 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cassert>
|
#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) {
|
std::string combine_path(const std::string& parent, const std::string& child) {
|
||||||
return parent + "/" + 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) {
|
std::string base_name(const std::string& filename) {
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
assert(!filename.empty());
|
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) {
|
uint32_t crc32(const std::vector<uint8_t>& data) {
|
||||||
return crc32(data.data(), data.size());
|
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 <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
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(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);
|
std::string base_name(const std::string& filename);
|
||||||
void write_text_file(const std::string& file_name, const std::string& text);
|
|
||||||
|
|
||||||
void init_crc();
|
void init_crc();
|
||||||
uint32_t crc32(const uint8_t* data, size_t size);
|
uint32_t crc32(const uint8_t* data, size_t size);
|
||||||
uint32_t crc32(const std::vector<uint8_t>& data);
|
uint32_t crc32(const std::vector<uint8_t>& data);
|
||||||
|
|
|
@ -78,8 +78,8 @@ add_library(runtime ${RUNTIME_SOURCE})
|
||||||
|
|
||||||
IF (WIN32)
|
IF (WIN32)
|
||||||
# set stuff for windows
|
# set stuff for windows
|
||||||
target_link_libraries(gk cross_sockets mman)
|
target_link_libraries(gk cross_sockets mman common_util)
|
||||||
ELSE()
|
ELSE()
|
||||||
# set stuff for other systems
|
# set stuff for other systems
|
||||||
target_link_libraries(gk cross_sockets pthread)
|
target_link_libraries(gk cross_sockets pthread common_util)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "game/sce/iop.h"
|
#include "game/sce/iop.h"
|
||||||
#include "isocommon.h"
|
#include "isocommon.h"
|
||||||
#include "overlord.h"
|
#include "overlord.h"
|
||||||
|
#include "common/util/FileUtil.h"
|
||||||
|
|
||||||
using namespace iop;
|
using namespace iop;
|
||||||
|
|
||||||
|
@ -71,25 +72,15 @@ void fake_iso_init_globals() {
|
||||||
read_in_progress = false;
|
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.
|
* Initialize the file system.
|
||||||
*/
|
*/
|
||||||
int FS_Init(u8* buffer) {
|
int FS_Init(u8* buffer) {
|
||||||
(void)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.
|
// get path to next/data/fake_iso.txt, the map file.
|
||||||
char fakeiso_path[512];
|
char fakeiso_path[512];
|
||||||
strcpy(fakeiso_path, next_dir);
|
strcpy(fakeiso_path, file_util::get_file_path({"game", "fake_iso.txt"}).c_str());
|
||||||
fake_iso_path = std::getenv("FAKE_ISO_PATH");
|
|
||||||
assert(fake_iso_path);
|
|
||||||
strcat(fakeiso_path, fake_iso_path);
|
|
||||||
|
|
||||||
// open the map.
|
// open the map.
|
||||||
FILE* fp = fopen(fakeiso_path, "r");
|
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) {
|
static const char* get_file_path(FileRecord* fr) {
|
||||||
assert(fr->location < fake_iso_entry_count);
|
assert(fr->location < fake_iso_entry_count);
|
||||||
static char path_buffer[1024];
|
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, "/");
|
||||||
strcat(path_buffer, fake_iso_entries[fr->location].file_path);
|
strcat(path_buffer, fake_iso_entries[fr->location].file_path);
|
||||||
return path_buffer;
|
return path_buffer;
|
||||||
|
|
2
gc.sh
2
gc.sh
|
@ -3,6 +3,4 @@
|
||||||
# Directory of this script
|
# Directory of this script
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
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 "$@"
|
$DIR/build/goalc/goalc "$@"
|
2
gk.sh
2
gk.sh
|
@ -3,6 +3,4 @@
|
||||||
# Directory of this script
|
# Directory of this script
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
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 "$@"
|
$DIR/build/game/gk "$@"
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
add_subdirectory(util)
|
|
||||||
add_subdirectory(goos)
|
add_subdirectory(goos)
|
||||||
add_subdirectory(listener)
|
add_subdirectory(listener)
|
||||||
|
|
||||||
|
@ -28,10 +27,10 @@ add_library(compiler
|
||||||
add_executable(goalc main.cpp)
|
add_executable(goalc main.cpp)
|
||||||
|
|
||||||
IF (WIN32)
|
IF (WIN32)
|
||||||
target_link_libraries(compiler util goos type_system listener mman)
|
target_link_libraries(compiler goos type_system listener mman common_util)
|
||||||
|
|
||||||
ELSE ()
|
ELSE ()
|
||||||
target_link_libraries(compiler util goos type_system listener)
|
target_link_libraries(compiler goos type_system listener common_util)
|
||||||
ENDIF ()
|
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"));
|
m_none = std::make_unique<None>(m_ts.make_typespec("none"));
|
||||||
|
|
||||||
// todo - compile library
|
// 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);
|
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);
|
auto compiled = compile_object_file("test-code", code, true);
|
||||||
color_object_file(compiled);
|
color_object_file(compiled);
|
||||||
auto data = codegen_object_file(compiled);
|
auto data = codegen_object_file(compiled);
|
||||||
|
|
|
@ -48,9 +48,8 @@ class Compiler {
|
||||||
void va_check(
|
void va_check(
|
||||||
const goos::Object& form,
|
const goos::Object& form,
|
||||||
const goos::Arguments& args,
|
const goos::Arguments& args,
|
||||||
const std::vector<util::MatchParam<goos::ObjectType>>& unnamed,
|
const std::vector<MatchParam<goos::ObjectType>>& unnamed,
|
||||||
const std::unordered_map<std::string, std::pair<bool, util::MatchParam<goos::ObjectType>>>&
|
const std::unordered_map<std::string, std::pair<bool, MatchParam<goos::ObjectType>>>& named);
|
||||||
named);
|
|
||||||
std::string as_string(const goos::Object& o);
|
std::string as_string(const goos::Object& o);
|
||||||
std::string symbol_string(const goos::Object& o);
|
std::string symbol_string(const goos::Object& o);
|
||||||
const goos::Object& pair_car(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(
|
void Compiler::va_check(
|
||||||
const goos::Object& form,
|
const goos::Object& form,
|
||||||
const goos::Arguments& args,
|
const goos::Arguments& args,
|
||||||
const std::vector<util::MatchParam<goos::ObjectType>>& unnamed,
|
const std::vector<MatchParam<goos::ObjectType>>& unnamed,
|
||||||
const std::unordered_map<std::string, std::pair<bool, util::MatchParam<goos::ObjectType>>>&
|
const std::unordered_map<std::string, std::pair<bool, MatchParam<goos::ObjectType>>>& named) {
|
||||||
named) {
|
|
||||||
assert(args.rest.empty());
|
assert(args.rest.empty());
|
||||||
if (unnamed.size() != args.unnamed.size()) {
|
if (unnamed.size() != args.unnamed.size()) {
|
||||||
throw_compile_error(form, "Got " + std::to_string(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/Compiler.h"
|
||||||
#include "goalc/compiler/IR.h"
|
#include "goalc/compiler/IR.h"
|
||||||
#include "goalc/util/Timer.h"
|
#include "common/util/Timer.h"
|
||||||
#include "goalc/util/file_io.h"
|
#include "common/util/FileUtil.h"
|
||||||
|
|
||||||
Val* Compiler::compile_exit(const goos::Object& form, const goos::Object& rest, Env* env) {
|
Val* Compiler::compile_exit(const goos::Object& form, const goos::Object& rest, Env* env) {
|
||||||
(void)env;
|
(void)env;
|
||||||
|
@ -59,7 +59,7 @@ Val* Compiler::compile_asm_file(const goos::Object& form, const goos::Object& re
|
||||||
});
|
});
|
||||||
|
|
||||||
Timer reader_timer;
|
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());
|
timing.emplace_back("read", reader_timer.getMs());
|
||||||
|
|
||||||
Timer compile_timer;
|
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*"));
|
// auto output_dir = as_string(get_constant_or_error(form, "*compiler-output-path*"));
|
||||||
// todo, change extension based on v3/v4
|
// todo, change extension based on v3/v4
|
||||||
auto output_name = m_goos.reader.get_source_dir() + "/out/" + obj_file_name + ".o";
|
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 {
|
} else {
|
||||||
if (load) {
|
if (load) {
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
add_library(goos SHARED Object.cpp TextDB.cpp Reader.cpp Interpreter.cpp InterpreterEval.cpp)
|
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(
|
void Interpreter::vararg_check(
|
||||||
const Object& form,
|
const Object& form,
|
||||||
const Arguments& args,
|
const Arguments& args,
|
||||||
const std::vector<util::MatchParam<ObjectType>>& unnamed,
|
const std::vector<MatchParam<ObjectType>>& unnamed,
|
||||||
const std::unordered_map<std::string, std::pair<bool, util::MatchParam<ObjectType>>>& named) {
|
const std::unordered_map<std::string, std::pair<bool, MatchParam<ObjectType>>>& named) {
|
||||||
assert(args.rest.empty());
|
assert(args.rest.empty());
|
||||||
if (unnamed.size() != args.unnamed.size()) {
|
if (unnamed.size() != args.unnamed.size()) {
|
||||||
throw_eval_error(form, "Got " + std::to_string(args.unnamed.size()) +
|
throw_eval_error(form, "Got " + std::to_string(args.unnamed.size()) +
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "Reader.h"
|
#include "Reader.h"
|
||||||
#include "goalc/util/MatchParam.h"
|
#include "common/util/MatchParam.h"
|
||||||
|
|
||||||
namespace goos {
|
namespace goos {
|
||||||
class Interpreter {
|
class Interpreter {
|
||||||
|
@ -53,8 +53,8 @@ class Interpreter {
|
||||||
void vararg_check(
|
void vararg_check(
|
||||||
const Object& form,
|
const Object& form,
|
||||||
const Arguments& args,
|
const Arguments& args,
|
||||||
const std::vector<util::MatchParam<ObjectType>>& unnamed,
|
const std::vector<MatchParam<ObjectType>>& unnamed,
|
||||||
const std::unordered_map<std::string, std::pair<bool, util::MatchParam<ObjectType>>>& named);
|
const std::unordered_map<std::string, std::pair<bool, MatchParam<ObjectType>>>& named);
|
||||||
|
|
||||||
Object eval_pair(const Object& o, const std::shared_ptr<EnvironmentObject>& env);
|
Object eval_pair(const Object& o, const std::shared_ptr<EnvironmentObject>& env);
|
||||||
void eval_args(Arguments* args, 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}, {});
|
vararg_check(form, args, {ObjectType::STRING}, {});
|
||||||
|
|
||||||
try {
|
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) {
|
} catch (std::runtime_error& e) {
|
||||||
throw_eval_error(form, std::string("reader error inside of read-file:\n") + e.what());
|
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;
|
Object o;
|
||||||
try {
|
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) {
|
} catch (std::runtime_error& e) {
|
||||||
throw_eval_error(form, std::string("reader error inside of load-file:\n") + e.what());
|
throw_eval_error(form, std::string("reader error inside of load-file:\n") + e.what());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "goalc/util/text_util.h"
|
#include "common/util/FileUtil.h"
|
||||||
|
|
||||||
namespace goos {
|
namespace goos {
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ std::string fixed_to_string(FloatType x) {
|
||||||
template <>
|
template <>
|
||||||
std::string fixed_to_string(char x) {
|
std::string fixed_to_string(char x) {
|
||||||
char buff[256];
|
char buff[256];
|
||||||
if (util::is_printable_char(x) && x != ' ') {
|
if (file_util::is_printable_char(x) && x != ' ') {
|
||||||
// can print directly
|
// can print directly
|
||||||
sprintf(buff, "#\\%c", x);
|
sprintf(buff, "#\\%c", x);
|
||||||
return {buff};
|
return {buff};
|
||||||
|
|
|
@ -11,8 +11,7 @@
|
||||||
|
|
||||||
#include "Reader.h"
|
#include "Reader.h"
|
||||||
#include "third-party/linenoise.h"
|
#include "third-party/linenoise.h"
|
||||||
#include "goalc/util/file_io.h"
|
#include "common/util/FileUtil.h"
|
||||||
#include "goalc/util/text_util.h"
|
|
||||||
|
|
||||||
namespace goos {
|
namespace goos {
|
||||||
|
|
||||||
|
@ -98,15 +97,6 @@ Reader::Reader() {
|
||||||
for (const char* c = bonus; *c; c++) {
|
for (const char* c = bonus; *c; c++) {
|
||||||
valid_symbols_chars[(int)*c] = true;
|
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
|
* Read a file
|
||||||
*/
|
*/
|
||||||
Object Reader::read_from_file(const std::string& filename) {
|
Object Reader::read_from_file(const std::vector<std::string>& file_path) {
|
||||||
auto textFrag = std::make_shared<FileText>(util::combine_path(get_source_dir(), filename));
|
auto textFrag = std::make_shared<FileText>(file_util::get_file_path(file_path));
|
||||||
db.insert(textFrag);
|
db.insert(textFrag);
|
||||||
|
|
||||||
auto result = internal_read(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) {
|
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 && 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]);
|
obj = Object::make_char(tok.text[2]);
|
||||||
return true;
|
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.
|
* Get the source directory of the current project.
|
||||||
*/
|
*/
|
||||||
std::string Reader::get_source_dir() {
|
std::string Reader::get_source_dir() {
|
||||||
return source_dir;
|
return file_util::get_project_path();
|
||||||
}
|
}
|
||||||
} // namespace goos
|
} // namespace goos
|
||||||
|
|
|
@ -70,7 +70,7 @@ class Reader {
|
||||||
Reader();
|
Reader();
|
||||||
Object read_from_string(const std::string& str);
|
Object read_from_string(const std::string& str);
|
||||||
Object read_from_stdin(const std::string& prompt_name);
|
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();
|
std::string get_source_dir();
|
||||||
|
|
||||||
|
@ -97,7 +97,6 @@ class Reader {
|
||||||
|
|
||||||
char valid_symbols_chars[256];
|
char valid_symbols_chars[256];
|
||||||
|
|
||||||
std::string source_dir;
|
|
||||||
std::unordered_map<std::string, std::string> reader_macros;
|
std::unordered_map<std::string, std::string> reader_macros;
|
||||||
};
|
};
|
||||||
} // namespace goos
|
} // namespace goos
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
* (+ 1 (+ a b)) ; compute the sum
|
* (+ 1 (+ a b)) ; compute the sum
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "goalc/util/file_io.h"
|
#include "common/util/FileUtil.h"
|
||||||
|
|
||||||
#include "TextDB.h"
|
#include "TextDB.h"
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ std::pair<int, int> SourceText::get_containing_line(int offset) {
|
||||||
* Read text from a file.
|
* Read text from a file.
|
||||||
*/
|
*/
|
||||||
FileText::FileText(std::string filename_) : filename(std::move(filename_)) {
|
FileText::FileText(std::string filename_) : filename(std::move(filename_)) {
|
||||||
text = util::read_text_file(filename);
|
text = file_util::read_text_file(filename);
|
||||||
build_offsets();
|
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]);
|
printf("Got version %d.%d", version_buffer[0], version_buffer[1]);
|
||||||
if (version_buffer[0] == GOAL_VERSION_MAJOR && version_buffer[1] == GOAL_VERSION_MINOR) {
|
if (version_buffer[0] == GOAL_VERSION_MAJOR && version_buffer[1] == GOAL_VERSION_MINOR) {
|
||||||
printf(" OK!\n");
|
printf(" OK!\n");
|
||||||
rcv_thread = std::thread(&Listener::receive_func, this);
|
|
||||||
m_connected = true;
|
m_connected = true;
|
||||||
|
rcv_thread = std::thread(&Listener::receive_func, this);
|
||||||
receive_thread_running = true;
|
receive_thread_running = true;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -189,10 +189,9 @@ void Listener::receive_func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ListenerMessageHeader* hdr = (ListenerMessageHeader*)buff;
|
ListenerMessageHeader* hdr = (ListenerMessageHeader*)buff;
|
||||||
// if(debug_listener) {
|
if (debug_listener) {
|
||||||
// printf("[T -> L] received %d bytes, kind %d\n",
|
printf("[T -> L] received %d bytes, kind %d\n", hdr->deci2_header.len, int(hdr->msg_kind));
|
||||||
// hdr->deci2_hdr.len, hdr->msg_kind);
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
switch (hdr->msg_kind) {
|
switch (hdr->msg_kind) {
|
||||||
case ListenerMessageKind::MSG_ACK:
|
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
|
# Directory of this script
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
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
|
cd $DIR/build/test
|
||||||
make init
|
make init
|
||||||
make gcov
|
make gcov
|
||||||
|
|
2
test.sh
2
test.sh
|
@ -3,6 +3,4 @@
|
||||||
# Directory of this script
|
# Directory of this script
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
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 "$@"
|
$DIR/build/test/goalc-test --gtest_color=yes "$@"
|
||||||
|
|
|
@ -22,9 +22,9 @@ IF (WIN32)
|
||||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
# TODO - split out these declarations for platform specific includes
|
# 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()
|
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()
|
ENDIF()
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX AND CODE_COVERAGE)
|
if(CMAKE_COMPILER_IS_GNUCXX AND CODE_COVERAGE)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
TEST(FileUtil, valid_path) {
|
TEST(FileUtil, valid_path) {
|
||||||
std::vector<std::string> test = {"cabbage", "banana", "apple"};
|
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;
|
// std::cout << sampleString << std::endl;
|
||||||
|
|
||||||
EXPECT_TRUE(true);
|
EXPECT_TRUE(true);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "goalc/goos/Reader.h"
|
#include "goalc/goos/Reader.h"
|
||||||
#include "goalc/util/file_io.h"
|
#include "common/util/FileUtil.h"
|
||||||
|
|
||||||
using namespace goos;
|
using namespace goos;
|
||||||
|
|
||||||
|
@ -316,16 +316,16 @@ TEST(GoosReader, TopLevel) {
|
||||||
|
|
||||||
TEST(GoosReader, FromFile) {
|
TEST(GoosReader, FromFile) {
|
||||||
Reader reader;
|
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))");
|
EXPECT_TRUE(result == "(top-level (1 2 3 4))");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(GoosReader, TextDb) {
|
TEST(GoosReader, TextDb) {
|
||||||
// very specific to this particular test file, but whatever.
|
// very specific to this particular test file, but whatever.
|
||||||
Reader reader;
|
Reader reader;
|
||||||
auto file_path = util::combine_path({"test", "test_reader_file0.gc"});
|
auto result =
|
||||||
auto result = reader.read_from_file(file_path).as_pair()->cdr.as_pair()->car;
|
reader.read_from_file({"test", "test_reader_file0.gc"}).as_pair()->cdr.as_pair()->car;
|
||||||
std::string expected = "text from " + util::combine_path(reader.get_source_dir(), file_path) +
|
std::string expected = "text from " + file_util::get_file_path({"test", "test_reader_file0.gc"}) +
|
||||||
", line: 5\n(1 2 3 4)\n";
|
", line: 5\n(1 2 3 4)\n";
|
||||||
EXPECT_EQ(expected, reader.db.get_info_for(result));
|
EXPECT_EQ(expected, reader.db.get_info_for(result));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,5 @@
|
||||||
# Directory of this script
|
# Directory of this script
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
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/
|
cd $DIR/build/
|
||||||
make goalc-test_coverage
|
make goalc-test_coverage
|
||||||
|
|
Loading…
Reference in a new issue