1/* 2 * Workaround to make NSAppicationMain more usable from Python. 3 */ 4#include <Python.h> 5#include "pyobjc-api.h" 6 7#import <AppKit/AppKit.h> 8 9static PyObject* 10objc_NSApplicationMain( 11 PyObject* self __attribute__((__unused__)), 12 PyObject* args, 13 PyObject* kwds) 14{ 15static char* keywords[] = { "argv", NULL }; 16 char** argv = NULL; 17 int argc; 18 PyObject* arglist; 19 int i; 20 PyObject* v; 21 int res; 22 23 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:NSApplicationMain", 24 keywords, &arglist)) { 25 return NULL; 26 } 27 28 if (!PySequence_Check(arglist)) { 29 PyErr_SetString(PyExc_TypeError, 30 "NSApplicationMain: need list of strings as argument"); 31 return NULL; 32 } 33 34 argc = PySequence_Size(arglist); 35 argv = calloc((argc + 1), sizeof(char**)); 36 if (argv == NULL) { 37 PyErr_SetString(PyExc_MemoryError, 38 "Out of memory"); 39 return NULL; 40 } 41 42 for (i = 0; i < argc; i++) { 43 v = PySequence_GetItem(arglist, i); 44 if (v == NULL) { 45 goto error_cleanup; 46 } 47 if (PyUnicode_Check(v)) { 48 PyObject* bytes = PyUnicode_AsEncodedString(v, 49 NULL, NULL); 50 if (!bytes) { 51 goto error_cleanup; 52 } 53 argv[i] = strdup(PyBytes_AsString(bytes)); 54#if PY_MAJOR_VERSION == 2 55 } else if (PyString_Check(v)) { 56 argv[i] = strdup(PyString_AsString(v)); 57#endif 58 } else { 59 PyErr_SetString(PyExc_TypeError, 60 "NSApplicationMain: need list of strings " 61 "as argument"); 62 goto error_cleanup; 63 } 64 65 if (argv[i] == NULL) { 66 PyErr_SetString(PyExc_MemoryError, 67 "Out of memory"); 68 goto error_cleanup; 69 } 70 } 71 72 argv[argc] = NULL; 73 74 PyObjC_DURING 75 res = NSApplicationMain(argc, (const char**)argv); 76 PyObjC_HANDLER 77 PyObjCErr_FromObjC(localException); 78 res = -1; 79 PyObjC_ENDHANDLER 80 81 for (i = 0; i < argc; i++) { 82 free(argv[i]); 83 } 84 free(argv); 85 86 if (res == -1 && PyErr_Occurred()) 87 return NULL; 88 return PyInt_FromLong(res); 89 90error_cleanup: 91 if (argv != NULL) { 92 for (i = 0; i < argc; i++) { 93 if (argv[i] != NULL) { 94 free(argv[i]); 95 argv[i] = NULL; 96 } 97 } 98 free(argv); 99 argv = NULL; 100 } 101 102 return NULL; 103} 104 105 106#define APPKIT_APPMAIN_METHODS \ 107 { \ 108 "NSApplicationMain", \ 109 (PyCFunction)objc_NSApplicationMain, \ 110 METH_VARARGS|METH_KEYWORDS, \ 111 "int NSApplicationMain(int argc, const char *argv[]);" \ 112 }, 113