-void cleanExit( char *intermed, int status )
-{
- unlink( intermed );
- exit( status );
-}
-
-#ifndef WIN32
-
-/* If any forward slash is found in argv0 then it is assumed that the path is
- * explicit and the path to the backend executable should be derived from
- * that. Whe check that location and also go up one then inside a directory of
- * the same name in case we are executing from the source tree. If no forward
- * slash is found it is assumed the file is being run from the installed
- * location. The PREFIX supplied during configuration is used. */
-char **makePathChecksUnix( const char *argv0, const char *progName )
-{
- char **result = new char*[3];
- const char *lastSlash = strrchr( argv0, '/' );
- int numChecks = 0;
-
- if ( lastSlash != 0 ) {
- char *path = strdup( argv0 );
- int givenPathLen = (lastSlash - argv0) + 1;
- path[givenPathLen] = 0;
-
- int progNameLen = strlen(progName);
- int length = givenPathLen + progNameLen + 1;
- char *check = new char[length];
- sprintf( check, "%s%s", path, progName );
- result[numChecks++] = check;
-
- length = givenPathLen + 3 + progNameLen + 1 + progNameLen + 1;
- check = new char[length];
- sprintf( check, "%s../%s/%s", path, progName, progName );
- result[numChecks++] = check;
- }
- else {
- int prefixLen = strlen(PREFIX);
- int progNameLen = strlen(progName);
- int length = prefixLen + 5 + progNameLen + 1;
- char *check = new char[length];
-
- sprintf( check, PREFIX "/bin/%s", progName );
- result[numChecks++] = check;
- }
-
- result[numChecks] = 0;
- return result;
-}
-
-
-void forkAndExec( const char *progName, char **pathChecks,
- ArgsVector &args, char *intermed )
-{
- pid_t pid = fork();
- if ( pid < 0 ) {
- /* Error, no child created. */
- error() << "failed to fork for " << progName << endl;
- cleanExit( intermed, 1 );
- }
- else if ( pid == 0 ) {
- /* child */
- while ( *pathChecks != 0 ) {
- /* Execv does not modify argv, it just uses the const form that is
- * compatible with the most code. Ours not included. */
- execv( *pathChecks, (char *const*) args.data );
- pathChecks += 1;
- }
- error() << "failed to exec " << progName << endl;
- cleanExit( intermed, 1 );
- }
-
- /* Parent process, wait for the child. */
- int status;
- wait( &status );
-
- /* What happened with the child. */
- if ( ! WIFEXITED( status ) ) {
- error() << progName << " did not exit normally" << endl;
- cleanExit( intermed, 1 );
- }
-
- if ( WEXITSTATUS(status) != 0 )
- cleanExit( intermed, WEXITSTATUS(status) );
-}
-
-#else
-
-/* GetModuleFileNameEx is used to find out where the the current process's
- * binary is. That location is searched first. If that fails then we go up one
- * directory and look for the executable inside a directory of the same name
- * in case we are executing from the source tree.
- * */
-char **makePathChecksWin( const char *progName )
-{
- int len = 1024;
- char *imageFileName = new char[len];
- HANDLE h = GetCurrentProcess();
- len = GetModuleFileNameEx( h, NULL, imageFileName, len );
- imageFileName[len] = 0;
-
- char **result = new char*[3];
- const char *lastSlash = strrchr( imageFileName, '\\' );
- int numChecks = 0;
-
- assert( lastSlash != 0 );
- char *path = strdup( imageFileName );
- int givenPathLen = (lastSlash - imageFileName) + 1;
- path[givenPathLen] = 0;
-
- int progNameLen = strlen(progName);
- int length = givenPathLen + progNameLen + 1;
- char *check = new char[length];
- sprintf( check, "%s%s", path, progName );
- result[numChecks++] = check;
-
- length = givenPathLen + 3 + progNameLen + 1 + progNameLen + 1;
- check = new char[length];
- sprintf( check, "%s..\\%s\\%s", path, progName, progName );
- result[numChecks++] = check;
-
- result[numChecks] = 0;
- return result;
-}
-
-void spawn( const char *progName, char **pathChecks,
- ArgsVector &args, char *intermed )
-{
- int result = 0;
- while ( *pathChecks != 0 ) {
- //cerr << "trying to execute " << *pathChecks << endl;
- result = _spawnv( _P_WAIT, *pathChecks, args.data );
- if ( result >= 0 || errno != ENOENT )
- break;
- pathChecks += 1;
- }
-
- if ( result < 0 ) {
- error() << "failed to spawn " << progName << endl;
- cleanExit( intermed, 1 );
- }
-
- if ( result > 0 )
- cleanExit( intermed, 1 );
-}
-
-#endif
-
-void execFrontend( const char *argv0, char *inputFileName, char *intermed )
-{
- /* The frontend program name. */
- const char *progName = "ragel";
-
- frontendArgs.insert( 0, progName );
- frontendArgs.insert( 1, "-x" );
- frontendArgs.append( "-o" );
- frontendArgs.append( intermed );
- frontendArgs.append( inputFileName );
- frontendArgs.append( 0 );
-
-#ifndef WIN32
- char **pathChecks = makePathChecksUnix( argv0, progName );
- forkAndExec( progName, pathChecks, frontendArgs, intermed );
-#else
- char **pathChecks = makePathChecksWin( progName );
- spawn( progName, pathChecks, frontendArgs, intermed );
-#endif
-}
-
-void execBackend( const char *argv0, char *intermed, char *outputFileName )
-{
- /* Locate the backend program */
- const char *progName = 0;
- if ( generateDot )
- progName = "rlgen-dot";
- else {
- switch ( hostLang->lang ) {
- case HostLang::C:
- case HostLang::D:
- progName = "rlgen-cd";
- break;
- case HostLang::Java:
- progName = "rlgen-java";
- break;
- case HostLang::Ruby:
- progName = "rlgen-ruby";
- break;
- }
- }
-
- backendArgs.insert( 0, progName );
- if ( outputFileName != 0 ) {
- backendArgs.append( "-o" );
- backendArgs.append( outputFileName );
- }
- backendArgs.append( intermed );
- backendArgs.append( 0 );
-
-#ifndef WIN32
- char **pathChecks = makePathChecksUnix( argv0, progName );
- forkAndExec( progName, pathChecks, backendArgs, intermed );
-#else
- char **pathChecks = makePathChecksWin( progName );
- spawn( progName, pathChecks, backendArgs, intermed );
-#endif
-}