Mercurial > parpg-core
diff bin/parpg.c.in @ 5:33684971cdb1
Replaced the shell script launcher with a cross-platform C executable.
* Replaced the Unix-only shell script launcher with a cross-platform compiled executable written in C.
* Added several new configuration variables to the SConsctruct script which allows the user to specify where their Python site-packages and executable are located;
* Cleaned up the SConstruct script and made it easier to grok.
author | M. George Hansen <technopolitica@gmail.com> |
---|---|
date | Tue, 17 May 2011 14:18:25 -0700 |
parents | |
children | dd4ed4945411 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/parpg.c.in Tue May 17 14:18:25 2011 -0700 @@ -0,0 +1,76 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef _MSC_VER +# include <process.h> +#else +# include <sys/types.h> +# include <sys/wait.h> +#endif + +#define CONCAT_ARRAYS(TYPE, ARRAY_A, SIZE_A, ARRAY_B, SIZE_B) \ + (TYPE*)concatArrays((const void**)(ARRAY_A), (SIZE_A), \ + (const void**)(ARRAY_B), (SIZE_B), sizeof(TYPE)) + +#define NULL_TERMINATE(TYPE, ARRAY, SIZE) \ + (TYPE*)realloc(ARRAY, sizeof(TYPE) * (SIZE + 1)) + +#define ARRAY_LEN(ARRAY) (sizeof(ARRAY) / sizeof *(ARRAY)) + +void* +concatArrays(const void* arrayA, size_t sizeA, + const void* arrayB, size_t sizeB, size_t sizeType) { + char* concatenatedArray = malloc(sizeType * (sizeA + sizeB)); + memcpy(concatenatedArray, arrayA, sizeA * sizeType); + memcpy(concatenatedArray + sizeA * sizeType, arrayB, sizeB * sizeType); + return concatenatedArray; +} + +char* +joinStr(char* strA, char* strB, char* separator) { + int lenA = strlen(strA); + int lenB = strlen(strB); + int lenSeparator = strlen(separator); + char* concatenatedStr = malloc(lenA + lenB + lenSeparator + 1); + memcpy(concatenatedStr, strA, lenA); + memcpy(concatenatedStr + lenA, separator, lenSeparator); + memcpy(concatenatedStr + lenA + lenSeparator, strB, lenB + 1); + return concatenatedStr; +} + +int +spawnParpgProcess(char* pythonExecutable, char* configDir, int argc, + char* argv[]) { + char* baseArgs[] = {pythonExecutable, "-m", "parpg.main", configDir}; + int nBaseArgs = ARRAY_LEN(baseArgs); + int nAdditionalArgs = argc - 1; + char* additionalArgs[nAdditionalArgs]; + int i; + for (i = 1; i < argc; i++) { + additionalArgs[i - 1] = argv[i]; + } + int nArgs = nBaseArgs + nAdditionalArgs; + char** args = NULL_TERMINATE(char*, CONCAT_ARRAYS(char*, baseArgs, + nBaseArgs, additionalArgs, nAdditionalArgs), nArgs); + char* oldPythonPath = getenv("PYTHONPATH"); + char* newPythonPath = joinStr(oldPythonPath, "@PY_PACKAGES_DIR@", ":"); + int exitStatus; + char* env[2] = {joinStr("PYTHONPATH=", newPythonPath, ""), (char*)(0)}; +#ifdef _MSC_VER + exitStatus = spawnve(P_WAIT, pythonExecutable, args, env); +#else + exitStatus = execve(pythonExecutable, args, env); +#endif + return exitStatus; +} + +int +main(int argc, char* argv[]) { + int exitStatus = spawnParpgProcess("@PYTHON@", "@SYS_CONF_DIR@", argc, + argv); + if (exitStatus) { + perror("parpg exited with error"); + } + return exitStatus; +} +