changeset 987:b5b090ebd708

Files changed to bring C++ version up to date with openjdk
author bachmann
date Sat, 06 Jan 2007 00:00:00 -0800
parents 6d2de34fea1b
children dd0b2e35d4ea
files src/share/tools/MakeDeps/Database.cpp src/share/tools/MakeDeps/Platform.cpp src/share/tools/MakeDeps/Platform.h src/share/tools/MakeDeps/UnixPlatform.cpp src/share/tools/MakeDeps/UnixPlatform.h
diffstat 5 files changed, 973 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/MakeDeps/Database.cpp	Sat Jan 06 00:00:00 2007 -0800
@@ -0,0 +1,515 @@
+/*
+ * @(#)Database.cpp	1.0 02/07/22 20:09:52
+ *
+ * Copyright 1993-2002 Sun Microsystems, Inc.  All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
+ */
+
+// import java.io.*;
+// import java.util.*;
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string>
+
+#include "Database.h"
+#include "MacroDefinitions.h"
+#include "FileList.h"
+#include "Platform.h"
+#include "FileName.h"
+
+Database::Database(Platform * plat, long t)
+{
+	this->plat = plat;
+	macros          = new MacroDefinitions();
+	allFiles        = new FileList("allFiles", plat);
+	platformFiles   = new FileList("platformFiles", plat);
+	outerFiles      = new FileList("outerFiles", plat);
+	indivIncludes   = new FileList("IndivIncludes", plat);
+	grandInclude    = new FileList(plat->getGIFileTemplate()->nameOfList(), plat);
+	threshold = t;
+	nOuterFiles = 0;
+	nPrecompiledFiles = 0;
+	missingOk = false;
+	firstFile = "";
+	lastFile = "";
+}
+
+FileList *
+Database::getAllFiles()
+{
+	return allFiles;
+}
+
+vector < Macro* >::iterator 
+Database::getMacrosBegin()
+{
+	return macros->getMacrosBegin();
+}
+
+vector < Macro* >::iterator 
+Database::getMacrosEnd()
+{
+	return macros->getMacrosEnd();
+}
+
+void
+Database::canBeMissing()
+{
+	missingOk = true;
+}
+
+bool
+Database::hfileIsInGrandInclude(FileList * hfile, FileList * cfile)
+{
+	return ((hfile->getCount() >= threshold) && (cfile->getUseGrandInclude()));
+}
+
+/** These allow you to specify files not in the include database
+	which are prepended and appended to the file list, allowing
+	you to have well-known functions at the start and end of the
+	text segment (allows us to find out in a portable fashion
+	whether the current PC is in VM code or not upon a crash) */
+void
+Database::setFirstFile(std::string fileName)
+{
+	firstFile = fileName;
+}
+
+void
+Database::setLastFile(std::string fileName)
+{
+    lastFile = fileName;
+}
+
+void
+Database::get(std::string platFileName, std::string dbFileName)
+{
+	macros->readFrom(platFileName, missingOk);
+
+	ifstream dbFile;
+	dbFile.open(dbFileName.c_str(),ios::in);
+	if (!dbFile.is_open()) {
+	  if (missingOk) {
+	    return;
+	  } else {
+	    cerr << "Could not open file: " << dbFileName << endl;
+		exit(-1);
+	  }
+	}
+	cout << "\treading database: " << dbFileName << endl;
+	
+	std::string line;
+	int lineNo = 0;
+	do {
+		getline(dbFile,line);
+	    lineNo++;
+	    if (line.length() == 0) {
+	    	if (dbFile.eof()) {
+	    		break;
+	    	}
+	    	if (dbFile.fail()) {
+	    		cerr << "getline failed on: " << dbFileName << endl;
+				exit(-1);
+	    	}
+	    	continue;
+	    }
+
+		// ignore everything past double slashes "//"
+		string::size_type comments = line.find("//");
+		if (comments != string::npos) {
+			line.erase(comments);
+		}
+
+		int numTok = 0;
+		string::size_type start = 0;
+		string::size_type end = 0;
+		std::string unexpandedIncluder;
+		std::string unexpandedIncludee;
+		do {
+			std::vector<char> stack;
+			start = line.find_first_not_of(" \t",end);
+			if (start == string::npos) break; // no more words
+			end = line.find_first_of(" \t\n\0",start+1);
+			if (end == string::npos) {
+				end = line.length();
+			}
+			
+			if (numTok == 0) {
+				unexpandedIncluder = line.substr(start,end-start);
+			} else if (numTok == 1) {
+				unexpandedIncludee = line.substr(start,end-start);
+			} else {
+				cerr << "invalid line: " << line << endl;
+				cerr << "error position: line " << lineNo << endl;
+				exit(-1);
+			}
+			end++;
+			numTok++;
+		} while (end <= line.length());
+		
+		if ((numTok != 0) && (numTok != 2)) {
+			cerr << "invalid line: " << line << endl;
+			cerr << "error position: line " << lineNo << endl;
+			exit(-1);
+		}
+		
+		if (numTok == 0) continue; // empty line
+			
+	    // Non-empty line
+	    std::string includer = macros->expand(unexpandedIncluder);
+	    std::string includee = macros->expand(unexpandedIncludee);
+	    
+	    if (includee == plat->generatePlatformDependentInclude()) {
+			MacroDefinitions * localExpander = macros->copy();
+			MacroDefinitions * localExpander2 = macros->copy();
+			localExpander->setAllMacroBodiesTo("pd");
+			localExpander2->setAllMacroBodiesTo("");
+
+			// unexpanded_includer e.g. thread_<os_arch>.hpp
+			// thread_solaris_i486.hpp -> _thread_pd.hpp.incl
+
+			FileName * pdName =
+			    plat->getInclFileTemplate()->copyStem(localExpander->expand(unexpandedIncluder));
+
+			// derive generic name from platform specific name
+			// e.g. os_<arch_os>.hpp => os.hpp. We enforce the
+			// restriction (imperfectly) noted in includeDB_core
+			// that platform specific files will have an underscore 
+			// preceding the macro invocation.
+	
+			// First expand macro as null string.
+
+			std::string newIncluder_temp =
+				localExpander2->expand(unexpandedIncluder);
+
+			// Now find "_." and remove the underscore.
+
+			std::string newIncluder = "";
+				
+			int len = newIncluder_temp.length();
+			int count = 0;
+
+			for ( int i = 0; i < len - 1 ; i++ ) {
+			  if ((newIncluder_temp[i] == '_') && (newIncluder_temp[i+1] == '.')) {
+			    count++;
+			  } else {
+			    newIncluder += newIncluder_temp[i];
+			  }
+			}
+			newIncluder += newIncluder_temp[len-1];
+
+			if (count != 1) {
+				cerr << "unexpected filename format for platform dependent file." << endl;
+				cerr << "invalid line: " << line << endl;
+				cerr << "error position: " << lineNo << endl;
+				exit(-1);
+			}
+				
+			FileList * p = allFiles->listForFile(includer);
+			p->setPlatformDependentInclude(pdName->dirPreStemSuff());
+
+			// Add an implicit dependency on platform
+			// specific file for the generic file
+
+			p = platformFiles->listForFile(newIncluder);
+
+			// if this list is empty then this is 1st
+			// occurance of a platform dependent file and
+			// we need a new version of the include file.
+			// Otherwise we just append to the current
+			// file.
+
+			ofstream pdFile(pdName->dirPreStemSuff().c_str(),
+			                (p->empty() ? ios::out : ios::app));
+			pdFile << "# include \"" << includer << "\"" << endl;
+			pdFile.close();
+			
+			// Add the platform specific file to the list
+			// for this generic file.
+
+			FileList * q = allFiles->listForFile(includer);
+			p->addIfAbsent(q);
+	    } else {
+	    	FileList * p = allFiles->listForFile(includer);
+			if (isOuterFile(includer)) {
+			    outerFiles->addIfAbsent(p);
+			}
+
+			if (includee == plat->noGrandInclude()) {
+			    p->setUseGrandInclude(false);
+			} else {            
+			    FileList * q = allFiles->listForFile(includee);
+			    p->addIfAbsent(q);
+			}
+	    }
+    } while (!dbFile.eof());
+
+    dbFile.close();
+
+	// Keep allFiles in well-known order so we can easily determine
+	// whether the known files are the same
+	allFiles->sortByName();
+
+	// Add first and last files differently to prevent a mistake
+	// in ordering in the include databases from breaking the
+	// error reporting in the VM.
+	if (firstFile != "") {
+		FileList * p = allFiles->listForFile(firstFile);
+		allFiles->setFirstFile(p);
+		outerFiles->setFirstFile(p);	  
+	}
+	
+	if (lastFile != "") {
+		FileList * p = allFiles->listForFile(lastFile);
+		allFiles->setLastFile(p);
+		outerFiles->setLastFile(p);	  
+	}
+}
+
+void
+Database::compute()
+{
+	cout << "\tcomputing closures\n" << endl;
+	// build both indiv and grand results
+	vector < FileList* >::iterator iter;
+	for (iter = outerFiles->begin(); iter != outerFiles->end(); iter++ ) {
+	    indivIncludes->push_back((*iter)->doCFile());
+	    ++nOuterFiles;
+	}
+	     
+	if (!plat->haveGrandInclude())
+	    return; // nothing in grand include
+	          
+	// count how many times each include is included & add em to grand
+	for (iter = indivIncludes->begin(); iter != indivIncludes->end(); iter++ ) {
+	    FileList * indivInclude = *iter;
+	    if (!indivInclude->getUseGrandInclude()) {
+			continue; // do not bump count if my files cannot be in grand include
+	    }
+	    indivInclude->doFiles(grandInclude); // put em on grand_include list
+		vector < FileList* >::iterator incListIter;
+		for (incListIter = indivInclude->begin(); incListIter != indivInclude->end(); incListIter++ ) {
+			(*incListIter)->incrementCount();
+	    }
+	}
+}
+
+// Not sure this is necessary in Java
+void
+Database::verify()
+{
+	vector < FileList* > ::iterator iter;
+	for (iter = indivIncludes->begin(); iter != indivIncludes->end(); iter++ ) {
+	    if ((*iter) == 0) {
+			plat->abort();
+	    }
+	}
+}
+
+void
+Database::put()
+{
+	writeIndividualIncludes();
+	if (plat->haveGrandInclude()) {
+	    writeGrandInclude();
+	}
+	writeGrandUnixMakefile();
+}
+
+void
+Database::writeIndividualIncludes()
+{
+   	cout << "\twriting individual include files\n" << endl;
+  	vector < FileList* > ::iterator iter;
+	for (iter = indivIncludes->begin(); iter != indivIncludes->end(); iter++ ) {
+	    FileList * list = *iter;
+	    cout << "\tcreating " << list->getName() << endl;
+	    list->putInclFile(this);
+	}
+}
+    
+void
+Database::writeGrandInclude()
+{
+   	cout << "\twriting grand include file\n" << endl;
+   	ofstream inclFile(plat->getGIFileTemplate()->dirPreStemSuff().c_str(),ios::out);
+   	plat->writeGIPragma(inclFile);
+   	vector < FileList* > ::iterator iter;
+	for (iter = grandInclude->begin(); iter != grandInclude->end(); iter++ ) {
+	    FileList * list = *iter;
+	    if (list->getCount() >= threshold) {
+	    	inclFile << "# include \""
+	    			 << plat->getGIFileTemplate()->getInvDir()
+	    			 << list->getName() << "\"" << endl;
+			nPrecompiledFiles += 1;
+	    }
+	}
+	inclFile << endl;
+	inclFile.close();
+}
+
+void
+Database::writeGrandUnixMakefile()
+{
+	if (!plat->writeDeps())
+		return;
+
+	cout << "\twriting dependencies file" << endl;
+	ofstream gd(plat->getGDFileTemplate()->dirPreStemSuff().c_str(),ios::out);
+	gd << "# generated by MakeDeps.cpp" << endl;
+	gd << endl;
+	
+	{
+	    // write Obj_Files = ...
+	    gd << "Obj_Files = \\" << endl;
+	    vector < FileList* > ::iterator iter;
+	    for (iter = outerFiles->begin(); iter != outerFiles->end(); iter++ ) {
+			FileList * anOuterFile = *iter;
+
+			std::string stemName = removeSuffixFrom(anOuterFile->getName());
+			gd << stemName << plat->objFileSuffix() << " \\" << endl;
+	    }
+		gd << endl;
+		gd << endl;
+	}
+
+	if (nPrecompiledFiles > 0) {
+	    // write Precompiled_Files = ...
+	    gd << "Precompiled_Files = \\" << endl;
+	    vector < FileList* > ::iterator iter;
+	    for (iter = grandInclude->begin(); iter != grandInclude->end(); iter++ ) {
+			FileList * list = *iter;
+			gd << list->getName() << " \\" << endl;
+	    }
+		gd << endl;
+		gd << endl;
+	}
+
+	gd << "DTraced_Files = \\" << endl;
+	vector < FileList* > ::iterator dtraced_iter;
+	for (dtraced_iter = outerFiles->begin(); dtraced_iter != outerFiles->end(); dtraced_iter++ ) {
+		FileList * anOuterFile = *dtraced_iter;
+
+		if (anOuterFile->hasListForFile("dtrace.hpp")) {
+			std::string stemName = removeSuffixFrom(anOuterFile->getName());
+			gd << stemName << plat->objFileSuffix() << " \\" << endl;
+		}
+    }
+	gd << endl;
+	gd << endl;
+
+	{
+	    // write each dependency
+		vector < FileList* > ::iterator iter;
+	    for (iter = indivIncludes->begin(); iter != indivIncludes->end(); iter++ ) {
+			FileList * anII = *iter;
+	
+			std::string stemName = removeSuffixFrom(anII->getName());
+			std::string inclFileName =
+			    plat->getInclFileTemplate()->copyStem(anII->getName())->preStemSuff();
+	
+			gd << stemName << plat->objFileSuffix() << " "
+			   << stemName << plat->asmFileSuffix() << ": \\" << endl;
+			
+			printDependentOn(gd, anII->getName());
+			// this gets the include file that includes all that
+			// this file needs (first level) since nested includes
+			// are skipped to avoid cycles.
+			printDependentOn(gd, inclFileName);
+		
+			if ( plat->haveGrandInclude() ) {
+			    printDependentOn(gd,plat->getGIFileTemplate()->preStemSuff());
+			}
+
+			vector < FileList* > ::iterator iiIter;
+			for (iiIter = anII->begin(); iiIter != anII->end(); iiIter++ ) {
+			    FileList * hfile = *iiIter;
+			    if (!hfileIsInGrandInclude(hfile, anII) ||
+					plat->writeDependenciesOnHFilesFromGI()) {
+					printDependentOn(gd, hfile->getName());
+			    }
+			    if (platformFiles->hasListForFile(hfile->getName())) {
+					FileList * p =
+					    platformFiles->listForFile(hfile->getName());
+					vector < FileList* > ::iterator hiIter;
+					for (hiIter = p->begin(); hiIter != p->end(); hiIter++ ) {
+					    FileList * hi2 = *hiIter;
+					    if (!hfileIsInGrandInclude(hi2, p)) {
+							printDependentOn(gd, hi2->getName());
+					    }
+					}
+			    }
+			}
+
+			if (plat->includeGIDependencies()
+			     && nPrecompiledFiles > 0 
+			     && anII->getUseGrandInclude()) {
+			    gd << "    $(Precompiled_Files) \\" << endl;
+			}
+			gd << endl;
+			gd << endl;
+	    }
+	}
+
+	gd.close();
+}
+
+void
+Database::putDiffs(Database * previous)
+{
+   	cout << "\tupdating output files" << endl << endl;
+
+	if (!indivIncludes->compareLists(previous->indivIncludes)
+	     || !grandInclude->compareLists(previous->grandInclude)) {
+	    cout << "The order of .c or .s has changed, or the grand include file has changed." << endl;
+	    put();
+	    return;
+	}
+
+	vector < FileList* > ::iterator curIter = indivIncludes->begin();
+	vector < FileList* > ::iterator prevIter = previous->indivIncludes->begin();
+
+    while (curIter != indivIncludes->end()) {
+		FileList * newCFileList = *curIter++;
+		FileList * prevCFileList = *prevIter++;
+		if (!newCFileList->compareLists(prevCFileList)) {
+		    cout << "\tupdating " << newCFileList->getName() << endl;
+		    newCFileList->putInclFile(this);
+		}
+    }
+	writeGrandUnixMakefile();
+}
+
+void
+Database::printDependentOn(ofstream & gd, std::string name)
+{
+	gd << " ";
+	gd << plat->dependentPrefix() << name;
+}
+    
+bool
+Database::isOuterFile(std::string s)
+{
+	int len = s.length();
+	std::vector < std::string > suffixes = plat->outerSuffixes();
+	for (vector < FileList* > ::size_type i = 0; i < suffixes.size(); i++) {
+	    std::string suffix = suffixes[i];
+	    int suffLen = suffix.length();
+	    if ((len >= suffLen) &&
+			(plat->fileNameStringEquality(s.substr(len - suffLen),suffix))) {
+			return true;
+	    }
+	}
+	return false;
+}
+
+std::string
+Database::removeSuffixFrom(std::string s)
+{
+	string::size_type idx = s.rfind('.');
+	if (idx == string::npos)
+	    plat->abort();
+	return s.substr(0,idx);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/MakeDeps/Platform.cpp	Sat Jan 06 00:00:00 2007 -0800
@@ -0,0 +1,185 @@
+/*
+ * @(#)Platform.cpp	1.0 02/07/23 13:40:56
+ *
+ * Copyright 1993-2002 Sun Microsystems, Inc.  All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
+ */
+
+/** Defines what must be specified for each platform. This class must
+    have a no-arg constructor. */
+
+//import java.io.*;
+
+#include <vector>
+#include <string>
+#include <iostream>
+#include "sstream"
+#include "FileName.h"
+#include "Platform.h"
+
+Platform::Platform()
+{
+	dummyFileTemplate = new FileName(this, "", "", "", "", "", "");
+}
+
+// Accessors
+FileName *
+Platform::getInclFileTemplate()
+{
+	return inclFileTemplate;
+}
+
+FileName *
+Platform::getGIFileTemplate()
+{
+	return giFileTemplate;
+}
+
+FileName *
+Platform::getGDFileTemplate()
+{
+	return gdFileTemplate;
+}
+
+// an incl file is the file included by each.c file that includes
+// all needed header files
+
+/** empty file name -> no grand include file */
+bool
+Platform::haveGrandInclude()
+{
+	return (giFileTemplate->nameOfList().length() > 0);
+}
+
+bool
+Platform::writeDeps()
+{
+	return (gdFileTemplate->nameOfList().length() > 0);
+}
+
+/** <p> A gi file is the grand-include file. It includes in one
+file any file that is included more than a certain number of
+times. </p>
+
+<p> It is used for precompiled header files. </p>
+
+<p> It has a source name, that is the file that this program
+generates, and a compiled name; that is the file that is
+included by other files. </p>
+
+<p> Some platforms have this program actually explictly
+include the preprocessed gi file-- see includeGIInEachIncl().
+</p>
+
+<p> Also, some platforms need a pragma in the GI file. </p> */
+bool
+Platform::includeGIInEachIncl()
+{
+	return false;
+}
+
+/** For some platforms, e.g. Solaris, include the grand-include
+dependencies in the makefile. For others, e.g. Windows, do
+not. */
+bool
+Platform::includeGIDependencies()
+{
+	return false;
+}
+
+/** Should C/C++ source file be dependent on a file included
+into the grand-include file. */
+bool
+Platform::writeDependenciesOnHFilesFromGI()
+{
+    return false;
+}
+    
+/** Default implementation does nothing */
+void
+Platform::writeGIPragma(ostream & out)
+{
+}
+
+/** A line with a filename and the noGrandInclude string means
+that this file cannot use the precompiled header. */
+std::string
+Platform::noGrandInclude()
+{
+	return "no_precompiled_headers";
+}
+
+/** A line with a filename and the
+generatePlatformDependentInclude means that an include file
+for the header file must be generated. This file generated include
+file is directly included by the non-platform dependent include file
+(e.g os.hpp includes _os_pd.hpp.incl. So while we notice files that
+are directly dependent on non-platform dependent files from the database
+we must infer the dependence on platform specific files to generate correct
+dependences on the platform specific files. */
+std::string
+Platform::generatePlatformDependentInclude()
+{
+	return "generate_platform_dependent_include";
+}
+
+// Exit routines:
+
+/** Abort means an internal error */
+void
+Platform::abort() throw (RuntimeException)
+{
+	throw RuntimeException("Internal error");
+}
+
+/** fatalError is used by clients to stop the system */
+void
+Platform::fatalError(std::string msg)
+   {
+	cerr << msg << endl;
+	exit(1);
+   }
+
+/** Default implementation performs case-sensitive comparison */
+bool
+Platform::fileNameStringEquality(std::string s1, std::string s2)
+{
+	return s1==s2;
+}
+
+void
+Platform::fileNamePortabilityCheck(std::string name)
+{
+	if ((name[0]>'A')&&(name[0]<'Z')) {
+		std::ostringstream errorMessage;
+		errorMessage << "Error: for the sake of portability we have chosen" << endl
+		             << "to avoid files starting with an uppercase letter." << endl
+		             << "Please rename " << name << ".";
+		fatalError(errorMessage.str());
+	}
+}
+
+void
+Platform::fileNamePortabilityCheck(std::string name, std::string matchingName)
+{
+	if (name!=matchingName) {
+		std::ostringstream errorMessage;
+		errorMessage << "Error: file " << name << " also appears as "
+		             << matchingName << ".  Case must be consistent for "
+		             "portability.";
+		fatalError(errorMessage.str());
+	}
+}
+
+/** max is 31 on mac, so warn */
+string::size_type
+Platform::fileNameLengthLimit()
+{
+	return 40;
+}
+
+int
+Platform::defaultGrandIncludeThreshold()
+{
+	return 30;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/MakeDeps/Platform.h	Sat Jan 06 00:00:00 2007 -0800
@@ -0,0 +1,139 @@
+/*
+ * @(#)Platform.h	1.0 02/07/23 14:17:56
+ *
+ * Copyright 1993-2002 Sun Microsystems, Inc.  All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
+ */
+
+/** Defines what must be specified for each platform. This class must
+    have a no-arg constructor. */
+
+//import java.io.*;
+
+#ifndef _MAKEDEFS_PLATFORM_H_
+#define _MAKEDEFS_PLATFORM_H_
+
+#include <vector>
+#include <string>
+#include "Exceptions.h"
+
+class FileName;
+class Database;
+
+class Platform {
+protected:
+	Platform();
+	
+    /** file name templates capture naming conventions */
+	FileName * dummyFileTemplate;
+
+    // The next three must be instantiated in subclasses' constructors
+
+    /** An incl file is produced per .c file and contains all the
+	includes it needs */
+	FileName * inclFileTemplate;
+
+    /** A GI (grand-include) file has any file used more than N times
+	for precompiled headers */
+	FileName * giFileTemplate;
+
+    /** A GD (grand-dependencies) file that tells Unix make all the
+	.o's needed for linking and the include dependencies */
+    FileName * gdFileTemplate;
+
+    // Accessors
+public:
+    virtual FileName * getInclFileTemplate();
+
+    virtual FileName * getGIFileTemplate();
+
+    virtual FileName * getGDFileTemplate();
+
+    // an incl file is the file included by each.c file that includes
+    // all needed header files
+
+    virtual void setupFileTemplates() = 0;
+    virtual vector < std::string > outerSuffixes() = 0;
+
+    /** empty file name -> no grand include file */
+    virtual bool haveGrandInclude();
+
+    virtual bool writeDeps();
+
+    /** <p> A gi file is the grand-include file. It includes in one
+	file any file that is included more than a certain number of
+	times. </p>
+
+	<p> It is used for precompiled header files. </p>
+
+	<p> It has a source name, that is the file that this program
+	generates, and a compiled name; that is the file that is
+	included by other files. </p>
+
+	<p> Some platforms have this program actually explictly
+	include the preprocessed gi file-- see includeGIInEachIncl().
+	</p>
+
+	<p> Also, some platforms need a pragma in the GI file. </p> */
+    virtual bool includeGIInEachIncl();
+
+    /** For some platforms, e.g. Solaris, include the grand-include
+	dependencies in the makefile. For others, e.g. Windows, do
+	not. */
+    virtual bool includeGIDependencies();
+
+    /** Should C/C++ source file be dependent on a file included
+        into the grand-include file. */
+    virtual bool writeDependenciesOnHFilesFromGI();
+
+    /** Default implementation does nothing */
+    void writeGIPragma(ostream & out);
+
+    /** A line with a filename and the noGrandInclude string means
+	that this file cannot use the precompiled header. */
+    virtual std::string noGrandInclude();
+
+    /** A line with a filename and the
+	generatePlatformDependentInclude means that an include file
+	for the header file must be generated. This file generated include
+	file is directly included by the non-platform dependent include file
+	(e.g os.hpp includes _os_pd.hpp.incl. So while we notice files that
+	are directly dependent on non-platform dependent files from the database
+	we must infer the dependence on platform specific files to generate correct
+	dependences on the platform specific files. */
+    virtual std::string generatePlatformDependentInclude();
+
+    /** Prefix and suffix strings for emitting Makefile rules */
+    virtual std::string objFileSuffix() = 0;
+    virtual std::string asmFileSuffix() = 0;
+    virtual std::string dependentPrefix() = 0;
+
+    // Exit routines:
+
+    /** Abort means an internal error */
+    virtual void abort() throw (RuntimeException);
+
+    /** fatalError is used by clients to stop the system */
+    virtual void fatalError(std::string msg);
+
+    /** Default implementation performs case-sensitive comparison */
+    virtual bool fileNameStringEquality(std::string s1, std::string s2);
+
+    virtual void fileNamePortabilityCheck(std::string name);
+
+    virtual void fileNamePortabilityCheck(std::string name, std::string matchingName);
+
+    /** max is 31 on mac, so warn */
+    virtual string::size_type fileNameLengthLimit();
+
+    virtual int defaultGrandIncludeThreshold();
+
+    /** Not very general, but this is a way to get platform-specific
+        files to be written. Default implementation does nothing. */
+	virtual void writePlatformSpecificFiles(Database * previousDB,
+					   Database * currentDB, std::vector < std::string > args)
+	throw (IllegalArgumentException, IOException) {
+	};
+};
+
+#endif // _MAKEDEFS_PLATFORM_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/MakeDeps/UnixPlatform.cpp	Sat Jan 06 00:00:00 2007 -0800
@@ -0,0 +1,89 @@
+/*
+ * @(#)UnixPlatform.cpp	1.0 02/07/23 05:21:57
+ *
+ * Copyright 1993-2002 Sun Microsystems, Inc.  All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
+ */
+
+#include <vector>
+#include <string>
+#include "Platform.h"
+#include "UnixPlatform.h"
+#include "FileName.h"
+
+std::vector < std::string > UnixPlatform::suffixes;
+
+UnixPlatform::UnixPlatform() : Platform()
+{
+	suffixes.push_back(".cpp");
+	suffixes.push_back(".c");
+	suffixes.push_back(".s");
+}
+
+void 
+UnixPlatform::setupFileTemplates()
+{
+	inclFileTemplate = new FileName(this,
+	    "incls/", "_", "",             ".incl", "", ""
+	);
+	giFileTemplate = new FileName(this,
+	    "incls/", "",  "_precompiled", ".incl", "", ""
+	);
+	gdFileTemplate = new FileName(this,
+	    "",       "",  "Dependencies", "",      "", ""
+	);
+}
+    
+std::vector < std::string >
+UnixPlatform::outerSuffixes()
+{
+	return suffixes;
+}
+
+std::string
+UnixPlatform::objFileSuffix()
+{
+	return ".o";
+}
+
+std::string
+UnixPlatform::asmFileSuffix()
+{
+	return ".i";
+}
+
+std::string
+UnixPlatform::dependentPrefix()
+{
+	return "";
+}
+
+/** Do not change this; unless you fix things so precompiled
+	header files get translated into make dependencies. - Ungar */
+int
+UnixPlatform::defaultGrandIncludeThreshold()
+{
+    if (getenv("USE_PRECOMPILED_HEADER") != NULL)
+       return 30;
+	return 1 << 30;
+}
+
+/** For Unix make, include the dependencies for precompiled header
+    files. */
+bool
+UnixPlatform::includeGIDependencies()
+{
+	return false;
+}
+
+/** Should C/C++ source file be dependent on a file included
+    into the grand-include file.
+    On Unix with precompiled headers we don't want each file to be
+    dependent on grand-include file. Instead each C/C++ source file
+    is depended on each own set of files, and recompiled only when
+    files from this set are changed. */
+bool
+UnixPlatform::writeDependenciesOnHFilesFromGI()
+{
+    return getenv("USE_PRECOMPILED_HEADER") != NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/MakeDeps/UnixPlatform.h	Sat Jan 06 00:00:00 2007 -0800
@@ -0,0 +1,45 @@
+/*
+ * @(#)UnixPlatform.h	1.0 02/07/23 05:21:57
+ *
+ * Copyright 1993-2002 Sun Microsystems, Inc.  All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
+ */
+
+#include <vector>
+#include <string>
+#include "Platform.h"
+
+class UnixPlatform : public Platform {
+public:
+	UnixPlatform();
+    void setupFileTemplates();
+    
+private:
+	static std::vector < std::string > suffixes;
+
+public:
+    std::vector < std::string > outerSuffixes();
+
+    std::string objFileSuffix();
+
+    std::string asmFileSuffix();
+
+    std::string dependentPrefix();
+
+    /** Do not change this; unless you fix things so precompiled
+	header files get translated into make dependencies. - Ungar */
+    int defaultGrandIncludeThreshold();
+
+    /** For Unix make, include the dependencies for precompiled header
+        files. */
+    bool includeGIDependencies();
+
+    /** Should C/C++ source file be dependent on a file included
+        into the grand-include file.
+        On Unix with precompiled headers we don't want each file to be
+        dependent on grand-include file. Instead each C/C++ source file
+        is depended on each own set of files, and recompiled only when
+        files from this set are changed. */
+    bool writeDependenciesOnHFilesFromGI();
+
+};