Ejemplo n.º 1
0
static CFStringRef pyStandardizePath(CFStringRef pyLocation) {
    CFRange foundRange;
    CFURLRef fmwkURL;
    CFURLRef locURL;
    CFStringRef subpath;
    static CFStringRef prefix = NULL;
    if (!prefix) prefix = py2app_CFSTR("@executable_path/");
    foundRange = py2app_CFStringFind(pyLocation, prefix, 0);
    if (foundRange.location == kCFNotFound || foundRange.length == 0) {
        return NULL;
    }
    fmwkURL = py2app_CFBundleCopyPrivateFrameworksURL(CFBundleGetMainBundle());
    foundRange.location = foundRange.length;
    foundRange.length = py2app_CFStringGetLength(pyLocation) - foundRange.length;
    subpath = py2app_CFStringCreateWithSubstring(NULL, pyLocation, foundRange);
    locURL = py2app_CFURLCreateWithFileSystemPathRelativeToBase(
        NULL,
        subpath,
        kCFURLPOSIXPathStyle,
        false,
        fmwkURL);
    py2app_CFRelease(subpath);
    py2app_CFRelease(fmwkURL);
    subpath = pathFromURL(locURL);
    py2app_CFRelease(locURL);
    return subpath;
}
Ejemplo n.º 2
0
static void setResourcePath(void) {
    CFURLRef resDir;
    CFStringRef resPath;
    resDir = py2app_CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
    resPath = pathFromURL(resDir);
    py2app_CFRelease(resDir);
    setcfenv("RESOURCEPATH", resPath);
    py2app_CFRelease(resPath);
}
Ejemplo n.º 3
0
int main(int argc, char * *argv, char * const *envp)
{
    int rval = 0;
    char exec_path[PATH_MAX+1];
    char resolved_path[PATH_MAX+1];
    uint32_t exec_path_size = sizeof(exec_path);
    CFStringRef argv0_string;
    CFURLRef argv0_url;
    char *argv0 = NULL;
    char *root = NULL;

    if (bind_CoreFoundation()) {
        fprintf(stderr, "CoreFoundation not found or functions missing\n");
        return -1;
    }

    if (_NSGetExecutablePath(exec_path, &exec_path_size) != 0) {
        fprintf(stderr, "_NSGetExecutablePath failed to find current executable\n");
        return -1;
    }
    exec_path[exec_path_size] = '\0';

    realpath(exec_path, resolved_path);
    root = dirname(dirname(dirname(resolved_path)));

    argv0_url = py2app_CFURLCreateFromFileSystemRepresentation(
        NULL,
        (uint8_t *)root,
        strlen(root),
        true
        );

    if (!argv0_url) {
        fprintf(stderr, "Could not cast '%s' to CFURL!\n", root);
        return -1;
    }

    py2app_main_bundle = py2app_CFBundleCreate(NULL, argv0_url);

    if (!py2app_main_bundle) {
        fprintf(stderr, "Not bundled, exiting\n");
        return -1;
    }

    py2app_pool = py2app_CFArrayCreateMutable(NULL, 0, py2app_kCFTypeArrayCallBacks);
    if (!py2app_pool) {
        fprintf(stderr, "Couldn't create global pool\n");
        return -1;
    }
    rval = py2app_main(argc, argv, envp);
    py2app_CFRelease(py2app_pool);
    py2app_CFRelease(py2app_main_bundle);
    py2app_CFRelease(argv0_url);
    // py2app_CFRelease(argv0_string);
    // free(argv0);
    return rval;
}
Ejemplo n.º 4
0
static CFStringRef getMainScript(void) {
    CFMutableArrayRef possibleMains;
    CFBundleRef bndl;
    CFStringRef e_py, e_pyc, e_pyo, path;
    int i, cnt;
    possibleMains = py2app_CFArrayCreateMutable(NULL, 0, py2app_kCFTypeArrayCallBacks);
    CFArrayRef firstMains = py2app_getKey("PyMainFileNames");
    if (firstMains) {
        CFRange rng;
        rng.location = 0;
        rng.length = py2app_CFArrayGetCount(firstMains);
        py2app_CFArrayAppendArray(possibleMains, firstMains, rng);
    }
    py2app_CFArrayAppendValue(possibleMains, py2app_CFSTR("__main__"));
    py2app_CFArrayAppendValue(possibleMains, py2app_CFSTR("__realmain__"));
    py2app_CFArrayAppendValue(possibleMains, py2app_CFSTR("Main"));

    e_py = py2app_CFSTR("py");
    e_pyc = py2app_CFSTR("pyc");
    e_pyo = py2app_CFSTR("pyo");

    cnt = py2app_CFArrayGetCount(possibleMains);
    bndl = CFBundleGetMainBundle();
    path = NULL;
    for (i = 0; i < cnt; i++) {
        CFStringRef base;
        CFURLRef resURL;
        base = py2app_CFArrayGetValueAtIndex(possibleMains, i);
        resURL = py2app_CFBundleCopyResourceURL(bndl, base, e_py, NULL);
        if (resURL == NULL) {
            resURL = py2app_CFBundleCopyResourceURL(bndl, base, e_pyc, NULL);
        }
        if (resURL == NULL) {
            resURL = py2app_CFBundleCopyResourceURL(bndl, base, e_pyo, NULL);
        }
        if (resURL != NULL) {
            path = pathFromURL(resURL);
            py2app_CFRelease(resURL);
            break;
        }
    }
    py2app_CFRelease(possibleMains);
    return path;
}
Ejemplo n.º 5
0
static Boolean doesPathExist(CFStringRef path) {
    struct stat st;
    CFURLRef locURL;
    UInt8 buf[PATH_MAX];
    locURL = py2app_CFURLCreateWithFileSystemPath(
        NULL, path, kCFURLPOSIXPathStyle, false);
    py2app_CFURLGetFileSystemRepresentation(locURL, true, buf, sizeof(buf));
    py2app_CFRelease(locURL);
    return (stat((const char *)buf, &st) == -1 ? false : true);
}
Ejemplo n.º 6
0
static CFStringRef tildeExpand(CFStringRef path) {
    CFURLRef pathURL;
    char buf[PATH_MAX];
    CFURLRef fullPathURL;
    struct passwd *pwnam;
    char tmp;
    char *dir = NULL;


    py2app_CFStringGetCString(path, buf, sizeof(buf), kCFStringEncodingUTF8);

    int i;
    if (buf[0] != '~') {
        return py2app_CFStringCreateWithCString(
            NULL, buf, kCFStringEncodingUTF8);
    }
    /* user in path */
    i = 1;
    while (buf[i] != '\0' && buf[i] != '/') {
        i++;
    }
    if (i == 1) {
        dir = getenv("HOME");
    } else {
        tmp = buf[i];
        buf[i] = '\0';
        pwnam = getpwnam((const char *)&buf[1]);
        if (pwnam) dir = pwnam->pw_dir;
        buf[i] = tmp;
    }
    if (!dir) {
        return py2app_CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8);
    }
    pathURL = py2app_CFURLCreateFromFileSystemRepresentation(
        NULL, (const UInt8*)dir, strlen(dir), false);
    fullPathURL = py2app_CFURLCreateFromFileSystemRepresentationRelativeToBase(
        NULL, (const UInt8*)&buf[i + 1], strlen(&buf[i + 1]), false, pathURL);
    py2app_CFRelease(pathURL);
    path = pathFromURL(fullPathURL);
    py2app_CFRelease(fullPathURL);
    return path;
}
Ejemplo n.º 7
0
static CFTypeRef py2app_getKey(const char *key) {
    CFTypeRef rval;
    CFStringRef cfKey = py2app_CFStringCreateWithCString(NULL,
        key, kCFStringEncodingUTF8);
    if (!cfKey) return NULL;
    rval = py2app_CFBundleGetValueForInfoDictionaryKey(
        CFBundleGetMainBundle(),
        cfKey);
    py2app_CFRelease(cfKey);
    return rval;
}
Ejemplo n.º 8
0
static int report_linkEdit_error(void) {
    CFStringRef errString;
    const char *errorString;
    char* buf;
    errorString = dlerror();
    fputs(errorString, stderr);
    errString = py2app_CFStringCreateWithFormat(
        NULL, NULL, py2app_CFSTR(ERR_LINKERRFMT), errorString);
    buf = alloca(py2app_CFStringGetMaximumSizeForEncoding(
            py2app_CFStringGetLength(errString), kCFStringEncodingUTF8));
    py2app_CFStringGetCString(errString, buf, sizeof(buf), kCFStringEncodingUTF8);
    py2app_CFRelease(errString);
    return report_error(buf);
}
Ejemplo n.º 9
0
static CFStringRef getErrorScript(void) {
    CFMutableArrayRef errorScripts;
    CFBundleRef bndl;
    CFStringRef path;
    int i, cnt;
    errorScripts = py2app_CFArrayCreateMutable(NULL, 0, py2app_kCFTypeArrayCallBacks);
    CFArrayRef firstErrorScripts = py2app_getKey("PyErrorScripts");
    if (firstErrorScripts) {
        CFRange rng;
        rng.location = 0;
        rng.length = py2app_CFArrayGetCount(firstErrorScripts);
        py2app_CFArrayAppendArray(errorScripts, firstErrorScripts, rng);
    }
    py2app_CFArrayAppendValue(errorScripts, py2app_CFSTR("__error__"));
    py2app_CFArrayAppendValue(errorScripts, py2app_CFSTR("__error__.py"));
    py2app_CFArrayAppendValue(errorScripts, py2app_CFSTR("__error__.pyc"));
    py2app_CFArrayAppendValue(errorScripts, py2app_CFSTR("__error__.pyo"));
    py2app_CFArrayAppendValue(errorScripts, py2app_CFSTR("__error__.sh"));

    cnt = py2app_CFArrayGetCount(errorScripts);
    bndl = CFBundleGetMainBundle();
    path = NULL;
    for (i = 0; i < cnt; i++) {
        CFStringRef base;
        CFURLRef resURL;
        base = py2app_CFArrayGetValueAtIndex(errorScripts, i);
        resURL = py2app_CFBundleCopyResourceURL(bndl, base, NULL, NULL);
        if (resURL) {
            path = pathFromURL(resURL);
            py2app_CFRelease(resURL);
            break;
        }
    }
    py2app_CFRelease(errorScripts);
    return path;

}
Ejemplo n.º 10
0
static CFStringRef getPythonInterpreter(CFStringRef pyLocation) {
    CFBundleRef bndl;
    CFStringRef auxName;
    CFURLRef auxURL;
    CFStringRef path;

    auxName = py2app_getKey("PyExecutableName");
    if (!auxName) auxName = py2app_CFSTR("python");
    bndl = CFBundleGetMainBundle();
    auxURL = py2app_CFBundleCopyAuxiliaryExecutableURL(bndl, auxName);
    if (auxURL) {
        path = pathFromURL(auxURL);
        py2app_CFRelease(auxURL);
        return path;
    }
    return NULL;
}
Ejemplo n.º 11
0
static CFStringRef py2app_findPyLocation(CFArrayRef pyLocations) {
    CFIndex i;
    CFIndex cnt = py2app_CFArrayGetCount(pyLocations);
    for (i = 0; i < cnt; i++) {
        CFStringRef newLoc;
        CFStringRef pyLocation = py2app_CFArrayGetValueAtIndex(pyLocations, i);
        newLoc = pyStandardizePath(pyLocation);
        if (!newLoc) {
		newLoc = pyLocation;
		py2app_CFRetain(newLoc);
	}
        if (doesPathExist(newLoc)) {
            return newLoc;
        }
        if (newLoc) py2app_CFRelease(newLoc);
    }
    return NULL;
}
Ejemplo n.º 12
0
static CFMutableArrayRef get_trimmed_lines(CFStringRef output) {
    CFMutableArrayRef lines;
    CFArrayRef tmp;
    CFRange rng;
    lines = py2app_CFArrayCreateMutable(NULL, 0, py2app_kCFTypeArrayCallBacks);
    tmp = py2app_CFStringCreateArrayBySeparatingStrings(
        NULL, output, py2app_CFSTR("\n"));
    rng.location = 0;
    rng.length = py2app_CFArrayGetCount(tmp);
    py2app_CFArrayAppendArray(lines, tmp, rng);
    while (true) {
        CFIndex cnt = py2app_CFArrayGetCount(lines);
        CFStringRef last;
        /* Nothing on stdout means pass silently */
        if (cnt <= 0) {
            py2app_CFRelease(lines);
            return NULL;
        }
        last = py2app_CFArrayGetValueAtIndex(lines, cnt - 1);
        if (py2app_CFStringGetLength(last) > 0) break;
        py2app_CFArrayRemoveValueAtIndex(lines, cnt - 1);
    }
    return lines;
}
Ejemplo n.º 13
0
static int py2app_main(int argc, char * const *argv, char * const *envp) {
    CFArrayRef pyLocations;
    CFStringRef pyLocation;
    CFStringRef mainScript;
    CFStringRef pythonInterpreter;
    char *resource_path;
    char buf[PATH_MAX];
    char c_pythonInterpreter[PATH_MAX];
    char c_mainScript[PATH_MAX];
    char **argv_new;
    struct stat sb;
    void *py_dylib;
    int rval;
    FILE *mainScriptFile;
    char* curenv = NULL;
    char* curlocale = NULL;


    if (getenv("PYTHONOPTIMIZE") != NULL) {
        unsetenv("PYTHONOPTIMIZE");
    }
    if (getenv("PYTHONDEBUG") != NULL) {
        unsetenv("PYTHONDEBUG");
    }
    if (getenv("PYTHONDONTWRITEBYTECODE") != NULL) {
        unsetenv("PYTHONDONTWRITEBYTECODE");
    }
    if (getenv("PYTHONIOENCODING") != NULL) {
        unsetenv("PYTHONIOENCODING");
    }
    if (getenv("PYTHONDUMPREFS") != NULL) {
        unsetenv("PYTHONDUMPREFS");
    }
    if (getenv("PYTHONMALLOCSTATS") != NULL) {
        unsetenv("PYTHONMALLOCSTATS");
    }

    /* Ensure that the interpreter won't try to write bytecode files
     * Two reasons:
     * - Apps are often read-only for users
     * - Writing byte-code will be blocked by the sandbox
     *   when running a sandboxed application.
     */
    setenv("PYTHONDONTWRITEBYTECODE", "1", 1);

#ifndef PY2APP_SECONDARY
    /*
     * Force stdout/stderr to be unbuffered, needed when using the ASL
     * output redirection because Python 3's IO library won't use
     * line buffering with that.
     */
    setenv("PYTHONUNBUFFERED", "1", 1);
#endif


    if (!py2app_getApplicationName()) return report_error(ERR_NONAME);
    pyLocations = (CFArrayRef)py2app_getKey("PyRuntimeLocations");
    if (!pyLocations) return report_error(ERR_PYRUNTIMELOCATIONS);
    pyLocation = py2app_findPyLocation(pyLocations);
    if (!pyLocation) return report_error(ERR_NOPYTHONRUNTIME);

    setExecutablePath();
    setResourcePath();
    /* check for ':' in path, not compatible with Python due to Py_GetPath */
    /* XXX: Could work-around by creating something in /tmp I guess */
    resource_path = getenv("RESOURCEPATH");
    if ((resource_path == NULL) || (strchr(resource_path, ':') != NULL)) {
        return report_error(ERR_COLONPATH);
    }
    py2app_setPythonPath();
    setenv("ARGVZERO", argv[0], 1);

    /* Clear unwanted environment variable that could be set
     * by a PyObjC bundle in a parent process. Not clearing causes
     * problems in PyObjC.
     */
    if (getenv("PYOBJC_BUNDLE_ADDRESS") != NULL) {
        unsetenv("PYOBJC_BUNDLE_ADDRESS");
    }
    snprintf(buf, sizeof(buf)-1, "PYOBJC_BUNDLE_ADDRESS%ld", (long)getpid());
    if (getenv(buf) != NULL) {
        unsetenv(buf);
    }

    mainScript = getMainScript();
    if (!mainScript) return report_error(ERR_NOPYTHONSCRIPT);

    pythonInterpreter = getPythonInterpreter(pyLocation);
    py2app_CFStringGetCString(
        pythonInterpreter, c_pythonInterpreter,
        sizeof(c_pythonInterpreter), kCFStringEncodingUTF8);
    py2app_CFRelease(pythonInterpreter);
    if (lstat(c_pythonInterpreter, &sb) == 0) {
        if (!((sb.st_mode & S_IFLNK) == S_IFLNK)) {
            setenv("PYTHONHOME", resource_path, 1);
        }
    }

    py2app_CFStringGetCString(pyLocation, buf, sizeof(buf), kCFStringEncodingUTF8);
    py_dylib = dlopen(buf, RTLD_LAZY);
    if (!py_dylib) return report_linkEdit_error();

#define LOOKUP(NAME) \
	    NAME ## Ptr py2app_ ## NAME = (NAME ## Ptr)dlsym(py_dylib, #NAME); \
	    if (!py2app_ ## NAME) { \
		return report_linkEdit_error(); \
	    }

#define OPT_LOOKUP(NAME) \
	    NAME ## Ptr py2app_ ## NAME = (NAME ## Ptr)dlsym(py_dylib, #NAME);

    LOOKUP(Py_SetProgramName);
    LOOKUP(Py_Initialize);
    LOOKUP(PyRun_SimpleFile);
    LOOKUP(Py_Finalize);
    LOOKUP(PySys_GetObject);
    LOOKUP(PySys_SetArgv);
    LOOKUP(PyObject_GetAttrString);
    LOOKUP(Py_BuildValue);
#if 0
    OPT_LOOKUP(Py_SetPath);
#endif
    OPT_LOOKUP(_Py_DecodeUTF8_surrogateescape);
    LOOKUP(PySys_SetObject);


    int isPy3K = dlsym(py_dylib, "PyBytes_FromString") != NULL;

#undef OPT_LOOKUP
#undef LOOKUP

    if (isPy3K) {
	    /*
	     * When apps are started from the Finder (or anywhere
	     * except from the terminal), the LANG and LC_* variables
	     * aren't set in the environment. This confuses Py_Initialize
	     * when it tries to import the codec for UTF-8,
	     * therefore explicitly set the locale.
	     *
	     * Also set the LC_CTYPE environment variable because Py_Initialize
	     * resets the locale information using the environment :-(
	     */
	    curlocale = setlocale(LC_ALL, NULL);
	    if (curlocale != NULL) {
	      curlocale = strdup(curlocale);
	      if (curlocale == NULL) {
		(void)report_error("cannot save locale information");
		return -1;
	      }
	    }
	    setlocale(LC_ALL, "en_US.UTF-8");

	    curenv = getenv("LC_CTYPE");
	    if (curenv == NULL) {
		setenv("LC_CTYPE", "en_US.UTF-8", 1);
	    }

	    wchar_t w_pythonInterpreter[PATH_MAX+1];
    	    mbstowcs(w_pythonInterpreter, c_pythonInterpreter, PATH_MAX+1);
    	    py2app_Py_SetProgramName((char*)w_pythonInterpreter);


    } else {
	    py2app_Py_SetProgramName(c_pythonInterpreter);
    }

    py2app_Py_Initialize();

    /*
     * Reset the environment and locale information
     */
    if (isPy3K) {
	    if (curenv == NULL) {
		unsetenv("LC_CTYPE");
	    }

	    setlocale(LC_CTYPE, curlocale);
	    free(curlocale);
    }

    py2app_CFStringGetCString(
        mainScript, c_mainScript,
        sizeof(c_mainScript), kCFStringEncodingUTF8);
    py2app_CFRelease(mainScript);

    if (isPy3K) {
       int i;

       argv_new = alloca((argc+1) * sizeof(wchar_t));
       argv_new[argc] = NULL;
       argv_new[0] = (char*)py2app__Py_DecodeUTF8_surrogateescape(c_mainScript, strlen(c_mainScript));

       for (i = 1; i < argc; i++) {
	  argv_new[i] = (char*)py2app__Py_DecodeUTF8_surrogateescape(argv[i], strlen(argv[i]));
       }

    } else {
       argv_new = alloca((argc + 1) * sizeof(char *));
       argv_new[argc] = NULL;
       argv_new[0] = c_mainScript;
       memcpy(&argv_new[1], &argv[1], (argc - 1) * sizeof(char *));
    }
    py2app_PySys_SetArgv(argc, argv_new);

    mainScriptFile = fopen(c_mainScript, "r");
    rval = py2app_PyRun_SimpleFile(mainScriptFile, c_mainScript);
    fclose(mainScriptFile);

    if (rval) {
        rval = report_script_error(ERR_PYTHONEXCEPTION);
    }

    py2app_Py_Finalize();

    return rval;
}
Ejemplo n.º 14
0
static int report_script_error(const char *msg) {
    CFStringRef errorScript;
    CFMutableArrayRef lines;
    CFRange foundRange;
    CFStringRef lastLine;
    CFStringRef output = NULL;
    CFIndex lineCount;
    CFURLRef buttonURL = NULL;
    CFStringRef buttonString = NULL;
    CFStringRef title = NULL;
    CFStringRef errmsg = NULL;
    id releasePool;
    int errBinding;
    int status = 0;

    errorScript = getErrorScript();
    if (!errorScript) return report_error(msg);

    errBinding = bind_objc_Cocoa_ApplicationServices();
    if (!errBinding) {
        id task, stdoutPipe, taskData;
        CFMutableArrayRef argv;
        releasePool = ((id(*)(id, SEL))py2app_objc_msgSend)(
		    ((id(*)(id, SEL))py2app_objc_msgSend)(
			    py2app_objc_getClass("NSAutoreleasePool"),
			    py2app_sel_getUid("alloc")),
		    py2app_sel_getUid("init"));
        task = ((id(*)(id, SEL))py2app_objc_msgSend)(
		    ((id(*)(id, SEL))py2app_objc_msgSend)(
			    py2app_objc_getClass("NSTask"),
			    py2app_sel_getUid("alloc")),
		    py2app_sel_getUid("init"));
        stdoutPipe = ((id(*)(id, SEL))py2app_objc_msgSend)(py2app_objc_getClass("NSPipe"), py2app_sel_getUid("pipe"));
        ((void(*)(id, SEL, id))py2app_objc_msgSend)(task, py2app_sel_getUid("setLaunchPath:"), py2app_CFSTR("/bin/sh"));
        ((void(*)(id, SEL, id))py2app_objc_msgSend)(task, py2app_sel_getUid("setStandardOutput:"), stdoutPipe);
        argv = py2app_CFArrayCreateMutable(NULL, 0, py2app_kCFTypeArrayCallBacks);
        py2app_CFArrayAppendValue(argv, errorScript);
        py2app_CFArrayAppendValue(argv, py2app_getApplicationName());
        ((void(*)(id, SEL, id))py2app_objc_msgSend)(task, py2app_sel_getUid("setArguments:"), argv);
        /* This could throw, in theory, but /bin/sh should prevent that */
        ((void(*)(id, SEL))py2app_objc_msgSend)(task, py2app_sel_getUid("launch"));
        ((void(*)(id, SEL))py2app_objc_msgSend)(task, py2app_sel_getUid("waitUntilExit"));
        taskData = ((id(*)(id, SEL))py2app_objc_msgSend)(
            ((id(*)(id, SEL))py2app_objc_msgSend)(stdoutPipe, py2app_sel_getUid("fileHandleForReading")),
            py2app_sel_getUid("readDataToEndOfFile"));
        py2app_CFRelease(argv);

        status = ((int(*)(id, SEL))py2app_objc_msgSend)(task, py2app_sel_getUid("terminationStatus"));
        py2app_CFRelease(task);
        if (!status && taskData) {
            output = py2app_CFStringCreateFromExternalRepresentation(
                NULL, taskData, kCFStringEncodingUTF8);
        }

        ((void(*)(id, SEL))py2app_objc_msgSend)(releasePool, py2app_sel_getUid("release"));
    }

    py2app_CFRelease(errorScript);
    if (status || !output) return report_error(msg);

    lines = get_trimmed_lines(output);
    py2app_CFRelease(output);
    /* Nothing on stdout means pass silently */
    if (!lines) return -1;
    lineCount = py2app_CFArrayGetCount(lines);
    lastLine = py2app_CFArrayGetValueAtIndex(lines, lineCount - 1);
    foundRange = py2app_CFStringFind(lastLine, py2app_CFSTR("ERRORURL: "), 0);
    if (foundRange.location != kCFNotFound && foundRange.length != 0) {
        CFMutableArrayRef buttonArr;
        CFArrayRef tmp;
        CFRange rng;
        buttonArr = py2app_CFArrayCreateMutable(NULL, 0, py2app_kCFTypeArrayCallBacks);
        tmp = py2app_CFStringCreateArrayBySeparatingStrings(
            NULL, lastLine, py2app_CFSTR(" "));
        lineCount -= 1;
        py2app_CFArrayRemoveValueAtIndex(lines, lineCount);
        rng.location = 1;
        rng.length = py2app_CFArrayGetCount(tmp) - 1;
        py2app_CFArrayAppendArray(buttonArr, tmp, rng);
        py2app_CFRelease(tmp);
        while (true) {
            CFStringRef tmpstr;
            if (py2app_CFArrayGetCount(buttonArr) <= 0) break;
            tmpstr = py2app_CFArrayGetValueAtIndex(buttonArr, 0);
            if (py2app_CFStringGetLength(tmpstr) == 0) {
                py2app_CFArrayRemoveValueAtIndex(buttonArr, 0);
            } else {
                break;
            }
        }

        buttonURL = py2app_CFURLCreateWithString(
            NULL, py2app_CFArrayGetValueAtIndex(buttonArr, 0), NULL);
        if (buttonURL) {
            py2app_CFArrayRemoveValueAtIndex(buttonArr, 0);
            while (true) {
                CFStringRef tmpstr;
                if (py2app_CFArrayGetCount(buttonArr) <= 0) break;
                tmpstr = py2app_CFArrayGetValueAtIndex(buttonArr, 0);
                if (py2app_CFStringGetLength(tmpstr) == 0) {
                    py2app_CFArrayRemoveValueAtIndex(buttonArr, 0);
                } else {
                    break;
                }
            }
            if (py2app_CFArrayGetCount(buttonArr) > 0) {
                buttonString = py2app_CFStringCreateByCombiningStrings(
                    NULL, buttonArr, py2app_CFSTR(" "));
            }
            if (!buttonString) buttonString = py2app_CFSTR(ERR_DEFAULTURLTITLE);
        }
        py2app_CFRelease(buttonArr);

    }
    if (lineCount <= 0 || errBinding) {
        py2app_CFRelease(lines);
        return report_error(msg);
    }

    releasePool = ((id(*)(id, SEL))py2app_objc_msgSend)(
		    ((id(*)(id, SEL))py2app_objc_msgSend)(
			    py2app_objc_getClass("NSAutoreleasePool"),
			    py2app_sel_getUid("alloc")),
		    py2app_sel_getUid("init"));

    title = py2app_CFArrayGetValueAtIndex(lines, 0);
    py2app_CFRetain(title);
    (void)AUTORELEASE(title);
    lineCount -= 1;
    py2app_CFArrayRemoveValueAtIndex(lines, lineCount);
    py2app_NSLog(py2app_CFSTR("%@"), title);
    if (lineCount > 0) {
        CFStringRef showerr;
        errmsg = py2app_CFStringCreateByCombiningStrings(
            NULL, lines, py2app_CFSTR("\r"));
        (void)AUTORELEASE(errmsg);
        showerr = ((id(*)(id, SEL, id))py2app_objc_msgSend)(
            ((id(*)(id, SEL, id))py2app_objc_msgSend)(errmsg, py2app_sel_getUid("componentsSeparatedByString:"), py2app_CFSTR("\r")),
            py2app_sel_getUid("componentsJoinedByString:"), py2app_CFSTR("\n"));
        py2app_NSLog(py2app_CFSTR("%@"), showerr);
    } else {
        errmsg = py2app_CFSTR("");
    }

    ensureGUI();
    if (!buttonURL) {
        int choice = py2app_NSRunAlertPanel(
            title, py2app_CFSTR("%@"), py2app_CFSTR(ERR_TERMINATE),
            py2app_CFSTR(ERR_CONSOLEAPPTITLE), NULL, errmsg);
        if (choice == NSAlertAlternateReturn) py2app_openConsole();
    } else {
        int choice = py2app_NSRunAlertPanel(
            title, py2app_CFSTR("%@"), py2app_CFSTR(ERR_TERMINATE),
            buttonString, NULL, errmsg);
        if (choice == NSAlertAlternateReturn) {
            id ws = ((id(*)(id, SEL))py2app_objc_msgSend)(py2app_objc_getClass("NSWorkspace"), py2app_sel_getUid("sharedWorkspace"));
            ((void(*)(id, SEL, id))py2app_objc_msgSend)(ws, py2app_sel_getUid("openURL:"), buttonURL);
        }
    }
    ((void(*)(id, SEL))py2app_objc_msgSend)(releasePool, py2app_sel_getUid("release"));
    py2app_CFRelease(lines);
    return -1;
}
Ejemplo n.º 15
0
static void py2app_setPythonPath(void) {
    CFMutableArrayRef paths;
    CFURLRef resDir;
    CFStringRef resPath;
    CFArrayRef resPackages;
    CFDictionaryRef options;

    paths = py2app_CFArrayCreateMutable(NULL, 0, py2app_kCFTypeArrayCallBacks);
    resDir = py2app_CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());

    resPath = pathFromURL(resDir);
    py2app_CFArrayAppendValue(paths, resPath);
    py2app_CFRelease(resPath);

    resPackages = py2app_getKey("PyResourcePackages");
    if (resPackages) {
        int i;
        int cnt = py2app_CFArrayGetCount(resPackages);
        for (i = 0; i < cnt; i++) {
            resPath = tildeExpand(py2app_CFArrayGetValueAtIndex(resPackages, i));
            if (py2app_CFStringGetLength(resPath)) {
                if (py2app_CFStringGetCharacterAtIndex(resPath, 0) != '/') {
                    CFURLRef absURL = py2app_CFURLCreateWithString(
                        NULL, resPath, resDir);
                    py2app_CFRelease(resPath);
                    resPath = pathFromURL(absURL);
                    py2app_CFRelease(absURL);
                }
                py2app_CFArrayAppendValue(paths, resPath);
            }
            py2app_CFRelease(resPath);
        }
    }

    py2app_CFRelease(resDir);

    options = py2app_getKey("PyOptions");
    if (options) {
        CFBooleanRef use_pythonpath;
	CFNumberRef optimize;
        use_pythonpath = py2app_CFDictionaryGetValue(
            options, py2app_CFSTR("use_pythonpath"));
        if (use_pythonpath && py2app_CFBooleanGetValue(use_pythonpath)) {
            char *ppath = getenv("PYTHONPATH");
            if (ppath) {
                CFArrayRef oldPath;
                oldPath = py2app_CFStringCreateArrayBySeparatingStrings(
                    NULL, py2app_CFSTR(ppath), py2app_CFSTR(":"));
                if (oldPath) {
                    CFRange rng;
                    rng.location = 0;
                    rng.length = py2app_CFArrayGetCount(oldPath);
                    py2app_CFArrayAppendArray(paths, oldPath, rng);
                    py2app_CFRelease(oldPath);
                }
            }
        }

	optimize = py2app_CFDictionaryGetValue(
		options, py2app_CFSTR("optimize"));
	if (optimize) {
		int v = 0;
		char buf[32];
		py2app_CFNumberGetValue(optimize, kCFNumberIntType, &v);
		snprintf(buf, 31, "%d", v);
		setenv("PYTHONOPTIMIZE", buf, 1);
	}
    }

    if (py2app_CFArrayGetCount(paths)) {
        resPath = py2app_CFStringCreateByCombiningStrings(NULL, paths, py2app_CFSTR(":"));
        setcfenv("PYTHONPATH", resPath);
        py2app_CFRelease(resPath);
    } else {
	 if (getenv("PYTHONPATH") != NULL) {
	     unsetenv("PYTHONPATH");
	 }
    }

    py2app_CFRelease(paths);
}
Ejemplo n.º 16
0
int
main(int argc, char * const *argv, char * const *envp)
{
    int rval;

#ifndef PY2APP_SECONDARY
    /* Running as a GUI app started by launch
     * services, try to redirect stdout/stderr
     * to ASL.
     *
     * NOTE: Detecting application bundles on OSX 10.9
     * is annoyingly hard, the devnull trick is the least
     * worst option I've found yet.
     */
    struct stat st;
    struct utsname uts;
    int is_app_bundle = 1;

    if (uname(&uts) != -1) {
        if (strcmp(uts.release, "13.") <= 0) {
	    /* OSX 10.8 or earlier */
            if (!have_psn_arg(argc, argv)) {
                is_app_bundle = 0;
	    }
	} else {
	    /* OSX 10.9 or later */
            if (fstat(1, &st) != -1) {
	        if (!S_ISCHR(st.st_mode) ||
	            major(st.st_dev) != 3 ||
     	            minor(st.st_dev) != 2) {

    	    	        /* We appear to be launched from the
			 * command-line after all.
		         */
		        is_app_bundle = st.st_dev;
	        }
            }
        }
    }


    if (is_app_bundle) {
        const char *bname;
        setenv("_PY2APP_LAUNCHED_", "1", 1);

        bname = strrchr(argv[0], '/');
        if (bname == NULL) {
	    bname = argv[0];
        } else {
	    bname++;
        }

        setup_asl(bname);
    }
#endif /* !PY2APP_SECONDARY */

    if (bind_CoreFoundation()) {
        fprintf(stderr, "CoreFoundation not found or functions missing\n");
        return -1;
    }
    if (!CFBundleGetMainBundle()) {
        fprintf(stderr, "Not bundled, exiting\n");
        return -1;
    }
    py2app_pool = py2app_CFArrayCreateMutable(NULL, 0, py2app_kCFTypeArrayCallBacks);
    if (!py2app_pool) {
        fprintf(stderr, "Couldn't create global pool\n");
        return -1;
    }
    rval = py2app_main(argc, argv, envp);
    py2app_CFRelease(py2app_pool);
    return rval;
}