# HG changeset patch # Parent 4682d18e8143adef66c2325f530fc34c8646deff diff -r 4682d18e8143 PC/launcher.c --- a/PC/launcher.c Sat Mar 23 06:35:22 2013 -0700 +++ b/PC/launcher.c Sun Jul 21 12:03:41 2013 +0100 @@ -119,6 +119,10 @@ #define RC_CREATE_PROCESS 101 #define RC_BAD_VIRTUAL_PATH 102 #define RC_NO_PYTHON 103 +#ifdef SCRIPT_WRAPPER +#define RC_NO_MEMORY 104 +#define RC_NO_SCRIPT 105 +#endif #define MAX_VERSION_SIZE 4 @@ -457,6 +461,51 @@ return result; } +#ifdef SCRIPT_WRAPPER +/* + * Check for a script located alongside the executable + */ + +#ifdef _WINDOWS +#define SCRIPT_SUFFIX L"-script.pyw" +#else +#define SCRIPT_SUFFIX L"-script.py" +#endif + +static wchar_t wrapped_script_path[MAX_PATH]; + +/* Locate the script being wrapped. + * + * This code should store the name of the wrapped script in + * wrapped_script_path, or terminate the program with an error if there is no + * valid wrapped script file. + */ +static void +locate_wrapped_script() +{ + wchar_t * p; + size_t plen; + DWORD attrs; + + plen = GetModuleFileNameW(NULL, wrapped_script_path, MAX_PATH); + p = wcsrchr(wrapped_script_path, L'.'); + if (p == NULL) { + debug(L"GetModuleFileNameW returned value has no extension: %s\n", + wrapped_script_path); + error(RC_NO_SCRIPT, L"Wrapper name '%s' is not valid.", wrapped_script_path); + } + + wcsncpy_s(p, MAX_PATH - (p - wrapped_script_path) + 1, SCRIPT_SUFFIX, _TRUNCATE); + attrs = GetFileAttributesW(wrapped_script_path); + if (attrs == INVALID_FILE_ATTRIBUTES) { + debug(L"File '%s' non-existent\n", wrapped_script_path); + error(RC_NO_SCRIPT, L"Script file '%s' is not present.", wrapped_script_path); + } + + debug(L"Using wrapped script file '%s'\n", wrapped_script_path); +} +#endif + /* * Process creation code */ @@ -1224,6 +1273,11 @@ VS_FIXEDFILEINFO * file_info; UINT block_size; int index; +#ifdef SCRIPT_WRAPPER + int newlen; + wchar_t * newcommand; + wchar_t * av[2]; +#endif wp = get_env(L"PYLAUNCH_DEBUG"); if ((wp != NULL) && (*wp != L'\0')) @@ -1303,7 +1357,39 @@ } command = skip_me(GetCommandLineW()); - debug(L"Called with command line: %s", command); + debug(L"Called with command line: %s\n", command); + +#ifdef SCRIPT_WRAPPER + /* He launcher is being used in "script wrapper" mode. + * There should therefore be a Python script named -script.py in + * the same directory as the launcher executable. + * Put the script name into argv as the first (script name) argument. + */ + + /* Get the wrapped script name - if the script is not present, this will + * terminate the program with an error. + */ + locate_wrapped_script(); + + /* Add the wrapped script to the start of command */ + newlen = wcslen(wrapped_script_path) + wcslen(command) + 2; + newcommand = malloc(sizeof(wchar_t) * newlen); + if (newcommand) { + wcscpy_s(newcommand, newlen, wrapped_script_path); + wcscat_s(newcommand, newlen, L" "); + wcscat_s(newcommand, newlen, command); + debug(L"Running wrapped script with command line '%s'\n", newcommand); + read_commands(); + av[0] = wrapped_script_path; + av[1] = NULL; + maybe_handle_shebang(av, newcommand); + /* Returns if no shebang line - pass to default processing */ + command = newcommand; + valid = FALSE; + } else { + error(RC_NO_MEMORY, L"Could not allocate new command line"); + } +#else if (argc <= 1) { valid = FALSE; p = NULL; @@ -1331,6 +1417,8 @@ } } } +#endif + if (!valid) { ip = locate_python(L""); if (ip == NULL)