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;
+}
+