From 4350d7f2807b45021eb480b4b3e3fb52eb58218f Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Thu, 17 Feb 2011 14:47:01 -0800 Subject: [PATCH] Allow embed option to take function name. --- Cython/Compiler/CmdLine.py | 10 +++-- Cython/Compiler/ModuleNode.py | 80 +++++++++++++++++++++-------------- Cython/Compiler/Options.py | 6 +-- 3 files changed, 59 insertions(+), 37 deletions(-) diff --git a/Cython/Compiler/CmdLine.py b/Cython/Compiler/CmdLine.py index 7b0bc390..60eff8db 100644 --- a/Cython/Compiler/CmdLine.py +++ b/Cython/Compiler/CmdLine.py @@ -34,7 +34,7 @@ Options: -a, --annotate Produce a colorized HTML version of the source. --line-directives Produce #line directives pointing to the .pyx source --cplus Output a C++ rather than C file. - --embed Generate a main() function that embeds the Python interpreter. + --embed[=] Generate a main() function that embeds the Python interpreter. -2 Compile based on Python-2 syntax and code semantics. -3 Compile based on Python-3 syntax and code semantics. --fast-fail Abort the compilation on the first error @@ -84,8 +84,12 @@ def parse_command_line(args): options.use_listing_file = 1 elif option in ("-+", "--cplus"): options.cplus = 1 - elif option == "--embed": - Options.embed = True + elif option.startswith("--embed"): + ix = option.find('=') + if ix == -1: + Options.embed = "main" + else: + Options.embed = option[ix+1:] elif option.startswith("-I"): options.include_path.append(get_param(option)) elif option == "--include-dir": diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 07220260..9ca919b7 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -1897,7 +1897,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): def generate_main_method(self, env, code): module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__')) - code.globalstate.use_utility_code(main_method.specialize(module_name=env.module_name, module_is_main=module_is_main)) + if Options.embed == "main": + wmain = "wmain" + else: + wmain = Options.embed + code.globalstate.use_utility_code( + main_method.specialize( + module_name = env.module_name, + module_is_main = module_is_main, + main_method = Options.embed, + wmain_method = wmain)) def generate_pymoduledef_struct(self, env, code): if env.doc: @@ -2646,9 +2655,9 @@ impl = """ #endif #if PY_MAJOR_VERSION < 3 -int main(int argc, char** argv) { +int %(main_method)s(int argc, char** argv) { #elif defined(WIN32) || defined(MS_WINDOWS) -int wmain(int argc, wchar_t **argv) { +int %(wmain_method)s(int argc, wchar_t **argv) { #else static int __Pyx_main(int argc, wchar_t **argv) { #endif @@ -2665,9 +2674,13 @@ static int __Pyx_main(int argc, wchar_t **argv) { m = fpgetmask(); fpsetmask(m & ~FP_X_OFL); #endif - Py_SetProgramName(argv[0]); + if (argc) { + Py_SetProgramName(argv[0]); + } Py_Initialize(); - PySys_SetArgv(argc, argv); + if (argc) { + PySys_SetArgv(argc, argv); + } %(module_is_main)s = 1; #if PY_MAJOR_VERSION < 3 init%(module_name)s(); @@ -2794,33 +2807,38 @@ oom: } int -main(int argc, char **argv) +%(main_method)s(int argc, char **argv) { - wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc); - /* We need a second copies, as Python might modify the first one. */ - wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc); - int i, res; - char *oldloc; - if (!argv_copy || !argv_copy2) { - fprintf(stderr, "out of memory\\n"); - return 1; - } - oldloc = strdup(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, ""); - for (i = 0; i < argc; i++) { - argv_copy2[i] = argv_copy[i] = __Pyx_char2wchar(argv[i]); - if (!argv_copy[i]) - return 1; - } - setlocale(LC_ALL, oldloc); - free(oldloc); - res = __Pyx_main(argc, argv_copy); - for (i = 0; i < argc; i++) { - free(argv_copy2[i]); - } - free(argv_copy); - free(argv_copy2); - return res; + if (!argc) { + return __Pyx_main(0, NULL); + } + else { + wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc); + /* We need a second copies, as Python might modify the first one. */ + wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc); + int i, res; + char *oldloc; + if (!argv_copy || !argv_copy2) { + fprintf(stderr, "out of memory\\n"); + return 1; + } + oldloc = strdup(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, ""); + for (i = 0; i < argc; i++) { + argv_copy2[i] = argv_copy[i] = __Pyx_char2wchar(argv[i]); + if (!argv_copy[i]) + return 1; + } + setlocale(LC_ALL, oldloc); + free(oldloc); + res = __Pyx_main(argc, argv_copy); + for (i = 0; i < argc; i++) { + free(argv_copy2[i]); + } + free(argv_copy); + free(argv_copy2); + return res; + } } #endif """) diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py index 4068db7d..52b26b8d 100644 --- a/Cython/Compiler/Options.py +++ b/Cython/Compiler/Options.py @@ -44,9 +44,9 @@ lookup_module_cpdef = 0 init_local_none = 1 # Whether or not to embed the Python interpreter, for use in making a -# standalone executable. This will provide a main() method which simply -# executes the body of this module. -embed = False +# standalone executable or calling from external libraries. +# This will provide a method which simply executes the body of this module. +embed = None # Disables function redefinition, allowing all functions to be declared at # module creation time. For legacy code only. -- 2.26.2