+const char *openIntermed( const char *inputFileName, const char *outputFileName )
+{
+ srand(time(0));
+ const char *result = 0;
+
+ /* Which filename do we use as the base? */
+ const char *baseFileName = outputFileName != 0 ? outputFileName : inputFileName;
+
+ /* The template for the intermediate file name. */
+ const char *intermedFileName = makeIntermedTemplate( baseFileName );
+
+ /* Randomize the name and try to open. */
+ char fnChars[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ char *firstX = strrchr( intermedFileName, 'X' ) - 5;
+ for ( int tries = 0; tries < 20; tries++ ) {
+ /* Choose a random name. */
+ for ( int x = 0; x < 6; x++ )
+ firstX[x] = fnChars[rand() % 52];
+
+ /* Try to open the file. */
+ int fd = ::open( intermedFileName, O_WRONLY|O_EXCL|O_CREAT, S_IRUSR|S_IWUSR );
+
+ if ( fd > 0 ) {
+ /* Success. Close the file immediately and return the name for use
+ * by the child processes. */
+ ::close( fd );
+ result = intermedFileName;
+ break;
+ }
+
+ if ( errno == EACCES ) {
+ error() << "failed to open temp file " << intermedFileName <<
+ ", access denied" << endp;
+ }
+ }
+
+ if ( result == 0 )
+ error() << "abnormal error: cannot find unique name for temp file" << endp;
+
+ return result;
+}
+
+
+
+/* Main, process args and call yyparse to start scanning input. */
+int main( int argc, const char **argv )
+{
+ const char *inputFileName = 0;
+ processArgs( argc, argv, inputFileName );