Last bit of string cleanup. string.h finally gone.
This commit is contained in:
parent
383d3acbb0
commit
24fe169f36
|
@ -45,7 +45,7 @@ int FinalizationPass::Run(HIRBuilder* builder) {
|
||||||
if (!label->name) {
|
if (!label->name) {
|
||||||
const size_t label_len = 6 + 4 + 1;
|
const size_t label_len = 6 + 4 + 1;
|
||||||
char* name = (char*)arena->Alloc(label_len);
|
char* name = (char*)arena->Alloc(label_len);
|
||||||
xesnprintfa(name, label_len, "_label%d", label->id);
|
snprintf(name, label_len, "_label%d", label->id);
|
||||||
label->name = name;
|
label->name = name;
|
||||||
}
|
}
|
||||||
label = label->next;
|
label = label->next;
|
||||||
|
|
|
@ -32,7 +32,7 @@ bool PPCContext::CompareRegWithString(const char* name, const char* value,
|
||||||
if (sscanf(name, "r%d", &n) == 1) {
|
if (sscanf(name, "r%d", &n) == 1) {
|
||||||
uint64_t expected = ParseInt64(value);
|
uint64_t expected = ParseInt64(value);
|
||||||
if (this->r[n] != expected) {
|
if (this->r[n] != expected) {
|
||||||
xesnprintfa(out_value, out_value_size, "%016llX", this->r[n]);
|
snprintf(out_value, out_value_size, "%016llX", this->r[n]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -294,7 +294,7 @@ void Disasm_bcx(InstrData& i, StringBuffer* str) {
|
||||||
}
|
}
|
||||||
char s2[8] = {0};
|
char s2[8] = {0};
|
||||||
if (!select_bits(i.B.BO, 4, 4)) {
|
if (!select_bits(i.B.BO, 4, 4)) {
|
||||||
xesnprintfa(s2, poly::countof(s2), "cr%d, ", i.B.BI >> 2);
|
snprintf(s2, poly::countof(s2), "cr%d, ", i.B.BI >> 2);
|
||||||
}
|
}
|
||||||
uint32_t nia;
|
uint32_t nia;
|
||||||
if (i.B.AA) {
|
if (i.B.AA) {
|
||||||
|
@ -310,7 +310,7 @@ void Disasm_bcctrx(InstrData& i, StringBuffer* str) {
|
||||||
const char* s0 = i.XL.LK ? "lr, " : "";
|
const char* s0 = i.XL.LK ? "lr, " : "";
|
||||||
char s2[8] = {0};
|
char s2[8] = {0};
|
||||||
if (!select_bits(i.XL.BO, 4, 4)) {
|
if (!select_bits(i.XL.BO, 4, 4)) {
|
||||||
xesnprintfa(s2, poly::countof(s2), "cr%d, ", i.XL.BI >> 2);
|
snprintf(s2, poly::countof(s2), "cr%d, ", i.XL.BI >> 2);
|
||||||
}
|
}
|
||||||
str->Append("%-8s %s%sctr", i.type->name, s0, s2);
|
str->Append("%-8s %s%sctr", i.type->name, s0, s2);
|
||||||
// TODO(benvanik): resolve target name?
|
// TODO(benvanik): resolve target name?
|
||||||
|
@ -328,7 +328,7 @@ void Disasm_bclrx(InstrData& i, StringBuffer* str) {
|
||||||
}
|
}
|
||||||
char s2[8] = {0};
|
char s2[8] = {0};
|
||||||
if (!select_bits(i.XL.BO, 4, 4)) {
|
if (!select_bits(i.XL.BO, 4, 4)) {
|
||||||
xesnprintfa(s2, poly::countof(s2), "cr%d, ", i.XL.BI >> 2);
|
snprintf(s2, poly::countof(s2), "cr%d, ", i.XL.BI >> 2);
|
||||||
}
|
}
|
||||||
str->Append("%-8s %s%s", name, s1, s2);
|
str->Append("%-8s %s%s", name, s1, s2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
|
||||||
|
|
||||||
void PPCHIRBuilder::AnnotateLabel(uint64_t address, Label* label) {
|
void PPCHIRBuilder::AnnotateLabel(uint64_t address, Label* label) {
|
||||||
char name_buffer[13];
|
char name_buffer[13];
|
||||||
xesnprintfa(name_buffer, poly::countof(name_buffer), "loc_%.8X",
|
snprintf(name_buffer, poly::countof(name_buffer), "loc_%.8X",
|
||||||
(uint32_t)address);
|
(uint32_t)address);
|
||||||
label->name = (char*)arena_->Alloc(sizeof(name_buffer));
|
label->name = (char*)arena_->Alloc(sizeof(name_buffer));
|
||||||
xe_copy_struct(label->name, name_buffer, sizeof(name_buffer));
|
xe_copy_struct(label->name, name_buffer, sizeof(name_buffer));
|
||||||
|
|
|
@ -30,28 +30,28 @@ void InstrOperand::Dump(std::string& out_str) {
|
||||||
case InstrOperand::kRegister:
|
case InstrOperand::kRegister:
|
||||||
switch (reg.set) {
|
switch (reg.set) {
|
||||||
case InstrRegister::kXER:
|
case InstrRegister::kXER:
|
||||||
xesnprintfa(buffer, max_count, "XER");
|
snprintf(buffer, max_count, "XER");
|
||||||
break;
|
break;
|
||||||
case InstrRegister::kLR:
|
case InstrRegister::kLR:
|
||||||
xesnprintfa(buffer, max_count, "LR");
|
snprintf(buffer, max_count, "LR");
|
||||||
break;
|
break;
|
||||||
case InstrRegister::kCTR:
|
case InstrRegister::kCTR:
|
||||||
xesnprintfa(buffer, max_count, "CTR");
|
snprintf(buffer, max_count, "CTR");
|
||||||
break;
|
break;
|
||||||
case InstrRegister::kCR:
|
case InstrRegister::kCR:
|
||||||
xesnprintfa(buffer, max_count, "CR%d", reg.ordinal);
|
snprintf(buffer, max_count, "CR%d", reg.ordinal);
|
||||||
break;
|
break;
|
||||||
case InstrRegister::kFPSCR:
|
case InstrRegister::kFPSCR:
|
||||||
xesnprintfa(buffer, max_count, "FPSCR");
|
snprintf(buffer, max_count, "FPSCR");
|
||||||
break;
|
break;
|
||||||
case InstrRegister::kGPR:
|
case InstrRegister::kGPR:
|
||||||
xesnprintfa(buffer, max_count, "r%d", reg.ordinal);
|
snprintf(buffer, max_count, "r%d", reg.ordinal);
|
||||||
break;
|
break;
|
||||||
case InstrRegister::kFPR:
|
case InstrRegister::kFPR:
|
||||||
xesnprintfa(buffer, max_count, "f%d", reg.ordinal);
|
snprintf(buffer, max_count, "f%d", reg.ordinal);
|
||||||
break;
|
break;
|
||||||
case InstrRegister::kVMX:
|
case InstrRegister::kVMX:
|
||||||
xesnprintfa(buffer, max_count, "vr%d", reg.ordinal);
|
snprintf(buffer, max_count, "vr%d", reg.ordinal);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -59,30 +59,30 @@ void InstrOperand::Dump(std::string& out_str) {
|
||||||
switch (imm.width) {
|
switch (imm.width) {
|
||||||
case 1:
|
case 1:
|
||||||
if (imm.is_signed) {
|
if (imm.is_signed) {
|
||||||
xesnprintfa(buffer, max_count, "%d", (int32_t)(int8_t)imm.value);
|
snprintf(buffer, max_count, "%d", (int32_t)(int8_t)imm.value);
|
||||||
} else {
|
} else {
|
||||||
xesnprintfa(buffer, max_count, "0x%.2X", (uint8_t)imm.value);
|
snprintf(buffer, max_count, "0x%.2X", (uint8_t)imm.value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (imm.is_signed) {
|
if (imm.is_signed) {
|
||||||
xesnprintfa(buffer, max_count, "%d", (int32_t)(int16_t)imm.value);
|
snprintf(buffer, max_count, "%d", (int32_t)(int16_t)imm.value);
|
||||||
} else {
|
} else {
|
||||||
xesnprintfa(buffer, max_count, "0x%.4X", (uint16_t)imm.value);
|
snprintf(buffer, max_count, "0x%.4X", (uint16_t)imm.value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if (imm.is_signed) {
|
if (imm.is_signed) {
|
||||||
xesnprintfa(buffer, max_count, "%d", (int32_t)imm.value);
|
snprintf(buffer, max_count, "%d", (int32_t)imm.value);
|
||||||
} else {
|
} else {
|
||||||
xesnprintfa(buffer, max_count, "0x%.8X", (uint32_t)imm.value);
|
snprintf(buffer, max_count, "0x%.8X", (uint32_t)imm.value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
if (imm.is_signed) {
|
if (imm.is_signed) {
|
||||||
xesnprintfa(buffer, max_count, "%lld", (int64_t)imm.value);
|
snprintf(buffer, max_count, "%lld", (int64_t)imm.value);
|
||||||
} else {
|
} else {
|
||||||
xesnprintfa(buffer, max_count, "0x%.16llX", imm.value);
|
snprintf(buffer, max_count, "0x%.16llX", imm.value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -625,7 +625,7 @@ void HIRBuilder::Comment(const char* format, ...) {
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
xevsnprintfa(buffer, 1024, format, args);
|
vsnprintf(buffer, 1024, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
size_t len = strlen(buffer);
|
size_t len = strlen(buffer);
|
||||||
if (!len) {
|
if (!len) {
|
||||||
|
|
|
@ -51,6 +51,22 @@ std::wstring to_absolute_path(const std::wstring& path) {
|
||||||
#endif // XE_LIKE_WIN32
|
#endif // XE_LIKE_WIN32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> split_path(const std::string& path) {
|
||||||
|
std::vector<std::string> parts;
|
||||||
|
size_t n = 0;
|
||||||
|
size_t last = 0;
|
||||||
|
while ((n = path.find_first_of("\\/", last)) != path.npos) {
|
||||||
|
if (last != n) {
|
||||||
|
parts.push_back(path.substr(last, n - last));
|
||||||
|
}
|
||||||
|
last = n + 1;
|
||||||
|
}
|
||||||
|
if (last != path.size()) {
|
||||||
|
parts.push_back(path.substr(last));
|
||||||
|
}
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
|
|
||||||
std::wstring join_paths(const std::wstring& left, const std::wstring& right,
|
std::wstring join_paths(const std::wstring& left, const std::wstring& right,
|
||||||
wchar_t sep) {
|
wchar_t sep) {
|
||||||
if (!left.size()) {
|
if (!left.size()) {
|
||||||
|
|
|
@ -10,13 +10,16 @@
|
||||||
#ifndef POLY_STRING_H_
|
#ifndef POLY_STRING_H_
|
||||||
#define POLY_STRING_H_
|
#define POLY_STRING_H_
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <poly/platform.h>
|
#include <poly/platform.h>
|
||||||
|
|
||||||
#if XE_LIKE_WIN32
|
#if XE_LIKE_WIN32
|
||||||
#define strcasecmp _stricmp
|
#define strcasecmp _stricmp
|
||||||
#define strncasecmp _strnicmp
|
#define strncasecmp _strnicmp
|
||||||
|
#define snprintf _snprintf
|
||||||
#endif // XE_LIKE_WIN32
|
#endif // XE_LIKE_WIN32
|
||||||
|
|
||||||
namespace poly {
|
namespace poly {
|
||||||
|
@ -31,6 +34,9 @@ std::string::size_type find_first_of_case(const std::string& target,
|
||||||
// Converts the given path to an absolute path based on cwd.
|
// Converts the given path to an absolute path based on cwd.
|
||||||
std::wstring to_absolute_path(const std::wstring& path);
|
std::wstring to_absolute_path(const std::wstring& path);
|
||||||
|
|
||||||
|
// Splits the given path on any valid path separator and returns all parts.
|
||||||
|
std::vector<std::string> split_path(const std::string& path);
|
||||||
|
|
||||||
// Joins two path segments with the given separator.
|
// Joins two path segments with the given separator.
|
||||||
std::wstring join_paths(const std::wstring& left, const std::wstring& right,
|
std::wstring join_paths(const std::wstring& left, const std::wstring& right,
|
||||||
wchar_t sep = poly::path_separator);
|
wchar_t sep = poly::path_separator);
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
#include <poly/atomic.h>
|
#include <poly/atomic.h>
|
||||||
#include <poly/byte_order.h>
|
#include <poly/byte_order.h>
|
||||||
#include <poly/memory.h>
|
#include <poly/memory.h>
|
||||||
|
#include <poly/string.h>
|
||||||
|
|
||||||
#include <xenia/logging.h>
|
#include <xenia/logging.h>
|
||||||
#include <xenia/malloc.h>
|
#include <xenia/malloc.h>
|
||||||
#include <xenia/profiling.h>
|
#include <xenia/profiling.h>
|
||||||
#include <xenia/string.h>
|
|
||||||
#include <xenia/types.h>
|
#include <xenia/types.h>
|
||||||
|
|
||||||
#endif // XENIA_COMMON_H_
|
#endif // XENIA_COMMON_H_
|
||||||
|
|
|
@ -22,7 +22,7 @@ typedef enum {
|
||||||
kXEFileModeWrite = (1 << 1),
|
kXEFileModeWrite = (1 << 1),
|
||||||
} xe_file_mode;
|
} xe_file_mode;
|
||||||
|
|
||||||
xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const xechar_t *path,
|
xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const wchar_t *path,
|
||||||
const size_t offset, const size_t length);
|
const size_t offset, const size_t length);
|
||||||
xe_mmap_ref xe_mmap_retain(xe_mmap_ref mmap);
|
xe_mmap_ref xe_mmap_retain(xe_mmap_ref mmap);
|
||||||
void xe_mmap_release(xe_mmap_ref mmap);
|
void xe_mmap_release(xe_mmap_ref mmap);
|
||||||
|
|
|
@ -21,7 +21,7 @@ typedef struct xe_mmap {
|
||||||
} xe_mmap_t;
|
} xe_mmap_t;
|
||||||
|
|
||||||
|
|
||||||
xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const xechar_t *path,
|
xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const wchar_t *path,
|
||||||
const size_t offset, const size_t length) {
|
const size_t offset, const size_t length) {
|
||||||
xe_mmap_ref mmap = (xe_mmap_ref)xe_calloc(sizeof(xe_mmap_t));
|
xe_mmap_ref mmap = (xe_mmap_ref)xe_calloc(sizeof(xe_mmap_t));
|
||||||
xe_ref_init((xe_ref)mmap);
|
xe_ref_init((xe_ref)mmap);
|
||||||
|
|
|
@ -114,12 +114,12 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
|
||||||
|
|
||||||
if (kernel_export) {
|
if (kernel_export) {
|
||||||
if (info->thunk_address) {
|
if (info->thunk_address) {
|
||||||
xesnprintfa(name, poly::countof(name), "__imp_%s", kernel_export->name);
|
snprintf(name, poly::countof(name), "__imp_%s", kernel_export->name);
|
||||||
} else {
|
} else {
|
||||||
xesnprintfa(name, poly::countof(name), "%s", kernel_export->name);
|
snprintf(name, poly::countof(name), "%s", kernel_export->name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xesnprintfa(name, poly::countof(name), "__imp_%s_%.3X", library->name,
|
snprintf(name, poly::countof(name), "__imp_%s_%.3X", library->name,
|
||||||
info->ordinal);
|
info->ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,10 +159,10 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
|
||||||
|
|
||||||
if (info->thunk_address) {
|
if (info->thunk_address) {
|
||||||
if (kernel_export) {
|
if (kernel_export) {
|
||||||
xesnprintfa(name, poly::countof(name), "%s", kernel_export->name);
|
snprintf(name, poly::countof(name), "%s", kernel_export->name);
|
||||||
} else {
|
} else {
|
||||||
xesnprintfa(name, poly::countof(name), "__kernel_%s_%.3X",
|
snprintf(name, poly::countof(name), "__kernel_%s_%.3X", library->name,
|
||||||
library->name, info->ordinal);
|
info->ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// On load we have something like this in memory:
|
// On load we have something like this in memory:
|
||||||
|
@ -423,7 +423,7 @@ int XexModule::FindSaveRest() {
|
||||||
if (gplr_start) {
|
if (gplr_start) {
|
||||||
uint64_t address = gplr_start;
|
uint64_t address = gplr_start;
|
||||||
for (int n = 14; n <= 31; n++) {
|
for (int n = 14; n <= 31; n++) {
|
||||||
xesnprintfa(name, poly::countof(name), "__savegprlr_%d", n);
|
snprintf(name, poly::countof(name), "__savegprlr_%d", n);
|
||||||
FunctionInfo* symbol_info;
|
FunctionInfo* symbol_info;
|
||||||
DeclareFunction(address, &symbol_info);
|
DeclareFunction(address, &symbol_info);
|
||||||
symbol_info->set_end_address(address + (31 - n) * 4 + 2 * 4);
|
symbol_info->set_end_address(address + (31 - n) * 4 + 2 * 4);
|
||||||
|
@ -436,7 +436,7 @@ int XexModule::FindSaveRest() {
|
||||||
}
|
}
|
||||||
address = gplr_start + 20 * 4;
|
address = gplr_start + 20 * 4;
|
||||||
for (int n = 14; n <= 31; n++) {
|
for (int n = 14; n <= 31; n++) {
|
||||||
xesnprintfa(name, poly::countof(name), "__restgprlr_%d", n);
|
snprintf(name, poly::countof(name), "__restgprlr_%d", n);
|
||||||
FunctionInfo* symbol_info;
|
FunctionInfo* symbol_info;
|
||||||
DeclareFunction(address, &symbol_info);
|
DeclareFunction(address, &symbol_info);
|
||||||
symbol_info->set_end_address(address + (31 - n) * 4 + 3 * 4);
|
symbol_info->set_end_address(address + (31 - n) * 4 + 3 * 4);
|
||||||
|
@ -451,7 +451,7 @@ int XexModule::FindSaveRest() {
|
||||||
if (fpr_start) {
|
if (fpr_start) {
|
||||||
uint64_t address = fpr_start;
|
uint64_t address = fpr_start;
|
||||||
for (int n = 14; n <= 31; n++) {
|
for (int n = 14; n <= 31; n++) {
|
||||||
xesnprintfa(name, poly::countof(name), "__savefpr_%d", n);
|
snprintf(name, poly::countof(name), "__savefpr_%d", n);
|
||||||
FunctionInfo* symbol_info;
|
FunctionInfo* symbol_info;
|
||||||
DeclareFunction(address, &symbol_info);
|
DeclareFunction(address, &symbol_info);
|
||||||
symbol_info->set_end_address(address + (31 - n) * 4 + 1 * 4);
|
symbol_info->set_end_address(address + (31 - n) * 4 + 1 * 4);
|
||||||
|
@ -464,7 +464,7 @@ int XexModule::FindSaveRest() {
|
||||||
}
|
}
|
||||||
address = fpr_start + (18 * 4) + (1 * 4);
|
address = fpr_start + (18 * 4) + (1 * 4);
|
||||||
for (int n = 14; n <= 31; n++) {
|
for (int n = 14; n <= 31; n++) {
|
||||||
xesnprintfa(name, poly::countof(name), "__restfpr_%d", n);
|
snprintf(name, poly::countof(name), "__restfpr_%d", n);
|
||||||
FunctionInfo* symbol_info;
|
FunctionInfo* symbol_info;
|
||||||
DeclareFunction(address, &symbol_info);
|
DeclareFunction(address, &symbol_info);
|
||||||
symbol_info->set_end_address(address + (31 - n) * 4 + 1 * 4);
|
symbol_info->set_end_address(address + (31 - n) * 4 + 1 * 4);
|
||||||
|
@ -484,7 +484,7 @@ int XexModule::FindSaveRest() {
|
||||||
// 64-127 rest
|
// 64-127 rest
|
||||||
uint64_t address = vmx_start;
|
uint64_t address = vmx_start;
|
||||||
for (int n = 14; n <= 31; n++) {
|
for (int n = 14; n <= 31; n++) {
|
||||||
xesnprintfa(name, poly::countof(name), "__savevmx_%d", n);
|
snprintf(name, poly::countof(name), "__savevmx_%d", n);
|
||||||
FunctionInfo* symbol_info;
|
FunctionInfo* symbol_info;
|
||||||
DeclareFunction(address, &symbol_info);
|
DeclareFunction(address, &symbol_info);
|
||||||
symbol_info->set_name(name);
|
symbol_info->set_name(name);
|
||||||
|
@ -496,7 +496,7 @@ int XexModule::FindSaveRest() {
|
||||||
}
|
}
|
||||||
address += 4;
|
address += 4;
|
||||||
for (int n = 64; n <= 127; n++) {
|
for (int n = 64; n <= 127; n++) {
|
||||||
xesnprintfa(name, poly::countof(name), "__savevmx_%d", n);
|
snprintf(name, poly::countof(name), "__savevmx_%d", n);
|
||||||
FunctionInfo* symbol_info;
|
FunctionInfo* symbol_info;
|
||||||
DeclareFunction(address, &symbol_info);
|
DeclareFunction(address, &symbol_info);
|
||||||
symbol_info->set_name(name);
|
symbol_info->set_name(name);
|
||||||
|
@ -508,7 +508,7 @@ int XexModule::FindSaveRest() {
|
||||||
}
|
}
|
||||||
address = vmx_start + (18 * 2 * 4) + (1 * 4) + (64 * 2 * 4) + (1 * 4);
|
address = vmx_start + (18 * 2 * 4) + (1 * 4) + (64 * 2 * 4) + (1 * 4);
|
||||||
for (int n = 14; n <= 31; n++) {
|
for (int n = 14; n <= 31; n++) {
|
||||||
xesnprintfa(name, poly::countof(name), "__restvmx_%d", n);
|
snprintf(name, poly::countof(name), "__restvmx_%d", n);
|
||||||
FunctionInfo* symbol_info;
|
FunctionInfo* symbol_info;
|
||||||
DeclareFunction(address, &symbol_info);
|
DeclareFunction(address, &symbol_info);
|
||||||
symbol_info->set_name(name);
|
symbol_info->set_name(name);
|
||||||
|
@ -520,7 +520,7 @@ int XexModule::FindSaveRest() {
|
||||||
}
|
}
|
||||||
address += 4;
|
address += 4;
|
||||||
for (int n = 64; n <= 127; n++) {
|
for (int n = 64; n <= 127; n++) {
|
||||||
xesnprintfa(name, poly::countof(name), "__restvmx_%d", n);
|
snprintf(name, poly::countof(name), "__restvmx_%d", n);
|
||||||
FunctionInfo* symbol_info;
|
FunctionInfo* symbol_info;
|
||||||
DeclareFunction(address, &symbol_info);
|
DeclareFunction(address, &symbol_info);
|
||||||
symbol_info->set_name(name);
|
symbol_info->set_name(name);
|
||||||
|
|
|
@ -11,92 +11,87 @@
|
||||||
|
|
||||||
#include <poly/math.h>
|
#include <poly/math.h>
|
||||||
|
|
||||||
using namespace xe;
|
namespace xe {
|
||||||
|
|
||||||
|
ExportResolver::ExportResolver() {}
|
||||||
|
|
||||||
ExportResolver::ExportResolver() {
|
ExportResolver::~ExportResolver() {}
|
||||||
}
|
|
||||||
|
|
||||||
ExportResolver::~ExportResolver() {
|
void ExportResolver::RegisterTable(const std::string& library_name,
|
||||||
}
|
KernelExport* exports, const size_t count) {
|
||||||
|
tables_.emplace_back(library_name, exports, count);
|
||||||
void ExportResolver::RegisterTable(
|
|
||||||
const char* library_name, KernelExport* exports, const size_t count) {
|
|
||||||
ExportTable table;
|
|
||||||
xestrcpya(table.name, poly::countof(table.name), library_name);
|
|
||||||
table.exports = exports;
|
|
||||||
table.count = count;
|
|
||||||
tables_.push_back(table);
|
|
||||||
|
|
||||||
for (size_t n = 0; n < count; n++) {
|
for (size_t n = 0; n < count; n++) {
|
||||||
exports[n].is_implemented = false;
|
exports[n].is_implemented = false;
|
||||||
exports[n].variable_ptr = 0;
|
exports[n].variable_ptr = 0;
|
||||||
exports[n].function_data.shim_data = NULL;
|
exports[n].function_data.shim_data = nullptr;
|
||||||
exports[n].function_data.shim = NULL;
|
exports[n].function_data.shim = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ExportResolver::GetLibraryOrdinal(const char* library_name) {
|
uint16_t ExportResolver::GetLibraryOrdinal(const std::string& library_name) {
|
||||||
uint16_t n = 0;
|
uint16_t n = 0;
|
||||||
for (auto it = tables_.begin(); it != tables_.end(); ++it, n++) {
|
for (const auto& table : tables_) {
|
||||||
if (!strcmp(library_name, it->name)) {
|
if (table.name != library_name) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
++n;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelExport* ExportResolver::GetExportByOrdinal(
|
KernelExport* ExportResolver::GetExportByOrdinal(const uint16_t library_ordinal,
|
||||||
const uint16_t library_ordinal, const uint32_t ordinal) {
|
const uint32_t ordinal) {
|
||||||
auto& table = tables_[library_ordinal];
|
const auto& table = tables_[library_ordinal];
|
||||||
// TODO(benvanik): binary search?
|
// TODO(benvanik): binary search?
|
||||||
for (size_t n = 0; n < table.count; n++) {
|
for (size_t n = 0; n < table.count; n++) {
|
||||||
if (table.exports[n].ordinal == ordinal) {
|
if (table.exports[n].ordinal == ordinal) {
|
||||||
return &table.exports[n];
|
return &table.exports[n];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelExport* ExportResolver::GetExportByOrdinal(const char* library_name,
|
KernelExport* ExportResolver::GetExportByOrdinal(
|
||||||
const uint32_t ordinal) {
|
const std::string& library_name, const uint32_t ordinal) {
|
||||||
for (std::vector<ExportTable>::iterator it = tables_.begin();
|
for (const auto& table : tables_) {
|
||||||
it != tables_.end(); ++it) {
|
if (table.name == library_name) {
|
||||||
if (!strcmp(library_name, it->name)) {
|
|
||||||
// TODO(benvanik): binary search?
|
// TODO(benvanik): binary search?
|
||||||
for (size_t n = 0; n < it->count; n++) {
|
for (size_t n = 0; n < table.count; n++) {
|
||||||
if (it->exports[n].ordinal == ordinal) {
|
if (table.exports[n].ordinal == ordinal) {
|
||||||
return &it->exports[n];
|
return &table.exports[n];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelExport* ExportResolver::GetExportByName(const char* library_name,
|
KernelExport* ExportResolver::GetExportByName(const std::string& library_name,
|
||||||
const char* name) {
|
const std::string& name) {
|
||||||
// TODO(benvanik): lookup by name.
|
// TODO(benvanik): lookup by name.
|
||||||
assert_always();
|
assert_always();
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportResolver::SetVariableMapping(const char* library_name,
|
void ExportResolver::SetVariableMapping(const std::string& library_name,
|
||||||
const uint32_t ordinal,
|
const uint32_t ordinal,
|
||||||
uint32_t value) {
|
uint32_t value) {
|
||||||
KernelExport* kernel_export = GetExportByOrdinal(library_name, ordinal);
|
auto kernel_export = GetExportByOrdinal(library_name, ordinal);
|
||||||
assert_not_null(kernel_export);
|
assert_not_null(kernel_export);
|
||||||
kernel_export->is_implemented = true;
|
kernel_export->is_implemented = true;
|
||||||
kernel_export->variable_ptr = value;
|
kernel_export->variable_ptr = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportResolver::SetFunctionMapping(
|
void ExportResolver::SetFunctionMapping(const std::string& library_name,
|
||||||
const char* library_name, const uint32_t ordinal,
|
const uint32_t ordinal, void* shim_data,
|
||||||
void* shim_data, xe_kernel_export_shim_fn shim) {
|
xe_kernel_export_shim_fn shim) {
|
||||||
KernelExport* kernel_export = GetExportByOrdinal(library_name, ordinal);
|
auto kernel_export = GetExportByOrdinal(library_name, ordinal);
|
||||||
assert_not_null(kernel_export);
|
assert_not_null(kernel_export);
|
||||||
kernel_export->is_implemented = true;
|
kernel_export->is_implemented = true;
|
||||||
kernel_export->function_data.shim_data = shim_data;
|
kernel_export->function_data.shim_data = shim_data;
|
||||||
kernel_export->function_data.shim = shim;
|
kernel_export->function_data.shim = shim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace xe
|
||||||
|
|
|
@ -12,15 +12,13 @@
|
||||||
|
|
||||||
#include <xenia/core.h>
|
#include <xenia/core.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
typedef struct xe_ppc_state xe_ppc_state_t;
|
typedef struct xe_ppc_state xe_ppc_state_t;
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
||||||
|
|
||||||
typedef void (*xe_kernel_export_shim_fn)(xe_ppc_state_t*, void*);
|
typedef void (*xe_kernel_export_shim_fn)(xe_ppc_state_t*, void*);
|
||||||
|
|
||||||
class KernelExport {
|
class KernelExport {
|
||||||
|
@ -55,41 +53,40 @@ public:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ExportResolver {
|
class ExportResolver {
|
||||||
public:
|
public:
|
||||||
ExportResolver();
|
ExportResolver();
|
||||||
~ExportResolver();
|
~ExportResolver();
|
||||||
|
|
||||||
void RegisterTable(const char* library_name, KernelExport* exports,
|
void RegisterTable(const std::string& library_name, KernelExport* exports,
|
||||||
const size_t count);
|
const size_t count);
|
||||||
|
|
||||||
uint16_t GetLibraryOrdinal(const char* library_name);
|
uint16_t GetLibraryOrdinal(const std::string& library_name);
|
||||||
|
|
||||||
KernelExport* GetExportByOrdinal(const uint16_t library_ordinal,
|
KernelExport* GetExportByOrdinal(const uint16_t library_ordinal,
|
||||||
const uint32_t ordinal);
|
const uint32_t ordinal);
|
||||||
KernelExport* GetExportByOrdinal(const char* library_name,
|
KernelExport* GetExportByOrdinal(const std::string& library_name,
|
||||||
const uint32_t ordinal);
|
const uint32_t ordinal);
|
||||||
KernelExport* GetExportByName(const char* library_name, const char* name);
|
KernelExport* GetExportByName(const std::string& library_name,
|
||||||
|
const std::string& name);
|
||||||
|
|
||||||
void SetVariableMapping(const char* library_name, const uint32_t ordinal,
|
void SetVariableMapping(const std::string& library_name,
|
||||||
uint32_t value);
|
const uint32_t ordinal, uint32_t value);
|
||||||
void SetFunctionMapping(const char* library_name, const uint32_t ordinal,
|
void SetFunctionMapping(const std::string& library_name,
|
||||||
void* shim_data, xe_kernel_export_shim_fn shim);
|
const uint32_t ordinal, void* shim_data,
|
||||||
|
xe_kernel_export_shim_fn shim);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ExportTable {
|
struct ExportTable {
|
||||||
public:
|
std::string name;
|
||||||
char name[32];
|
|
||||||
KernelExport* exports;
|
KernelExport* exports;
|
||||||
size_t count;
|
size_t count;
|
||||||
|
ExportTable(const std::string& name, KernelExport* exports, size_t count)
|
||||||
|
: name(name), exports(exports), count(count) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<ExportTable> tables_;
|
std::vector<ExportTable> tables_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
#endif // XENIA_EXPORT_RESOLVER_H_
|
#endif // XENIA_EXPORT_RESOLVER_H_
|
||||||
|
|
|
@ -99,9 +99,7 @@ ID3D10Blob* D3D11GeometryShader::Compile(const char* shader_source) {
|
||||||
}
|
}
|
||||||
uint64_t hash = hash64(shader_source, strlen(shader_source)); // ?
|
uint64_t hash = hash64(shader_source, strlen(shader_source)); // ?
|
||||||
char file_name[poly::max_path];
|
char file_name[poly::max_path];
|
||||||
xesnprintfa(file_name, poly::countof(file_name),
|
snprintf(file_name, poly::countof(file_name), "%s/gen_%.16llX.gs", base_path,
|
||||||
"%s/gen_%.16llX.gs",
|
|
||||||
base_path,
|
|
||||||
hash);
|
hash);
|
||||||
|
|
||||||
if (FLAGS_dump_shaders.size()) {
|
if (FLAGS_dump_shaders.size()) {
|
||||||
|
|
|
@ -50,11 +50,8 @@ ID3D10Blob* D3D11ShaderCompile(XE_GPU_SHADER_TYPE type,
|
||||||
}
|
}
|
||||||
size_t hash = hash64(disasm_source, strlen(disasm_source)); // ?
|
size_t hash = hash64(disasm_source, strlen(disasm_source)); // ?
|
||||||
char file_name[poly::max_path];
|
char file_name[poly::max_path];
|
||||||
xesnprintfa(file_name, poly::countof(file_name),
|
snprintf(file_name, poly::countof(file_name), "%s/gen_%.16llX.%s", base_path,
|
||||||
"%s/gen_%.16llX.%s",
|
hash, type == XE_GPU_SHADER_TYPE_VERTEX ? "vs" : "ps");
|
||||||
base_path,
|
|
||||||
hash,
|
|
||||||
type == XE_GPU_SHADER_TYPE_VERTEX ? "vs" : "ps");
|
|
||||||
|
|
||||||
if (FLAGS_dump_shaders.size()) {
|
if (FLAGS_dump_shaders.size()) {
|
||||||
FILE* f = fopen(file_name, "w");
|
FILE* f = fopen(file_name, "w");
|
||||||
|
|
|
@ -48,8 +48,7 @@ private:
|
||||||
void append(const char* format, ...) {
|
void append(const char* format, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
int len = xevsnprintfa(buffer_ + offset_, capacity_ - offset_,
|
int len = vsnprintf(buffer_ + offset_, capacity_ - offset_, format, args);
|
||||||
format, args);
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
offset_ += len;
|
offset_ += len;
|
||||||
buffer_[offset_] = 0;
|
buffer_[offset_] = 0;
|
||||||
|
|
|
@ -58,8 +58,7 @@ struct Output {
|
||||||
void append(const char* format, ...) {
|
void append(const char* format, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
int len = xevsnprintfa(
|
int len = vsnprintf(buffer + offset, capacity - offset, format, args);
|
||||||
buffer + offset, capacity - offset, format, args);
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
offset += len;
|
offset += len;
|
||||||
buffer[offset] = 0;
|
buffer[offset] = 0;
|
||||||
|
|
|
@ -56,34 +56,13 @@ Entry* DiscImageDevice::ResolvePath(const char* path) {
|
||||||
GDFXEntry* gdfx_entry = gdfx_->root_entry();
|
GDFXEntry* gdfx_entry = gdfx_->root_entry();
|
||||||
|
|
||||||
// Walk the path, one separator at a time.
|
// Walk the path, one separator at a time.
|
||||||
// We copy it into the buffer and shift it left over and over.
|
auto path_parts = poly::split_path(path);
|
||||||
char remaining[poly::max_path];
|
for (auto& part : path_parts) {
|
||||||
xestrcpya(remaining, poly::countof(remaining), path);
|
gdfx_entry = gdfx_entry->GetChild(part.c_str());
|
||||||
while (remaining[0]) {
|
|
||||||
char* next_slash = strchr(remaining, '\\');
|
|
||||||
if (next_slash == remaining) {
|
|
||||||
// Leading slash - shift
|
|
||||||
xestrcpya(remaining, poly::countof(remaining), remaining + 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the buffer just the name.
|
|
||||||
if (next_slash) {
|
|
||||||
*next_slash = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look up in the entry.
|
|
||||||
gdfx_entry = gdfx_entry->GetChild(remaining);
|
|
||||||
if (!gdfx_entry) {
|
if (!gdfx_entry) {
|
||||||
// Not found.
|
// Not found.
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift the buffer down, unless we are at the end.
|
|
||||||
if (!next_slash) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
xestrcpya(remaining, poly::countof(remaining), next_slash + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry::Type type = gdfx_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ?
|
Entry::Type type = gdfx_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ?
|
||||||
|
|
|
@ -56,34 +56,13 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) {
|
||||||
STFSEntry* stfs_entry = stfs_->root_entry();
|
STFSEntry* stfs_entry = stfs_->root_entry();
|
||||||
|
|
||||||
// Walk the path, one separator at a time.
|
// Walk the path, one separator at a time.
|
||||||
// We copy it into the buffer and shift it left over and over.
|
auto path_parts = poly::split_path(path);
|
||||||
char remaining[poly::max_path];
|
for (auto& part : path_parts) {
|
||||||
xestrcpya(remaining, poly::countof(remaining), path);
|
stfs_entry = stfs_entry->GetChild(part.c_str());
|
||||||
while (remaining[0]) {
|
|
||||||
char* next_slash = strchr(remaining, '\\');
|
|
||||||
if (next_slash == remaining) {
|
|
||||||
// Leading slash - shift
|
|
||||||
xestrcpya(remaining, poly::countof(remaining), remaining + 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the buffer just the name.
|
|
||||||
if (next_slash) {
|
|
||||||
*next_slash = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look up in the entry.
|
|
||||||
stfs_entry = stfs_entry->GetChild(remaining);
|
|
||||||
if (!stfs_entry) {
|
if (!stfs_entry) {
|
||||||
// Not found.
|
// Not found.
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift the buffer down, unless we are at the end.
|
|
||||||
if (!next_slash) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
xestrcpya(remaining, poly::countof(remaining), next_slash + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry::Type type = stfs_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ?
|
Entry::Type type = stfs_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ?
|
||||||
|
|
|
@ -219,7 +219,7 @@ X_STATUS XThread::Create() {
|
||||||
}
|
}
|
||||||
|
|
||||||
char thread_name[32];
|
char thread_name[32];
|
||||||
xesnprintfa(thread_name, poly::countof(thread_name), "XThread%04X", handle());
|
snprintf(thread_name, poly::countof(thread_name), "XThread%04X", handle());
|
||||||
set_name(thread_name);
|
set_name(thread_name);
|
||||||
|
|
||||||
uint32_t proc_mask = creation_params_.creation_flags >> 24;
|
uint32_t proc_mask = creation_params_.creation_flags >> 24;
|
||||||
|
|
|
@ -111,11 +111,6 @@ void xe_xex2_release(xe_xex2_ref xex) {
|
||||||
xe_ref_release((xe_ref)xex, (xe_ref_dealloc_t)xe_xex2_dealloc);
|
xe_ref_release((xe_ref)xex, (xe_ref_dealloc_t)xe_xex2_dealloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
const xechar_t* xe_xex2_get_name(xe_xex2_ref xex) {
|
|
||||||
// TODO(benvanik): get name.
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const xe_xex2_header_t* xe_xex2_get_header(xe_xex2_ref xex) {
|
const xe_xex2_header_t* xe_xex2_get_header(xe_xex2_ref xex) {
|
||||||
return &xex->header;
|
return &xex->header;
|
||||||
}
|
}
|
||||||
|
@ -264,8 +259,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
||||||
for (size_t i = 0, j = 0; i < string_table_size;) {
|
for (size_t i = 0, j = 0; i < string_table_size;) {
|
||||||
assert_true(j <= 0xFF);
|
assert_true(j <= 0xFF);
|
||||||
if (j == name_index) {
|
if (j == name_index) {
|
||||||
xestrcpya(library->name, poly::countof(library->name),
|
std::strncpy(library->name, string_table + i,
|
||||||
string_table + i);
|
poly::countof(library->name));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (string_table[i] == 0) {
|
if (string_table[i] == 0) {
|
||||||
|
|
|
@ -51,7 +51,6 @@ xe_xex2_ref xe_xex2_load(xe::Memory* memory,
|
||||||
xe_xex2_ref xe_xex2_retain(xe_xex2_ref xex);
|
xe_xex2_ref xe_xex2_retain(xe_xex2_ref xex);
|
||||||
void xe_xex2_release(xe_xex2_ref xex);
|
void xe_xex2_release(xe_xex2_ref xex);
|
||||||
|
|
||||||
const xechar_t *xe_xex2_get_name(xe_xex2_ref xex);
|
|
||||||
const xe_xex2_header_t *xe_xex2_get_header(xe_xex2_ref xex);
|
const xe_xex2_header_t *xe_xex2_get_header(xe_xex2_ref xex);
|
||||||
const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name);
|
const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name);
|
||||||
|
|
||||||
|
|
|
@ -42,12 +42,13 @@ void xe_format_log_line(
|
||||||
|
|
||||||
// Format string - add a trailing newline if required.
|
// Format string - add a trailing newline if required.
|
||||||
const char* outfmt = "XE[%c] %s:%d: ";
|
const char* outfmt = "XE[%c] %s:%d: ";
|
||||||
char* buffer_ptr = buffer + xesnprintfa(
|
char* buffer_ptr = buffer + snprintf(buffer, buffer_count - 1, outfmt,
|
||||||
buffer, buffer_count - 1, outfmt, level_char, filename, line_number);
|
level_char, filename, line_number);
|
||||||
|
|
||||||
// Scribble args into the print buffer.
|
// Scribble args into the print buffer.
|
||||||
buffer_ptr = buffer_ptr + xevsnprintfa(
|
buffer_ptr = buffer_ptr + vsnprintf(buffer_ptr,
|
||||||
buffer_ptr, buffer_count - (buffer_ptr - buffer) - 1, fmt, args);
|
buffer_count - (buffer_ptr - buffer) - 1,
|
||||||
|
fmt, args);
|
||||||
|
|
||||||
// Add a trailing newline.
|
// Add a trailing newline.
|
||||||
if (buffer_ptr[-1] != '\n') {
|
if (buffer_ptr[-1] != '\n') {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <xenia/string.h>
|
#include <poly/string.h>
|
||||||
|
|
||||||
#define XE_OPTION_ENABLE_LOGGING 1
|
#define XE_OPTION_ENABLE_LOGGING 1
|
||||||
#define XE_OPTION_LOG_ERROR 1
|
#define XE_OPTION_LOG_ERROR 1
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <xenia/string.h>
|
#include <poly/string.h>
|
||||||
#include <xenia/types.h>
|
#include <xenia/types.h>
|
||||||
|
|
||||||
#define XE_OPTION_PROFILING 1
|
#define XE_OPTION_PROFILING 1
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
'malloc.h',
|
'malloc.h',
|
||||||
'profiling.cc',
|
'profiling.cc',
|
||||||
'profiling.h',
|
'profiling.h',
|
||||||
'string.h',
|
|
||||||
'types.h',
|
'types.h',
|
||||||
'xbox.h',
|
'xbox.h',
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef XENIA_STRING_H_
|
|
||||||
#define XENIA_STRING_H_
|
|
||||||
|
|
||||||
#include <poly/string.h>
|
|
||||||
|
|
||||||
// NOTE: these differing implementations should behave pretty much the same.
|
|
||||||
// If they don't, then they will have to be abstracted out.
|
|
||||||
|
|
||||||
#if !XE_LIKE_WIN32
|
|
||||||
int strncpy_s(char* dest, size_t destLength, const char* source, size_t count);
|
|
||||||
#define strcpy_s(dest, destLength, source) !(strcpy(dest, source) == dest + (destLength*0))
|
|
||||||
#define _snprintf_s(dest, destLength, x, format, ...) snprintf(dest, destLength, format, ##__VA_ARGS__)
|
|
||||||
#endif // !WIN32
|
|
||||||
|
|
||||||
#define xesnprintfw(buffer, bufferCount, format, ...) _snwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, ##__VA_ARGS__)
|
|
||||||
|
|
||||||
#define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0)
|
|
||||||
#define xesnprintfa(buffer, bufferCount, format, ...) _snprintf_s(buffer, bufferCount, bufferCount, format, ##__VA_ARGS__)
|
|
||||||
#define xevsnprintfa(buffer, bufferCount, format, args) vsnprintf(buffer, bufferCount, format, args)
|
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32 && defined(UNICODE) && UNICODE
|
|
||||||
|
|
||||||
typedef wchar_t xechar_t;
|
|
||||||
|
|
||||||
// xestrcpy fs + module
|
|
||||||
// xesnprintf many uses - only remove some?
|
|
||||||
|
|
||||||
#define xesnprintf xesnprintfw
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
typedef char xechar_t;
|
|
||||||
|
|
||||||
#define xesnprintf xesnprintfa
|
|
||||||
|
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
#endif // XENIA_STRING_H_
|
|
Loading…
Reference in New Issue