23 #include "TargetConditionals.h"
25 #include <mach-o/dyld.h>
26 #elif TARGET_OS_IPHONE
27 #elif TARGET_IPHONE_SIMULATOR
30 #elif defined _WIN32 || defined _WIN64
34 #if defined _WIN32 || defined _WIN64
35 #define PATH_SEPARATOR '\\'
37 #define PATH_SEPARATOR '/'
40 #define PATH_BUFFER_SIZE 4096
42 void perr(
const char* str) {
46 int qsort_int_cmp(
const void* a,
const void* b) {
47 return *((
int*)a) - *((
int*)b);
50 char* mstrcpy(
const char* str) {
51 char* strbuf = (
char*)malloc(
sizeof(
char) * (strlen(str) + 1));
57 char* mstrncpy(
const char* str,
size_t n) {
58 char* strbuf = (
char*)malloc(
sizeof(
char) * (n + 1));
60 strncpy(strbuf, str, n);
65 void skip_utf8_bom(FILE* fp) {
80 for (n = 0; n <= 2 && (bom[n] = getc(fp)) != EOF; n++) {}
84 if ((n < 3) || (bom[0] != 0xEF) || (bom[1] != 0xBB) || (bom[2] != 0xBF)) {
85 for (n--; n >= 0; n--) {
93 const char* executable_path(
void) {
94 static char path_buffer[PATH_BUFFER_SIZE];
95 static int calculated = 0;
99 ssize_t res = readlink(
"/proc/self/exe", path_buffer,
sizeof(path_buffer));
102 uint32_t size =
sizeof(path_buffer);
103 int res = _NSGetExecutablePath(path_buffer, &size);
105 #elif _WIN32 || _WIN64
108 DWORD res = GetModuleFileNameA(NULL, path_buffer, PATH_BUFFER_SIZE);
114 char* last_sep = strrchr(path_buffer, PATH_SEPARATOR);
115 assert(last_sep != NULL);
122 char* try_open_file(
const char* path) {
124 FILE* fp = fopen(path,
"r");
128 return mstrcpy(path);
132 if (is_absolute_path(path)) {
137 const char* exe_dir = executable_path();
139 (
char*)malloc(
sizeof(
char) * (strlen(path) + strlen(exe_dir) + 2));
140 sprintf(filename,
"%s/%s", exe_dir, path);
141 fp = fopen(filename,
"r");
151 (
char*)malloc(
sizeof(
char) * (strlen(path) + strlen(PKGDATADIR) + 2));
152 sprintf(filename,
"%s/%s", PKGDATADIR, path);
153 fp = fopen(filename,
"r");
163 char* get_file_path(
const char* filename) {
164 const char* last_sep = strrchr(filename,
'/');
166 if (last_sep == NULL) {
169 char* path = mstrncpy(filename, last_sep - filename);
173 int is_absolute_path(
const char* path) {
174 if (path[0] ==
'/') {
178 if (path[1] ==
':') {