Index: driver/cc1.cc
===================================================================
--- driver/cc1.cc	(revision ef22ad65ff9727de264304f61406d2505d5d7d45)
+++ driver/cc1.cc	(revision bbb1b35eaa5582395a5450ee332dbe21ed7013ba)
@@ -10,6 +10,6 @@
 // Created On       : Fri Aug 26 14:23:51 2005
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 22 22:29:52 2019
-// Update Count     : 328
+// Last Modified On : Fri Aug 23 15:06:27 2019
+// Update Count     : 371
 //
 
@@ -24,4 +24,6 @@
 #include <unistd.h>										// execvp, fork, unlink
 #include <sys/wait.h>									// wait
+#include <fcntl.h>
+
 
 #include "config.h"										// configure info
@@ -34,5 +36,7 @@
 static string compiler_path( CFA_BACKEND_CC );			// path/name of C compiler
 static bool CFA_flag = false;							// -CFA flag
+static bool save_temps = false;							// -save-temps flag
 static string o_file;
+
 
 static bool prefix( const string & arg, const string & pre ) {
@@ -44,7 +48,5 @@
 	static const string suffixes[NumSuffixes] = { "cfa", "hfa", "ifa" };
 
-	//std::cerr << arg << std::endl;
 	size_t dot = arg.find_last_of( "." );
-	//std::cerr << dot << " " << (dot != string::npos ? arg.substr( dot + 1 ) : "fred" ) << std::endl;
 	if ( dot == string::npos ) return;
 	const string * end = suffixes + NumSuffixes;
@@ -62,5 +64,5 @@
 
 	for ( int i = 0; environ[i]; i += 1 ) {
-		string arg = environ[i];
+		string arg( environ[i] );
 		#ifdef __DEBUG_H__
 		cerr << "env arg:\"" << arg << "\"" << endl;
@@ -68,5 +70,5 @@
 
 		if ( prefix( arg, __CFA_FLAGPREFIX__ ) ) {
-			string val = arg.substr( __CFA_FLAGPREFIX__.size() + 4 );
+			string val( arg.substr( __CFA_FLAGPREFIX__.size() + 4 ) );
 			if ( prefix( val, "-compiler=" ) ) {
 				compiler_path = val.substr( 10 );
@@ -81,5 +83,5 @@
 
 	for ( int i = 0; environ[i]; i += 1 ) {
-		string arg = environ[i];
+		string arg( environ[i] );
 		#ifdef __DEBUG_H__
 		cerr << "env arg:\"" << arg << "\"" << endl;
@@ -87,9 +89,11 @@
 
 		if ( prefix( arg, __CFA_FLAGPREFIX__ ) ) {
-			string val = arg.substr( __CFA_FLAGPREFIX__.size() + 4 );
+			string val( arg.substr( __CFA_FLAGPREFIX__.size() + 4 ) );
 			if ( prefix( val, "-compiler=" ) ) {
 				compiler_path = val.substr( 10 );
-			} else if ( prefix( val, "-CFA" ) ) {
+			} else if ( val == "-CFA" ) {
 				CFA_flag = true;
+			} else if ( val == "-save-temps" ) {
+				save_temps = true;
 			} else if ( prefix( val, "-o=" ) ) {		// output file for -CFA
 				o_file = val.substr( 3 );
@@ -107,4 +111,6 @@
 
 static void rmtmpfile() {
+	if ( tmpfilefd == -1 ) return;						// RACE, file created ?
+
 	startrm = true;										// RACE with C-c C-c
 	if ( unlink( tmpname ) == -1 ) {					// remove tmpname
@@ -130,11 +136,11 @@
 	string arg;
 
-	const char *cpp_in = NULL;
-	const char *cpp_out = NULL;
+	const char * cpp_in = nullptr;
+	const char * cpp_out = nullptr;
 
 	bool cpp_flag = false;
 	bool o_flag = false;
 
-	const char *args[argc + 100];						// leave space for 100 additional cpp command line values
+	const char * args[argc + 100];						// leave space for 100 additional cpp command line values
 	int nargs = 1;										// number of arguments in args list; 0 => command name
 
@@ -202,10 +208,10 @@
 			} // if
 		} else {										// obtain input and possibly output files
-			if ( cpp_in == NULL ) {
+			if ( cpp_in == nullptr ) {
 				cpp_in = argv[i];
 				#ifdef __DEBUG_H__
 				cerr << "cpp_in:\"" << cpp_in << "\"" << endl;
 				#endif // __DEBUG_H__
-			} else if ( cpp_out == NULL ) {
+			} else if ( cpp_out == nullptr ) {
 				cpp_out = argv[i];
 				#ifdef __DEBUG_H__
@@ -224,10 +230,10 @@
 		cerr << " " << args[i];
 	} // for
-	if ( cpp_in != NULL ) cerr << " " << cpp_in;
-	if ( cpp_out != NULL ) cerr << " " << cpp_out;
+	if ( cpp_in != nullptr ) cerr << " " << cpp_in;
+	if ( cpp_out != nullptr ) cerr << " " << cpp_out;
 	cerr << endl;
 	#endif // __DEBUG_H__
 
-	if ( cpp_in == NULL ) {
+	if ( cpp_in == nullptr ) {
 		cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
 		exit( EXIT_FAILURE );
@@ -245,9 +251,9 @@
 		} // if
 		args[nargs++] = cpp_out;
-		args[nargs] = NULL;								// terminate argument list
+		args[nargs] = nullptr;							// terminate argument list
 
 		#ifdef __DEBUG_H__
 		cerr << "nargs: " << nargs << endl;
-		for ( int i = 0; args[i] != NULL; i += 1 ) {
+		for ( int i = 0; args[i] != nullptr; i += 1 ) {
 			cerr << args[i] << " ";
 		} // for
@@ -255,5 +261,5 @@
 		#endif // __DEBUG_H__
 
-		execvp( args[0], (char *const *)args );			// should not return
+		execvp( args[0], (char * const *)args );		// should not return
 		perror( "CC1 Translator error: stage 1, execvp" );
 		exit( EXIT_FAILURE );
@@ -266,5 +272,5 @@
 		// an error (e.g., cannot find include file). Whereas, output is always generated, even when there is an error,
 		// when cpp writes to stdout. Hence, stdout is redirected into the temporary file.
-		if ( freopen( cpp_out, "w", stdout ) == NULL ) { // redirect stdout to output file
+		if ( freopen( cpp_out, "w", stdout ) == nullptr ) { // redirect stdout to output file
 			perror( "CC1 Translator error: stage 1, freopen" );
 			exit( EXIT_FAILURE );
@@ -274,9 +280,9 @@
 		suffix( cpp_in, args, nargs );					// check suffix
 		args[nargs++] = cpp_in;							// input to cpp
-		args[nargs] = NULL;								// terminate argument list
+		args[nargs] = nullptr;							// terminate argument list
 
 		#ifdef __DEBUG_H__
 		cerr << "cpp nargs: " << nargs << endl;
-		for ( int i = 0; args[i] != NULL; i += 1 ) {
+		for ( int i = 0; args[i] != nullptr; i += 1 ) {
 			cerr << args[i] << " ";
 		} // for
@@ -284,5 +290,5 @@
 		#endif // __DEBUG_H__
 
-		execvp( args[0], (char *const *)args );			// should not return
+		execvp( args[0], (char * const *)args );		// should not return
 		perror( "CC1 Translator error: stage 1, execvp" );
 		exit( EXIT_FAILURE );
@@ -308,10 +314,10 @@
 	string arg;
 
-	const char * cpp_in = NULL;
-	const char * cpp_out = NULL;
-
-	const char *args[argc + 100];						// leave space for 100 additional cfa command line values
+	const char * cpp_in = nullptr;
+	const char * cpp_out = nullptr;
+
+	const char * args[argc + 100];						// leave space for 100 additional cfa command line values
 	int nargs = 1;										// number of arguments in args list; 0 => command name
-	const char *cargs[20];								// leave space for 20 additional cfa-cpp command line values
+	const char * cargs[20];								// leave space for 20 additional cfa-cpp command line values
 	int ncargs = 1;										// 0 => command name
 
@@ -359,10 +365,10 @@
 			} // if
 		} else {										// obtain input and possibly output files
-			if ( cpp_in == NULL ) {
+			if ( cpp_in == nullptr ) {
 				cpp_in = argv[i];
 				#ifdef __DEBUG_H__
 				cerr << "cpp_in:\"" << cpp_in << "\"" << endl;
 				#endif // __DEBUG_H__
-			} else if ( cpp_out == NULL ) {
+			} else if ( cpp_out == nullptr ) {
 				cpp_out = argv[i];
 				#ifdef __DEBUG_H__
@@ -370,22 +376,48 @@
 				#endif // __DEBUG_H__
 			} else {
-				cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
+				cerr << "Usage: " << argv[0] << " more than two files specified" << endl;
 				exit( EXIT_FAILURE );
 			} // if
 		} // if
 	} // for
+
+	if ( cpp_in == nullptr ) {
+		cerr << "Usage: " << argv[0] << " missing input file" << endl;
+		exit( EXIT_FAILURE );
+	} // if
+	if ( cpp_out == nullptr ) {
+		cerr << "Usage: " << argv[0] << " missing output file" << endl;
+		exit( EXIT_FAILURE );
+	} // if
 
 	// Create a temporary file, if needed, to store output of the cfa-cpp preprocessor. Cannot be created in forked
 	// process because variables tmpname and tmpfilefd are cloned.
 
-	if ( ! CFA_flag ) {								// run cfa-cpp ?
-		tmpfilefd = mkstemps( tmpname, 2 );
-		if ( tmpfilefd == -1 ) {
-			perror( "CC1 Translator error: stage 2, mkstemp" );
-			exit( EXIT_FAILURE );
-		} // if
-
-		#ifdef __DEBUG_H__
-		cerr << "tmpname:" << tmpname << " tmpfilefd:" << tmpfilefd << endl;
+	string cfa_cpp_out;
+
+	if ( ! CFA_flag ) {									// run compiler ?
+		if ( save_temps ) {
+			cfa_cpp_out = cpp_in;
+			size_t dot = cfa_cpp_out.find_last_of( "." );
+			if ( dot == string::npos ) {
+				cerr << "CC1 Translator error: stage 2, bad file name " << endl;
+				exit( EXIT_FAILURE );
+			} // if
+
+			cfa_cpp_out = cfa_cpp_out.substr( 0, dot ) + ".ifa";
+			if ( creat( cfa_cpp_out.c_str(), 0666 ) == -1 ) {
+				perror( "CC1 Translator error: stage 2, creat" );
+				exit( EXIT_FAILURE );
+			} // if
+		} else {
+			tmpfilefd = mkstemps( tmpname, 2 );
+			if ( tmpfilefd == -1 ) {
+				perror( "CC1 Translator error: stage 2, mkstemp" );
+				exit( EXIT_FAILURE );
+			} // if
+			cfa_cpp_out = tmpname;
+		} // if
+		#ifdef __DEBUG_H__
+		cerr << "cfa_cpp_out: " << cfa_cpp_out << endl;
 		#endif // __DEBUG_H__
 	} // if
@@ -404,10 +436,10 @@
 			} // if
 		} else {
-			cargs[ncargs++] = tmpname;
-		} // if
-		cargs[ncargs] = NULL;							// terminate argument list
-
-		#ifdef __DEBUG_H__
-		for ( int i = 0; cargs[i] != NULL; i += 1 ) {
+			cargs[ncargs++] = cfa_cpp_out.c_str();
+		} // if
+		cargs[ncargs] = nullptr;							// terminate argument list
+
+		#ifdef __DEBUG_H__
+		for ( int i = 0; cargs[i] != nullptr; i += 1 ) {
 			cerr << cargs[i] << " ";
 		} // for
@@ -446,6 +478,5 @@
 		cerr << " " << args[i];
 	} // for
-	cerr << endl;
-	if ( cpp_in != NULL ) cerr << " " << cpp_in;
+	cerr << " " << cpp_in << endl;
 	#endif // __DEBUG_H__
 
@@ -453,10 +484,14 @@
 		args[0] = compiler_path.c_str();
 		args[nargs++] = "-S";							// only compile and put assembler output in specified file
-		args[nargs++] = tmpname;
-		args[nargs] = NULL;								// terminate argument list
+		if ( save_temps ) {								// make gcc accept .ifa suffix
+			args[nargs++] = "-x";
+			args[nargs++] = "cpp-output";
+		} // if
+		args[nargs++] = cfa_cpp_out.c_str();
+		args[nargs] = nullptr;							// terminate argument list
 
 		#ifdef __DEBUG_H__
 		cerr << "stage2 nargs: " << nargs << endl;
-		for ( int i = 0; args[i] != NULL; i += 1 ) {
+		for ( int i = 0; args[i] != nullptr; i += 1 ) {
 			cerr << args[i] << " ";
 		} // for
@@ -493,5 +528,5 @@
 int main( const int argc, const char * const argv[], __attribute__((unused)) const char * const env[] ) {
 	#ifdef __DEBUG_H__
-	for ( int i = 0; env[i] != NULL; i += 1 ) {
+	for ( int i = 0; env[i] != nullptr; i += 1 ) {
 		cerr << env[i] << endl;
 	} // for
@@ -501,5 +536,5 @@
 	signal( SIGTERM, sigTermHandler );
 
-	string arg = argv[1];
+	string arg( argv[1] );
 
 	// Currently, stage 1 starts with flag -E and stage 2 with flag -fpreprocessed.
Index: driver/cfa.cc
===================================================================
--- driver/cfa.cc	(revision ef22ad65ff9727de264304f61406d2505d5d7d45)
+++ driver/cfa.cc	(revision bbb1b35eaa5582395a5450ee332dbe21ed7013ba)
@@ -10,6 +10,6 @@
 // Created On       : Tue Aug 20 13:44:49 2002
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 22 22:29:50 2019
-// Update Count     : 403
+// Last Modified On : Fri Aug 23 16:27:07 2019
+// Update Count     : 411
 //
 
@@ -39,5 +39,5 @@
 	static int flags = 0;								// environment variables must have unique names
 
-	if ( putenv( (char *)( *new string( string( "__CFA_FLAG" + to_string( flags++ ) + "__=" ) + arg ) ).c_str() ) != 0 ) {
+	if ( putenv( (char *)( *new string( string( "__CFA_FLAG" + to_string( flags++ ) + "__=" ) + arg ) ).c_str() ) ) {
 		cerr << argv[0] << " error, cannot set environment variable." << endl;
 		exit( EXIT_FAILURE );
@@ -89,6 +89,6 @@
 
 	bool x_flag = false;								// -x flag
-	bool nonoptarg = false;								// indicates non-option argument specified
-	bool link = true;									// linking as well as compiling
+	bool nonoptarg = false;								// no non-option arguments specified, i.e., no file names
+	bool link = true;									// link stage occurring
 	bool verbose = false;								// -v flag
 	bool quiet = false;									// -quiet flag
@@ -103,5 +103,5 @@
 	bool m32 = false;									// -m32 flag
 	bool m64 = false;									// -m64 flag
-	bool intree = false;
+	bool intree = false;								// build in tree
 	int o_file = 0;										// -o filename position
 
@@ -176,4 +176,7 @@
 				debugging = true;						// symbolic debugging required
 				args[nargs++] = argv[i];				// pass argument along
+			} else if ( arg == "-save-temps" ) {
+				args[nargs++] = argv[i];				// pass argument along
+				Putenv( argv, arg );					// save cfa-cpp output
 			} else if ( prefix( arg, "-x" ) ) {			// file suffix ?
 				string lang;
@@ -258,8 +261,9 @@
 	#endif // __DEBUG_H__
 
-	// if ( cpp_flag && CFA_flag ) {
-	// 	cerr << argv[0] << " error, cannot use -E and -CFA flags together." << endl;
-	// 	exit( EXIT_FAILURE );
-	// } // if
+	// -E flag stops at cc1 stage 1, so cfa-cpp in cc1 stage 2 is never executed.
+	if ( cpp_flag && CFA_flag ) {
+		cerr << argv[0] << " error, cannot use -E and -CFA flags together." << endl;
+		exit( EXIT_FAILURE );
+	} // if
 
 	// add the CFA include-library paths, which allow direct access to header files without directory qualification
@@ -292,5 +296,5 @@
 	} // if
 
-	string arch = m32 ? CFA_32_CPU : (m64 ? CFA_64_CPU : CFA_DEFAULT_CPU);
+	string arch( m32 ? CFA_32_CPU : (m64 ? CFA_64_CPU : CFA_DEFAULT_CPU) );
 	if ( ! m32 && ! m64 ) {
 		if ( arch == "x86" ) {
@@ -301,5 +305,5 @@
 	} // if
 
-	string libdir = libbase + arch + "-" + (nolib ? "nolib" : (debug ? "debug": "nodebug"));
+	string libdir( libbase + arch + "-" + (nolib ? "nolib" : (debug ? "debug": "nodebug")) );
 	if ( ! dirExists( libdir ) ) {
 		cerr << argv[0] << " internal error, cannot find prelude directory " << libdir << endl;
@@ -350,4 +354,6 @@
 		Putenv( argv, "-N" );
 		Putenv( argv, "-CFA" );
+		// -CFA implies cc1 stage 2, but gcc does not pass the -o file to this stage because it believe the file is for
+		// the linker. Hence, the -o file is explicit passed to cc1 stage 2 and used as cfa-cpp's output file.
 		if ( o_file ) Putenv( argv, string( "-o=" ) + argv[o_file] );
 	} else {
@@ -401,10 +407,10 @@
 	} // if
 
-	args[nargs] = NULL;									// terminate
+	args[nargs] = nullptr;								// terminate
 
 	#ifdef __DEBUG_H__
 	cerr << "nargs: " << nargs << endl;
 	cerr << "args:" << endl;
-	for ( int i = 0; args[i] != NULL; i += 1 ) {
+	for ( int i = 0; args[i] != nullptr; i += 1 ) {
 		cerr << " \"" << args[i] << "\"" << endl;
 	} // for
@@ -428,5 +434,5 @@
 		if ( argc == 2 ) exit( EXIT_SUCCESS );			// if only the -v flag is specified, do not invoke gcc
 
-		for ( int i = 0; args[i] != NULL; i += 1 ) {
+		for ( int i = 0; args[i] != nullptr; i += 1 ) {
 			cerr << args[i] << " ";
 		} // for
