2007-06-19 16:49:21 +00:00

218 lines
5.3 KiB
C++
Executable File

///////////////////////////////////////////////////////////////////////
//
// This is a little wrapper to make it easy to run a python
// program from the command line.
//
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
//
// Windows Version
//
///////////////////////////////////////////////////////////////////////
#ifdef WIN32
#ifdef BUILDING_GENPYCODE
#define LINK_SOURCE "\\bin\\genpycode.exe"
#define LINK_TARGET "\\python\\python.exe"
#endif
#ifdef BUILDING_PACKPANDA
#define LINK_SOURCE "\\bin\\packpanda.exe"
#define LINK_TARGET "\\python\\python.exe"
#endif
#ifdef BUILDING_EGGCACHER
#define LINK_SOURCE "\\bin\\eggcacher.exe"
#define LINK_TARGET "\\python\\python.exe"
#endif
#include <windows.h>
#include <winuser.h>
#include <stdlib.h>
#include <process.h>
#include <malloc.h>
#include <stdio.h>
#include <signal.h>
#define PATH_MAX 1024
void pathfail(void)
{
fprintf(stderr, "Cannot locate the root of the panda tree\n");
exit(1);
}
int main(int argc, char **argv)
{
char fnbuf[PATH_MAX],ppbuf[PATH_MAX],pabuf[PATH_MAX],modcmd[PATH_MAX];
int fnlen;
// Ask windows for the file name of this executable.
fnlen = GetModuleFileName(NULL, fnbuf, 1023);
if ((fnlen <= 0)||(fnlen >= 1023)) pathfail();
fnbuf[fnlen] = 0;
// Make sure that the executable's name ends in LINK_SOURCE
int srclen = strlen(LINK_SOURCE);
if (fnlen < srclen + 4) pathfail();
if (stricmp(fnbuf + fnlen - srclen, LINK_SOURCE)) pathfail();
fnlen -= srclen; fnbuf[fnlen] = 0;
// See if we can find the panda root. If not, abort.
sprintf(ppbuf,"%s/direct/__init__.py",fnbuf);
FILE *f = fopen(ppbuf,"r");
if (f==0) pathfail();
fclose(f);
// Set the PYTHONPATH
char *pp = getenv("PYTHONPATH");
if (pp) sprintf(ppbuf,"PYTHONPATH=%s;%s\\bin;%s",fnbuf,fnbuf,pp);
else sprintf(ppbuf,"PYTHONPATH=%s;%s\\bin",fnbuf,fnbuf);
putenv(ppbuf);
// Fetch the command line and trim the first word.
char *cmdline = GetCommandLine();
char *args = cmdline;
bool inquote = false;
while (*args && ((*args != ' ')||(inquote))) {
if (*args == '"') inquote = !inquote;
args++;
}
while (*args==' ') args++;
// Append LINK_TARGET to the file name.
if (fnlen + strlen(LINK_TARGET) > 1023) pathfail();
strcat(fnbuf, LINK_TARGET);
// Calculate MODCMD
#ifdef BUILDING_GENPYCODE
sprintf(modcmd,"python -c \"import direct.ffi.jGenPyCode\" %s",args);
#endif
#ifdef BUILDING_PACKPANDA
sprintf(modcmd,"python -c \"import direct.directscripts.packpanda\" %s",args);
#endif
#ifdef BUILDING_EGGCACHER
sprintf(modcmd,"python -c \"import direct.directscripts.eggcacher\" %s",args);
#endif
// Run it.
signal(SIGINT, SIG_IGN);
PROCESS_INFORMATION pinfo;
STARTUPINFO sinfo;
GetStartupInfo(&sinfo);
BOOL ok = CreateProcess(fnbuf,modcmd,NULL,NULL,TRUE,NULL,NULL,NULL,&sinfo,&pinfo);
if (ok) WaitForSingleObject(pinfo.hProcess,INFINITE);
}
#endif /* WIN32 */
///////////////////////////////////////////////////////////////////////
//
// Linux Version
//
// This would probably work on most unixes, with the possible
// exception of the /proc/self/exe bit.
//
///////////////////////////////////////////////////////////////////////
#ifdef __linux__
#ifdef BUILDING_GENPYCODE
#define LINK_SOURCE "/bin/genpycode"
#endif
#ifdef BUILDING_PACKPANDA
#define LINK_SOURCE "/bin/packpanda"
#endif
#ifdef BUILDING_EGGCACHER
#define LINK_SOURCE "/bin/eggcacher"
#endif
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <sys/param.h>
void errorexit(char *s)
{
fprintf(stderr,"%s\n");
exit(1);
}
void pathfail(void)
{
fprintf(stderr, "Cannot locate the root of the panda tree\n");
exit(1);
}
int main(int argc, char **argv)
{
char fnbuf[PATH_MAX],ppbuf[PATH_MAX];
char *modargv[1024];
int fnlen,modargc;
// Ask linux for the file name of this executable.
int ok = readlink("/proc/self/exe", fnbuf, PATH_MAX-1);
if (ok<0) errorexit("Cannot read /proc/sys/exe");
fnbuf[PATH_MAX-1] = 0;
fnlen = strlen(fnbuf);
// Make sure that the executable's name ends in LINK_SOURCE
int srclen = strlen(LINK_SOURCE);
if (fnlen < srclen + 4) pathfail();
if (strcmp(fnbuf + fnlen - srclen, LINK_SOURCE)) pathfail();
fnlen -= srclen; fnbuf[fnlen] = 0;
// See if we can find the 'direct' tree locally.
// If not, continue anyway. It may be possible to succeed.
sprintf(ppbuf,"%s/direct/__init__.py",fnbuf);
FILE *f = fopen(ppbuf,"r");
if (f) {
char *pp = getenv("PYTHONPATH");
if (pp) sprintf(ppbuf,"PYTHONPATH=%s:%s/lib:%s",fnbuf,fnbuf,pp);
else sprintf(ppbuf,"PYTHONPATH=%s:%s/lib",fnbuf,fnbuf);
putenv(ppbuf);
}
// Calculate MODARGV
modargc=0;
modargv[modargc++]="python";
#ifdef BUILDING_GENPYCODE
modargv[modargc++] = "-c";
modargv[modargc++] = "import direct.ffi.jGenPyCode";
#endif
#ifdef BUILDING_PACKPANDA
modargv[modargc++] = "-c";
modargv[modargc++] = "import direct.directscripts.packpanda";
#endif
#ifdef BUILDING_EGGCACHER
modargv[modargc++] = "-c";
modargv[modargc++] = "import direct.directscripts.eggcacher";
#endif
for (int i=1; i<argc; i++) modargv[modargc++] = argv[i];
modargv[modargc] = 0;
// Run it.
execv("/usr/bin/python", modargv);
}
#endif /* LINUX */