comparison 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
comparison
equal deleted inserted replaced
4:20c2b7a42c63 5:33684971cdb1
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #ifdef _MSC_VER
5 # include <process.h>
6 #else
7 # include <sys/types.h>
8 # include <sys/wait.h>
9 #endif
10
11 #define CONCAT_ARRAYS(TYPE, ARRAY_A, SIZE_A, ARRAY_B, SIZE_B) \
12 (TYPE*)concatArrays((const void**)(ARRAY_A), (SIZE_A), \
13 (const void**)(ARRAY_B), (SIZE_B), sizeof(TYPE))
14
15 #define NULL_TERMINATE(TYPE, ARRAY, SIZE) \
16 (TYPE*)realloc(ARRAY, sizeof(TYPE) * (SIZE + 1))
17
18 #define ARRAY_LEN(ARRAY) (sizeof(ARRAY) / sizeof *(ARRAY))
19
20 void*
21 concatArrays(const void* arrayA, size_t sizeA,
22 const void* arrayB, size_t sizeB, size_t sizeType) {
23 char* concatenatedArray = malloc(sizeType * (sizeA + sizeB));
24 memcpy(concatenatedArray, arrayA, sizeA * sizeType);
25 memcpy(concatenatedArray + sizeA * sizeType, arrayB, sizeB * sizeType);
26 return concatenatedArray;
27 }
28
29 char*
30 joinStr(char* strA, char* strB, char* separator) {
31 int lenA = strlen(strA);
32 int lenB = strlen(strB);
33 int lenSeparator = strlen(separator);
34 char* concatenatedStr = malloc(lenA + lenB + lenSeparator + 1);
35 memcpy(concatenatedStr, strA, lenA);
36 memcpy(concatenatedStr + lenA, separator, lenSeparator);
37 memcpy(concatenatedStr + lenA + lenSeparator, strB, lenB + 1);
38 return concatenatedStr;
39 }
40
41 int
42 spawnParpgProcess(char* pythonExecutable, char* configDir, int argc,
43 char* argv[]) {
44 char* baseArgs[] = {pythonExecutable, "-m", "parpg.main", configDir};
45 int nBaseArgs = ARRAY_LEN(baseArgs);
46 int nAdditionalArgs = argc - 1;
47 char* additionalArgs[nAdditionalArgs];
48 int i;
49 for (i = 1; i < argc; i++) {
50 additionalArgs[i - 1] = argv[i];
51 }
52 int nArgs = nBaseArgs + nAdditionalArgs;
53 char** args = NULL_TERMINATE(char*, CONCAT_ARRAYS(char*, baseArgs,
54 nBaseArgs, additionalArgs, nAdditionalArgs), nArgs);
55 char* oldPythonPath = getenv("PYTHONPATH");
56 char* newPythonPath = joinStr(oldPythonPath, "@PY_PACKAGES_DIR@", ":");
57 int exitStatus;
58 char* env[2] = {joinStr("PYTHONPATH=", newPythonPath, ""), (char*)(0)};
59 #ifdef _MSC_VER
60 exitStatus = spawnve(P_WAIT, pythonExecutable, args, env);
61 #else
62 exitStatus = execve(pythonExecutable, args, env);
63 #endif
64 return exitStatus;
65 }
66
67 int
68 main(int argc, char* argv[]) {
69 int exitStatus = spawnParpgProcess("@PYTHON@", "@SYS_CONF_DIR@", argc,
70 argv);
71 if (exitStatus) {
72 perror("parpg exited with error");
73 }
74 return exitStatus;
75 }
76