3
#include <CoreFoundation/CoreFoundation.h>
4
#include <mach-o/dyld.h>
7
static const char *ERR_UNKNOWNPYTHONEXCEPTION = "An uncaught exception was raised during execution of the main script, but its class or name could not be determined";
10
report_error(const char *msg) {
12
fprintf(stderr, "\n");
17
// These variable must be filled in before compiling
18
static const char *ENV_VARS[] = { /*ENV_VARS*/ NULL };
19
static const char *ENV_VAR_VALS[] = { /*ENV_VAR_VALS*/ NULL};
20
static char PROGRAM[] = "**PROGRAM**";
21
static const char MODULE[] = "**MODULE**";
23
#define EXE "@executable_path/.."
26
set_env_vars(const char* exe_path, const char* rpath) {
29
const char *env_var, *val;
32
env_var = ENV_VARS[i];
33
if (env_var == NULL) break;
34
val = ENV_VAR_VALS[i++];
35
if (strstr(val, EXE) == val && strlen(val) >= strlen(EXE)+1) {
36
strncpy(buf, exe_path, 3*PATH_MAX-150);
37
strncpy(buf+strlen(exe_path), val+strlen(EXE), 150);
38
setenv(env_var, buf, 1);
40
setenv(env_var, val, 1);
42
setenv("CALIBRE_LAUNCH_MODULE", MODULE, 1);
43
setenv("RESOURCEPATH", rpath, 1);
48
main(int argc, char * const *argv, char * const *envp) {
54
uint32_t buf_size = PATH_MAX+1;
55
char *ebuf = calloc(buf_size, sizeof(char));
56
ret = _NSGetExecutablePath(ebuf, &buf_size);
59
ebuf = calloc(buf_size, sizeof(char));
60
if (_NSGetExecutablePath(ebuf, &buf_size) != 0)
61
return report_error("Failed to find real path of executable.");
63
pathPtr = realpath(ebuf, buf);
64
if (pathPtr == NULL) {
65
return report_error(strerror(errno));
68
for (i = 0; i < 3; i++) {
69
t = rindex(pathPtr, '/');
70
if (t == NULL) return report_error("Failed to determine bundle path.");
76
char rpath[PATH_MAX+1];
77
strncpy(rpath, pathPtr, strlen(pathPtr));
78
strncat(rpath, "/Contents/Resources", 50);
79
char exe_path[PATH_MAX+1];
80
strncpy(exe_path, pathPtr, strlen(pathPtr));
81
strncat(exe_path, "/Contents", 50);
83
set_env_vars(exe_path, rpath);
85
char main_script[PATH_MAX+1];
86
strncpy(main_script, rpath, strlen(rpath));
87
strncat(main_script, "/launcher.py", 20);
89
Py_SetProgramName(PROGRAM);
93
char **argv_new = calloc(argc+1, sizeof(char *));
94
argv_new[argc] = NULL;
95
argv_new[0] = main_script;
96
memcpy(&argv_new[1], &argv[1], (argc - 1) * sizeof(char *));
97
PySys_SetArgv(argc, argv_new);
99
FILE *main_script_file = fopen(main_script, "r");
100
int rval = PyRun_SimpleFileEx(main_script_file, main_script, 1);
103
PyObject *exc, *exceptionClassName, *v, *exceptionName;
104
exc = PySys_GetObject("last_type");
107
rval = report_error(ERR_UNKNOWNPYTHONEXCEPTION);
111
exceptionClassName = PyObject_GetAttrString(exc, "__name__");
112
if (!exceptionClassName) {
113
rval = report_error(ERR_UNKNOWNPYTHONEXCEPTION);
117
v = PySys_GetObject("last_value");
118
exceptionName = (v ? PyObject_Str(v) : NULL);
120
char *class = PyString_AsString(exceptionClassName);
121
char *exception = "";
122
Py_DecRef(exceptionClassName);
124
exception = PyString_AsString(exceptionName);
125
Py_DecRef(exceptionName);
128
strncpy(msg, "An unexpected error occurred: ", 100);
129
strncpy(msg, class, 500);
130
strncpy(msg, " : ", 3);
131
strncpy(msg, exception, 500);
132
rval = report_error(msg);