OpenJDK / haiku / haiku / hotspot
changeset 988:dd0b2e35d4ea
Files unchanged from original C++ version
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/Database.h Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,95 @@ +/* + * @(#)Database.h 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.*; + +#ifndef _MAKEDEFS_DATABASE_H_ +#define _MAKEDEFS_DATABASE_H_ + +#include <iostream> +#include <fstream> +#include <string> + +class MacroDefinitions; +class FileList; +class Platform; +class Macro; + +class Database { +private: + MacroDefinitions * macros; + // allFiles is kept in lexicographically sorted order. See get(). + FileList * allFiles; + // files that have implicit dependency on platform files + // e.g. os.hpp: os_<os_family>.hpp os_<os_arch>.hpp but only + // recorded if the platform file was seen. + FileList * platformFiles; + FileList * outerFiles; + FileList * indivIncludes; + FileList * grandInclude; // the results for the grand include file + long threshold; + int nOuterFiles; + int nPrecompiledFiles; + bool missingOk; + Platform * plat; + /** 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) */ + std::string firstFile; + std::string lastFile; + +public: + Database(Platform * plat, long t) ; + FileList * getAllFiles() ; + + vector < Macro * > ::iterator getMacrosBegin() ; + vector < Macro * > ::iterator getMacrosEnd() ; + + void canBeMissing() ; + + bool hfileIsInGrandInclude(FileList * hfile, FileList * cfile) ; + + /** 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 setFirstFile(std::string fileName) ; + + void setLastFile(std::string fileName) ; + + void get(std::string platFileName, std::string dbFileName) ; + + void compute() ; + + // Not sure this is necessary in Java + void verify() ; + + void put() ; + +private: + void writeIndividualIncludes() ; + + void writeGrandInclude() ; + + void writeGrandUnixMakefile() ; + +public: + void putDiffs(Database * previous) ; + +private: + void printDependentOn(ofstream & gd, std::string name) ; + + bool isOuterFile(std::string s) ; + + std::string removeSuffixFrom(std::string s) ; +}; + +#endif // _MAKEDEFS_DATABASE_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/DirectoryTreeNode.h Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,30 @@ +/* + * @(#)DirectoryTreeNode.h 1.0 02/07/23 05:36:53 + * + * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +// import java.util.*; + +#ifndef _MAKEDEFS_DIRECTORY_TREE_NODE_H_ +#define _MAKEDEFS_DIRECTORY_TREE_NODE_H_ + +#include <string> +#include <vector> +#include "Exceptions.h" + +class DirectoryTreeNode { +public: + virtual bool isFile() = 0; + virtual bool isDirectory() = 0; + virtual std::string getName() = 0; + virtual std::string getParent() = 0; + virtual vector<>::iterator getChildrenBegin() throw (IllegalArgumentException) = 0; + virtual vector<>::iterator getChildrenEnd() throw (IllegalArgumentException) = 0; + virtual int getNumChildren() throw (IllegalArgumentException) = 0; + virtual DirectoryTreeNode * getChild(int i) + throw (IllegalArgumentException, ArrayIndexOutOfBoundsException) = 0; +}; + +#endif // _MAKEDEFS_DIRECTORY_TREE_NODE_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/Exceptions.cpp Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,76 @@ +// Original Author : Andrew Bachmann +// Creation Date : July 23, 2002 1:43 AM +// Exceptions for MakeDefs + +#include <string> +#include "Exceptions.h" + +Exception::Exception() +{ +} + +Exception::Exception(std::string message) +{ + _message = message; +} + +std::string +Exception::getMessage() +{ + return _message; +} + +IOException::IOException() : Exception() +{ +} + +IOException::IOException(std::string message) + : Exception(message) +{ +} + +// runtime exception + +RuntimeException::RuntimeException() : Exception() +{ +} + +RuntimeException::RuntimeException(std::string message) + : Exception(message) +{ +} + +//// Runtime Exceptions +// NoSuchElementException + +NoSuchElementException::NoSuchElementException() : RuntimeException() +{ +} + +NoSuchElementException::NoSuchElementException(std::string message) + : RuntimeException(message) +{ +} + +// IllegalArgumentException + +IllegalArgumentException::IllegalArgumentException() : RuntimeException() +{ +} + +IllegalArgumentException::IllegalArgumentException(std::string message) + : RuntimeException(message) +{ +} + +// NullPointerException + +NullPointerException::NullPointerException() : RuntimeException() +{ +} + +NullPointerException::NullPointerException(std::string message) + : RuntimeException(message) +{ +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/Exceptions.h Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,52 @@ +// Original Author : Andrew Bachmann +// Creation Date : July 23, 2002 1:23 AM +// Exceptions for MakeDefs + + +#ifndef _MAKEDEFS_EXCEPTIONS_H_ +#define _MAKEDEFS_EXCEPTIONS_H_ + +#include <string> + +class Exception { +public: + Exception(); + Exception(std::string message); + std::string getMessage(); +private: + std::string _message; +}; + +class IOException : public Exception { +public: + IOException(); + IOException(std::string message); +}; + +class RuntimeException : public Exception { +public: + RuntimeException(); + RuntimeException(std::string message); +}; + +// runtime exceptions + +class NoSuchElementException : public RuntimeException { +public: + NoSuchElementException(); + NoSuchElementException(std::string message); +}; + +class IllegalArgumentException : public RuntimeException { +public: + IllegalArgumentException(); + IllegalArgumentException(std::string message); +}; + +class NullPointerException : public RuntimeException { +public: + NullPointerException(); + NullPointerException(std::string message); +}; + +#endif // _MAKEDEFS_EXCEPTIONS_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/FileFormatException.cpp Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,18 @@ +/* + * @(#)FileFormatException.cpp 1.0 02/07/23 01:55:53 + * + * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#include "FileFormatException.h" +#include "Exceptions.h" + +FileFormatException::FileFormatException() : Exception() +{ +} + +FileFormatException::FileFormatException(std::string message) + : Exception(message) +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/FileFormatException.h Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,20 @@ +/* + * @(#)FileFormatException.h 1.0 02/07/23 01:38:53 + * + * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#ifndef _MAKEDEFS_FILE_FORMAT_EXCEPTION_H_ +#define _MAKEDEFS_FILE_FORMAT_EXCEPTION_H_ + +#include <string> +#include "Exceptions.h" + +class FileFormatException : public Exception { +public: + FileFormatException(); + FileFormatException(std::string message); +}; + +#endif // _MAKEDEFS_FILE_FORMAT_EXCEPTION_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/FileList.cpp Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,322 @@ +/* + * @(#)FileList.cpp 1.0 02/07/23 03:28:54 + * + * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +//import java.io.*; +//import java.util.*; + +/** This class implements the java.util.List interface as well as + providing functionality specific to keeping track of lists of + files. See the documentation for the Database class to see how + these are used. Each FileList must only contain other FileLists + (although that is not currently enforced in the mutators). */ + +#include <string> +#include <vector> +#include <algorithm> +#include <iostream> +#include <fstream> +#include "sstream" + +#include "Platform.h" +#include "FileList.h" +#include "FileName.h" +#include "Database.h" + +FileList::FileList(std::string n, Platform * plat) { + this->plat = plat; + beenHere = mayBeCycle = isCycle = false; + platformDependentInclude = ""; + name = n; + count = 0; + useGrandInclude = plat->haveGrandInclude(); +} + +// Necessary accessors +std::string +FileList::getName() +{ + return name; +} + +void +FileList::setPlatformDependentInclude(std::string arg) +{ + platformDependentInclude = arg; +} + +std::string +FileList::getPlatformDependentInclude() +{ + return platformDependentInclude; +} + +bool +FileList::getUseGrandInclude() +{ + return useGrandInclude; +} + +void +FileList::setUseGrandInclude(bool arg) +{ + useGrandInclude = arg; +} + +void +FileList::incrementCount() +{ + count++; +} + +int +FileList::getCount() +{ + return count; +} + +FileList * +FileList::listForFile(std::string fileName) +{ + vector < FileList* >::iterator iter; + for (iter = Vector.begin(); iter != Vector.end(); iter++) { + FileList * fl = *iter; + if (plat->fileNameStringEquality(fl->name, fileName)) { + plat->fileNamePortabilityCheck(fl->name, fileName); + return fl; + } + } + plat->fileNamePortabilityCheck(fileName); + FileList * newList = new FileList(fileName, plat); + Vector.push_back(newList); + return newList; +} + +bool +FileList::hasListForFile(std::string fileName) +{ + vector < FileList* >::iterator iter; + for (iter = Vector.begin(); iter != Vector.end(); iter++) { + FileList * fl = *iter; + if (plat->fileNameStringEquality(fl->name, fileName)) { + plat->fileNamePortabilityCheck(fl->name, fileName); + return true; + } + } + return false; +} + +bool +FileList::compareLists(FileList * s) +{ + vector < FileList* >::iterator myIter = Vector.begin(); + vector < FileList* >::iterator hisIter = s->Vector.begin(); + while ((myIter != Vector.end()) + && (hisIter != s->Vector.end())) { + // crude: order dependent + FileList * myElement = *myIter; + FileList * hisElement = *hisIter; + if (!plat->fileNameStringEquality(myElement->name,hisElement->name)) { + return false; + } + myIter++; + hisIter++; + } + if ((myIter != Vector.end()) + || (hisIter != s->Vector.end())) { + // One ended earlier + return false; + } + return true; +} + +void +FileList::addIfAbsent(FileList * s) +{ + vector < FileList* >::iterator iter; + for (iter = Vector.begin(); iter != Vector.end(); iter++) { + if (*iter == s) { + return; + } + } + Vector.push_back(s); +} + +bool comparison(FileList * a, FileList * b) { + return (a->getName() < b->getName()); +} + +void +FileList::sortByName() +{ + sort(Vector.begin(),Vector.end(),&comparison); +} + +void +FileList::setFirstFile(FileList * s) +{ + vector < FileList* >::iterator iter = Vector.begin(); + // insert at the front + iter = Vector.insert(iter,s); + // then skip over it and check for any already existing + iter++; + while (iter != Vector.end()) { + if (s == *iter) { + iter = Vector.erase(iter); + break; // java.util.Vector.remove() only removes first occurance + } + else { + iter++; + } + } +} + +void +FileList::setLastFile(FileList * s) +{ + vector < FileList* >::iterator iter; + // Remove the file list if it's already here + iter = Vector.begin(); + while (iter != Vector.end()) { + if (s == *iter) { + iter = Vector.erase(iter); + break; // java.util.Vector.remove() only removes first occurance + } else { + iter++; + } + } + // insert it at the back + Vector.push_back(s); +} + +bool +FileList::doFiles(FileList * s) +{ + bool result = true; + vector < FileList* >::iterator iter; + for (iter = Vector.begin(); iter != Vector.end(); iter++) { + FileList * h = *iter; + if (h->platformDependentInclude != "") { + cerr << "Error: the source for " + << h->platformDependentInclude + << " is " << h->name << "." << endl; + cerr << "\tIt shouldn't be included directly by " + << name + "." << endl; + h->platformDependentInclude = ""; // report once per file + result = false; + } + h->doHFile(s); + } + return result; +} + +void +FileList::traceCycle(FileList * s) +{ + if (isCycle) // already traced + return; + isCycle = true; + cerr << "\ttracing cycle for " << name << endl; + // FIXME: must return status in caller routine + // exitCode = 1; + vector < FileList* >::iterator iter; + for (iter = Vector.begin(); iter != Vector.end(); iter++) { + FileList * q = *iter; + if (q->mayBeCycle) { + if (s == q) { + std::ostringstream errorMessage; + errorMessage << "\tend of cycle for " << s->getName(); + plat->fatalError(errorMessage.str()); + } else { + q->traceCycle(s); + } + } + } +} + +void +FileList::doHFile(FileList * s) +{ + if (beenHere) { + if (mayBeCycle) { + traceCycle(this); + } + return; + } + beenHere = true; + mayBeCycle = true; + doFiles(s); + mayBeCycle = false; + s->Vector.push_back(this); +} + +FileList * +FileList::doCFile() +{ + FileList * s = new FileList(name, plat); + s->useGrandInclude = useGrandInclude; // propagate this + doFiles(s); + vector < FileList* >::iterator iter; + for (iter = s->Vector.begin(); iter != s->Vector.end(); iter++) { + FileList * l = *iter; + l->beenHere = false; + } + return s; +} + +/** if .h file is included thresh times, put it in the grand + include file */ +void +FileList::putInclFile(Database * db) +throw (IOException) +{ + bool needline = true; + FileName * inclName = plat->getInclFileTemplate()->copyStem(name); + ofstream inclFile(inclName->dirPreStemSuff().c_str(),ios::out); + if (plat->haveGrandInclude() && plat->includeGIInEachIncl()) { + inclFile << "# include \"" + << plat->getGIFileTemplate()->dirPreStemAltSuff() + << "\"" << endl; + needline = false; + } + vector < FileList* >::iterator iter; + for (iter = Vector.begin(); iter != Vector.end(); iter++) { + FileList * hfile = *iter; + if (!db->hfileIsInGrandInclude(hfile, this)) { + inclFile << "# include \"" + << plat->getInclFileTemplate()->getInvDir() + << hfile->name << "\"" << endl; + needline = false; + } + } + + // Solaris C++ in strict mode warns about empty files + + if(needline) { + inclFile << endl; + } + inclFile.close(); +} + +vector < FileList* > ::iterator +FileList::begin() { + return Vector.begin(); +} + +vector < FileList* > ::iterator +FileList::end() { + return Vector.end(); +} + +void +FileList::push_back(FileList * item) { + Vector.push_back(item); +} + +bool +FileList::empty() { + return Vector.empty(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/FileList.h Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,88 @@ +/* + * @(#)FileList.h 1.0 02/07/23 04:10:54 + * + * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +//import java.io.*; +//import java.util.*; + +/** This class implements the java.util.List interface as well as + providing functionality specific to keeping track of lists of + files. See the documentation for the Database class to see how + these are used. Each FileList must only contain other FileLists + (although that is not currently enforced in the mutators). */ + +#include <string> +#include <vector> + +//extends Vector +class FileList { +private: + std::string name; // (also the file name) + bool beenHere; + bool mayBeCycle; + bool isCycle; + /** Put in list because a file can refuse to */ + bool useGrandInclude; + std::string platformDependentInclude; + int count; + Platform * plat; + vector < FileList* > Vector; + +public: + FileList(std::string n, Platform * plat); + +// // Change definition of equality from AbstractList so remove() works properly +// bool equals(Object o) { +// return ((Object) this) == o; +// } + + // Necessary accessors + std::string getName(); + + void setPlatformDependentInclude(std::string arg); + + std::string getPlatformDependentInclude(); + + bool getUseGrandInclude(); + + void setUseGrandInclude(bool arg); + + void incrementCount(); + + int getCount(); + + FileList * listForFile(std::string fileName); + + bool hasListForFile(std::string fileName); + + bool compareLists(FileList * s); + + void addIfAbsent(FileList * s); + + void sortByName(); + + void setFirstFile(FileList * s); + + void setLastFile(FileList * s); + + bool doFiles(FileList * s); + + void traceCycle(FileList * s); + + void doHFile(FileList * s); + + FileList * doCFile(); + + /** if .h file is included thresh times, put it in the grand + include file */ + void putInclFile(Database * db) + throw (IOException); + + vector < FileList* > ::iterator begin(); + vector < FileList* > ::iterator end(); + void push_back(FileList * item); + bool empty(); +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/FileName.cpp Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,94 @@ +/* + * @(#)FileName.cpp 1.0 02/07/23 02:19:54 + * + * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#include <string> +#include "sstream" +#include "Exceptions.h" +#include "Platform.h" +#include "FileName.h" + +/** None of the passed strings may be null. */ +FileName::FileName(Platform * plat, std::string dir, std::string prefix, + std::string stem, std::string suffix, + std::string inverseDir, std::string altSuffix) + throw (NullPointerException) +{ + this->plat = plat; + + this->dir = dir; + this->prefix = prefix; + this->stem = stem; + this->suffix = suffix; + this->inverseDir = inverseDir; + this->altSuffix = altSuffix; + + pss = prefix + stem + suffix; + dpss = dir + prefix + stem + suffix; + psa = prefix + stem + altSuffix; + dpsa = dir + prefix + stem + altSuffix; + + checkLength(plat); +} + +void +FileName::checkLength(Platform * p) { + string::size_type len; + std::string s; + string::size_type suffLen = suffix.length(); + string::size_type altSuffLen = altSuffix.length(); + if (suffLen >= altSuffLen) { + len = suffLen; + s = suffix; + } else { + len = altSuffLen; + s = altSuffix; + } + len += prefix.length() + stem.length(); + string::size_type lim = p->fileNameLengthLimit(); + if (len > lim) { + std::ostringstream errorMessage; + errorMessage << prefix << stem << s << " is too long: " + << len << " >= " << lim; + p->fatalError(errorMessage.str()); + } +} + +std::string +FileName::dirPreStemSuff() { + return dpss; +} + +std::string +FileName::preStemSuff() { + return pss; +} + +std::string +FileName::dirPreStemAltSuff() { + return dpsa; +} + +std::string +FileName::preStemAltSuff() { + return psa; +} + +FileName * +FileName::copyStem(std::string newStem) { + return new FileName(plat, dir, prefix, newStem, + suffix, inverseDir, altSuffix); +} + +std::string +FileName::nameOfList() { + return stem; +} + +std::string +FileName::getInvDir() { + return inverseDir; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/FileName.h Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,56 @@ +/* + * @(#)FileName.h 1.0 02/07/23 02:29:54 + * + * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#ifndef _MAKEDEFS_FILE_NAME_H_ +#define _MAKEDEFS_FILE_NAME_H_ + +#include <string> +#include "Exceptions.h" + +class Platform; + +class FileName { +private: + std::string dir; + std::string prefix; + std::string stem; + std::string suffix; + std::string inverseDir; + std::string altSuffix; + + std::string dpss; + std::string psa; + std::string dpsa; + std::string pss; + + Platform * plat; + +public: + /** None of the passed strings may be null. */ + FileName(Platform * plat, std::string dir, std::string prefix, + std::string stem, std::string suffix, + std::string inverseDir, std::string altSuffix) + throw (NullPointerException); + + void checkLength(Platform * p); + + std::string dirPreStemSuff(); + + std::string preStemSuff(); + + std::string dirPreStemAltSuff(); + + std::string preStemAltSuff(); + + FileName * copyStem(std::string newStem); + + std::string nameOfList(); + + std::string getInvDir(); +}; + +#endif // _MAKEDEFS_FILE_NAME_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/Macro.h Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,19 @@ +/* + * @(#)Macro.h 1.0 02/07/23 00:39:54 + * + * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#ifndef _MAKEDEFS_MACRO_H_ +#define _MAKEDEFS_MACRO_H_ + +#include <string> + +class Macro { +public: + std::string name; + std::string contents; +}; + +#endif // _MAKEDEFS_MACRO_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/MacroDefinitions.cpp Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,257 @@ +/* + * @(#)MacroDefinitions.cpp 1.0 02/07/22 23:24:55 + * + * 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 <vector> +#include <string> +#include <iostream> +#include <fstream> + +#include "MacroDefinitions.h" +#include "Exceptions.h" +#include "Macro.h" + +MacroDefinitions::MacroDefinitions() +{ +// macros = new Vector(); +} + +std::string +MacroDefinitions::lookup(std::string name) throw (NoSuchElementException) +{ + std::vector < Macro* >::iterator iter; + for (iter = macros.begin(); iter != macros.end(); iter++ ) { + Macro * macro = *iter; + if (macro->name == name) { + return macro->contents; + } + } + throw NoSuchElementException(); +} + +void +MacroDefinitions::addMacro(std::string name, std::string contents) +{ + Macro * macro = new Macro(); + macro->name = name; + macro->contents = contents; + macros.push_back(macro); +} + +bool +MacroDefinitions::lineIsEmpty(std::string s) +{ + return (s.find_first_not_of(" \t\n") == string::npos); +} + +void +MacroDefinitions::readFrom(std::string fileName, bool missingOk) +// throws FileNotFoundException, FileFormatException, IOException +{ + ifstream reader; + reader.open(fileName.c_str(),ios::in); + if (!reader.is_open()) { + if (missingOk) { + return; + } else { + cerr << "Could not open file: " << fileName << endl; + exit(-1); + } + } + + std::string line; + do { + getline(reader,line); + if (line.length() == 0) { + if (reader.eof()) { + break; + } + if (reader.fail()) { + cerr << "getline failed on: " << fileName << endl; + exit(-1); + } + continue; + } + + // This had to be rewritten (compare to Database.java) + // because the Solaris platform file has been + // repurposed and now contains "macros" with spaces in + // them. + + if (line.compare("//",2)==0) continue; + if (lineIsEmpty(line)) continue; + + string::size_type nameBegin; + string::size_type nameEnd; + bool gotEquals = false; + string::size_type contentsBegin; + string::size_type contentsEnd; + + // Scan forward for beginning of name + nameBegin = line.find_first_not_of(" \t\n"); + if (nameBegin == string::npos) { + nameBegin = line.length(); + } + + // Scan forward for end of name + nameEnd = line.find_first_of(" \t\n",nameBegin); + if (nameEnd == string::npos) { + nameEnd = line.length(); + } + + // Scan forward for equals sign + string::size_type i = line.find('=',nameEnd); + gotEquals = (i != string::npos); + if (i == string::npos) { + i = line.length(); + } + + // Scan forward for start of contents + contentsBegin = line.find_first_not_of(" \t\n",i+1); + if (contentsBegin == string::npos) { + contentsBegin = line.length(); + } + + // Scan *backward* for end of contents + contentsEnd = line.find_last_not_of(" \t\n")+1; + if (contentsEnd == string::npos) { + contentsEnd = line.length(); + } + + // Now do consistency check + if (!((nameBegin < nameEnd) && + (nameEnd < contentsBegin) && + (contentsBegin < contentsEnd) && + (gotEquals == true))) { + cerr << "Expected \"macroname = value\", " + << "but found: " << line << endl; + exit(-1); + } + + std::string name = line.substr(nameBegin,nameEnd-nameBegin); + std::string contents = line.substr(contentsBegin,contentsEnd-contentsBegin+1); + addMacro(name, contents); + } while (!reader.eof()); + reader.close(); +} + +/** Throws IllegalArgumentException if passed token is illegally + formatted */ +std::string +MacroDefinitions::expand(std::string token) +// throws IllegalArgumentException +{ + // the token may contain one or more <macroName>'s + + std::string out = ""; + + // emacs lingo + string::size_type mark = 0; + string::size_type point = 0; + + string::size_type len = token.length(); + + if (len == 0) + return out; + + do { + // Scan "point" forward until hitting either the end of + // the string or the beginning of a macro + point = token.find('<',point); + + if (point == string::npos) { + point = len; + break; + } + + // Append (point - mark) to out + if ((point - mark) != 0) { + out += token.substr(mark, point-mark); + } + mark = point + 1; + // Scan forward from point for right bracket + point = token.find('>',point); + if (point == string::npos) { + cerr << "Could not find right angle-bracket in token " + << token << endl; + exit(-1); + } + if (mark >= point) { + cerr << "Empty macro in token " + << token << endl; + exit(-1); + } + std::string name = token.substr(mark, point-mark); + std::string contents; + try { + contents = lookup(name); + out += contents; + point++; + mark = point; + } catch (NoSuchElementException n) { + cerr << "Unknown macro " << name + << " in token " << token << endl; + exit(-1); + } + } while (point != len); + + if (mark != point) { + out += token.substr(mark, point); + } + + return out; +} + +MacroDefinitions * +MacroDefinitions::copy() +{ + MacroDefinitions * ret = new MacroDefinitions(); + std::vector < Macro* >::iterator iter; + for (iter = macros.begin(); iter != macros.end(); iter++ ) { + Macro * orig = *iter; + Macro * macro = new Macro(); + macro->name = orig->name; + macro->contents = orig->contents; + ret->macros.push_back(macro); + } + return ret; +} + +void +MacroDefinitions::setAllMacroBodiesTo(std::string s) +{ + std::vector < Macro* >::iterator iter; + for (iter = macros.begin(); iter != macros.end(); iter++ ) { + Macro * macro = *iter; + macro->contents = s; + } +} + +/** This returns an Iterator of Macros. You should not mutate the + returned Macro objects or use the Iterator to remove + macros. */ +std::vector < Macro* >::iterator +MacroDefinitions::getMacrosBegin() +{ + return macros.begin(); +} + +std::vector < Macro* >::iterator +MacroDefinitions::getMacrosEnd() +{ + return macros.end(); +} + +void +MacroDefinitions::error(std::string text) // throws FileFormatException +{ + cerr << "Expected \"macroname = value\", but found: " + << text << endl; + exit(-1); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/MacroDefinitions.h Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,56 @@ +/* + * @(#)MacroDefinitions.h 1.0 02/07/22 23:24:55 + * + * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +// import java.io.*; +// import java.util.*; + +#ifndef _MAKEDEFS_MACRO_DEFINITIONS_H_ +#define _MAKEDEFS_MACRO_DEFINITIONS_H_ + +#include <string> +#include <vector> +#include "Macro.h" +#include "Exceptions.h" + +class MacroDefinitions { + +private: + std::vector < Macro* > macros; + +public: + MacroDefinitions() ; + +private: + std::string lookup(std::string name) throw (NoSuchElementException) ; + +public: + void addMacro(std::string name, std::string contents) ; + +private: + bool lineIsEmpty(std::string s) ; + +public: + void readFrom(std::string fileName, bool missingOk) ; + + std::string expand(std::string token) ; + + MacroDefinitions * copy() ; + + void setAllMacroBodiesTo(std::string s) ; + + /** This returns an Iterator of Macros. You should not mutate the + returned Macro objects or use the Iterator to remove + macros. */ + vector < Macro* > ::iterator getMacrosBegin() ; + + vector < Macro* > ::iterator getMacrosEnd() ; + +private: + void error(std::string text) ; +}; + +#endif // _MAKEDEFS_MACRO_DEFINITIONS_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/MakeDeps.cpp Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,196 @@ +/* + * @(#)MakeDeps.java 1.7 01/11/27 19:33:55 + * + * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +// This program reads an include file database. +// The database should cover each self .c and .h file, +// but not files in /usr/include +// The database consists of pairs of nonblank words, where the first word is +// the filename that needs to include the file named by the second word. +// For each .c file, this program generates a fooIncludes.h file that +// the .c file may include to include all the needed files in the right order. +// It also generates a foo.dep file to include in the makefile. +// Finally it detects cycles, and can work with two files, an old and a new one. +// To incrementally write out only needed files after a small change. +// +// Based on a suggestion by Roland Conybeare, algorithm suggested by Craig +// Chambers, written by David Ungar, 3/1/89. +// Added PREFIX, {DEP/INC}_DIR, smaller dep output 10/92 -Urs + +// Add something for precompiled headers + +// To handle different platforms, I am introducing a platform file. +// The platform file contains lines like: +// os = svr4 +// +// Then, when processing the includeDB file, a token such as <os> +// gets replaced by svr4. -- dmu 3/25/97 + +// Modified to centralize Dependencies to speed up make -- dmu 5/97 + +#include <string> +#include <vector> +#include <iostream> +#include "Exceptions.h" +#include "Platform.h" +#include "Database.h" +#include "MakeDeps.h" +#include "UnixPlatform.h" +#include "MetroWerksMacPlatform.h" + +// bootstrap method +int +main (int argc, char ** argv) +{ + vector < std::string > args; + for (int i = 1 ; i < argc ; i++) { + args.push_back(argv[i]); + } + MakeDeps::main(args); +} + +void MakeDeps::usage() { + cout << "usage:" << endl; + cout << "\tmakeDeps platform-name platform-file database-file [MakeDeps args] [platform args]" << endl; + cout << "\tmakeDeps diffs platform-name old-platform-file old-database-file new-platform-file new-database-file [MakeDeps args] [platform args]" << endl; + cout << "where platform-name is the name of a platform MakeDeps supports" << endl; + cout << "(currently \"UnixPlatform\" or \"MetroWerksMacPlatform\")" << endl; + cout << "MakeDeps options:" << endl; + cout << " -firstFile [filename]: Specify the first file in link order (i.e.," << endl; + cout << " to have a well-known function at the start of the output file)" << endl; + cout << " -lastFile [filename]: Specify the last file in link order (i.e.," << endl; + cout << " to have a well-known function at the end of the output file)" << endl; +} + +void MakeDeps::main(vector < std::string > args) { + try { + if (args.size() < 3) { + usage(); + exit(1); + } + + vector < std::string >::size_type argc = 0; + bool diffMode = false; + if (args[argc]=="diffs") { + diffMode = true; + ++argc; + } + + std::string platformName = args[argc++]; + + std::string plat1 = ""; + std::string db1 = ""; + std::string plat2 = ""; + std::string db2 = ""; + + std::string firstFile = ""; + std::string lastFile = ""; + + int numOptionalArgs = + (diffMode ? (args.size() - 6) : (args.size() - 3)); + if (numOptionalArgs < 0) { + usage(); + exit(1); + } + + plat1 = args[argc++]; + db1 = args[argc++]; + + if (diffMode) { + plat2 = args[argc++]; + db2 = args[argc++]; + } + + // argc now points at start of optional arguments, if any + + try { + bool gotOne = true; + while (gotOne && (argc < args.size() - 1)) { + gotOne = false; + std::string arg = args[argc]; + if (arg=="-firstFile") { + firstFile = args[argc + 1]; + argc += 2; + gotOne = true; + } else if (arg=="-lastFile") { + lastFile = args[argc + 1]; + argc += 2; + gotOne = true; + } + } + } + catch (Exception e) { + cerr << e.getMessage(); + usage(); + exit(1); + } + + Platform * platform; + if (platformName == "UnixPlatform") { + platform = new UnixPlatform(); + } else if (platformName == "MetroWerksMacPlatform") { + platform = new MetroWerksMacPlatform(); + } + + platform->setupFileTemplates(); + + long t = platform->defaultGrandIncludeThreshold(); + + vector < std::string > platformArgs; + vector < std::string >::size_type numPlatformArgs = args.size() - argc; + if (numPlatformArgs > (vector < std::string >::size_type)0) { + vector < std::string >::size_type offset = argc; + while (argc < args.size()) { + platformArgs[argc - offset] = args[argc]; + ++argc; + } + } + + // If you want to change the threshold, change the default + // "grand include" threshold in Platform.java, or override + // it in the platform-specific file like UnixPlatform.java + + Database * previous = new Database(platform, t); + Database * current = new Database(platform, t); + + previous->canBeMissing(); + + if (firstFile != "") { + previous->setFirstFile(firstFile); + current->setFirstFile(firstFile); + } + if (lastFile != "") { + previous->setLastFile(lastFile); + current->setLastFile(lastFile); + } + + if (diffMode) { + cout << "Old database:" << endl; + previous->get(plat1, db1); + previous->compute(); + cout << "New database:" << endl; + current->get(plat2, db2); + current->compute(); + cout << "Deltas:" << endl; + current->putDiffs(previous); + } else { + cout << "New database:" << endl; + current->get(plat1, db1); + current->compute(); + current->put(); + } + + if (platformArgs.size() > (vector < std::string >::size_type)0) { + // Allow the platform to write platform-specific files + platform->writePlatformSpecificFiles(previous, current, + platformArgs); + } + } + catch (Exception e) { + cout << e.getMessage() << endl << flush; + exit(1); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/MakeDeps.h Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,41 @@ +/* + * @(#)MakeDeps.h 1.0 02/07/23 05:54:55 + * + * Copyright 1993-2002 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +// This program reads an include file database. +// The database should cover each self .c and .h file, +// but not files in /usr/include +// The database consists of pairs of nonblank words, where the first word is +// the filename that needs to include the file named by the second word. +// For each .c file, this program generates a fooIncludes.h file that +// the .c file may include to include all the needed files in the right order. +// It also generates a foo.dep file to include in the makefile. +// Finally it detects cycles, and can work with two files, an old and a new one. +// To incrementally write out only needed files after a small change. +// +// Based on a suggestion by Roland Conybeare, algorithm suggested by Craig +// Chambers, written by David Ungar, 3/1/89. +// Added PREFIX, {DEP/INC}_DIR, smaller dep output 10/92 -Urs + +// Add something for precompiled headers + +// To handle different platforms, I am introducing a platform file. +// The platform file contains lines like: +// os = svr4 +// +// Then, when processing the includeDB file, a token such as <os> +// gets replaced by svr4. -- dmu 3/25/97 + +// Modified to centralize Dependencies to speed up make -- dmu 5/97 + +#include <string> +#include <vector> + +class MakeDeps { +public: + static void usage() ; + static void main(vector < std::string > args) ; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/MetroWerksMacPlatform.cpp Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,79 @@ +/* + * @(#)MetroWerksMacPlatform.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 "MetroWerksMacPlatform.h" +#include "FileName.h" +#include "Exceptions.h" + +std::vector < std::string > MetroWerksMacPlatform::suffixes; + +MetroWerksMacPlatform::MetroWerksMacPlatform() : Platform() +{ + suffixes.push_back(".cpp"); + suffixes.push_back(".c"); + suffixes.push_back(".s"); +} + +void +MetroWerksMacPlatform::setupFileTemplates() +{ + inclFileTemplate = new FileName(this, + ":incls:", "_", "", ".incl", "", "" + ); + giFileTemplate = new FileName(this, + "", "", "precompiledHeader", ".pch", "", "" + ); + gdFileTemplate = dummyFileTemplate; +} + +std::vector < std::string > +MetroWerksMacPlatform::outerSuffixes() +{ + return suffixes; +} + +bool +MetroWerksMacPlatform::includeGIInEachIncl() +{ + return true; +} + +int +MetroWerksMacPlatform::defaultGrandIncludeThreshold() +{ + return 150; +} + +void +MetroWerksMacPlatform::writeGIPragma(ostream & out) +{ + out << "#pragma precompile_target \"" + << giFileTemplate->preStemAltSuff() + << "\"" << endl; + out << endl; +} + +std::string +MetroWerksMacPlatform::objFileSuffix() +{ + throw RuntimeException("Unimplemented in original makeDeps"); +} + +std::string +MetroWerksMacPlatform::asmFileSuffix() +{ + throw RuntimeException("Unimplemented in original makeDeps"); +} + +std::string +MetroWerksMacPlatform::dependentPrefix() +{ + throw RuntimeException("Unimplemented in original makeDeps"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/MetroWerksMacPlatform.h Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,37 @@ +/* + * @(#)MetroWerksMacPlatform.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 <fstream> +#include <iostream> +#include "Platform.h" + +class MetroWerksMacPlatform : public Platform { +public: + MetroWerksMacPlatform(); + void setupFileTemplates(); + +private: + static std::vector < std::string > suffixes; + +public: + std::vector < std::string > outerSuffixes(); + + bool includeGIInEachIncl(); + + int defaultGrandIncludeThreshold(); + + void writeGIPragma(ostream & out); + + std::string objFileSuffix(); + + std::string asmFileSuffix(); + + std::string dependentPrefix(); + +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/makefile Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,123 @@ +## BeOS Generic Makefile v2.2 ## + +## Fill in this file to specify the project being created, and the referenced +## makefile-engine will do all of the hard work for you. This handles both +## Intel and PowerPC builds of the BeOS. + +## Application Specific Settings --------------------------------------------- + +# specify the name of the binary +NAME= MakeDeps + +# specify the type of binary +# APP: Application +# SHARED: Shared library or add-on +# STATIC: Static library archive +# DRIVER: Kernel Driver +TYPE= APP + +# add support for new Pe and Eddie features +# to fill in generic makefile + +#%{ +# @src->@ + +# specify the source files to use +# full paths or paths relative to the makefile can be included +# all files, regardless of directory, will have their object +# files created in the common object directory. +# Note that this means this makefile will not work correctly +# if two source files with the same name (source.c or source.cpp) +# are included from different directories. Also note that spaces +# in folder names do not work well with this makefile. +SRCS= Exceptions.cpp FileFormatException.cpp MacroDefinitions.cpp \ + FileName.cpp FileList.cpp Platform.cpp UnixPlatform.cpp \ + MetroWerksMacPlatform.cpp Database.cpp MakeDeps.cpp + + +# specify the resource files to use +# full path or a relative path to the resource file can be used. +RSRCS= + +# @<-src@ +#%} + +# end support for Pe and Eddie + +# specify additional libraries to link against +# there are two acceptable forms of library specifications +# - if your library follows the naming pattern of: +# libXXX.so or libXXX.a you can simply specify XXX +# library: libbe.so entry: be +# +# - if your library does not follow the standard library +# naming scheme you need to specify the path to the library +# and it's name +# library: my_lib.a entry: my_lib.a or path/my_lib.a +LIBS= stdc++.r4 + +# specify additional paths to directories following the standard +# libXXX.so or libXXX.a naming scheme. You can specify full paths +# or paths relative to the makefile. The paths included may not +# be recursive, so include all of the paths where libraries can +# be found. Directories where source files are found are +# automatically included. +LIBPATHS= + +# additional paths to look for system headers +# thes use the form: #include <header> +# source file directories are NOT auto-included here +SYSTEM_INCLUDE_PATHS = + +# additional paths to look for local headers +# thes use the form: #include "header" +# source file directories are automatically included +LOCAL_INCLUDE_PATHS = + +# specify the level of optimization that you desire +# NONE, SOME, FULL +OPTIMIZE= + +# specify any preprocessor symbols to be defined. The symbols will not +# have their values set automatically; you must supply the value (if any) +# to use. For example, setting DEFINES to "DEBUG=1" will cause the +# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" +# would pass "-DDEBUG" on the compiler's command line. +DEFINES= + +# specify special warning levels +# if unspecified default warnings will be used +# NONE = supress all warnings +# ALL = enable all warnings +WARNINGS = ALL + +# specify whether image symbols will be created +# so that stack crawls in the debugger are meaningful +# if TRUE symbols will be created +SYMBOLS = + +# specify debug settings +# if TRUE will allow application to be run from a source-level +# debugger. Note that this will disable all optimzation. +DEBUGGER = TRUE + +# specify additional compiler flags for all files +COMPILER_FLAGS = + +# specify additional linker flags +LINKER_FLAGS = + +# specify the version of this particular item +# (for example, -app 3 4 0 d 0 -short 340 -long "340 "`echo -n -e '\302\251'`"1999 GNU GPL") +# This may also be specified in a resource. +APP_VERSION = + +# (for TYPE == DRIVER only) Specify desired location of driver in the /dev +# hierarchy. Used by the driverinstall rule. E.g., DRIVER_PATH = video/usb will +# instruct the driverinstall rule to place a symlink to your driver's binary in +# ~/add-ons/kernel/drivers/dev/video/usb, so that your driver will appear at +# /dev/video/usb when loaded. Default is "misc". +DRIVER_PATH = + +## include the makefile-engine +include $(BUILDHOME)/etc/makefile-engine
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/MakeDeps/sstream Sat Oct 11 00:00:00 2003 -0700 @@ -0,0 +1,225 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 2000 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Magnus Fromreide (magfr@lysator.liu.se). */ + +#ifndef __SSTREAM__ +#define __SSTREAM__ + +#include <string> +#include <iostream.h> +#include <streambuf.h> + +namespace std +{ + class stringbuf : public streambuf + { + public: + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + + explicit stringbuf(int which=ios::in|ios::out) : + streambuf(which), buf(), mode(static_cast<ios::open_mode>(which)), + rpos(0), bufsize(1) + { } + + explicit stringbuf(const std::string &s, int which=ios::in|ios::out) : + streambuf(which), buf(s), mode(static_cast<ios::open_mode>(which)), + bufsize(1) + { + if(mode & ios::in) + { + setg(&defbuf, &defbuf + bufsize, &defbuf + bufsize); + } + if(mode & ios::out) + { + setp(&defbuf, &defbuf + bufsize); + } + rpos = (mode & ios::ate ? s.size() : 0); + } + + std::string str() const + { + const_cast<stringbuf*>(this)->sync(); // Sigh, really ugly hack + return buf; + }; + + void str(const std::string& s) + { + buf = s; + if(mode & ios::in) + { + gbump(egptr() - gptr()); + } + if(mode & ios::out) + { + pbump(pbase() - pptr()); + } + rpos = (mode & ios::ate ? s.size() : 0); + } + + protected: + inline virtual int sync(); + inline virtual int overflow(int = EOF); + inline virtual int underflow(); + private: + std::string buf; + ios::open_mode mode; + std::string::size_type rpos; + streamsize bufsize; + char defbuf; + }; + + class stringstreambase : virtual public ios { + protected: + stringbuf __my_sb; + public: + std::string str() const + { + return dynamic_cast<stringbuf*>(_strbuf)->str(); + } + void str(const std::string& s) + { + clear(); + dynamic_cast<stringbuf*>(_strbuf)->str(s); + } + + stringbuf* rdbuf() + { + return &__my_sb; + } + protected: + stringstreambase(int which) : + __my_sb(which) + { + init (&__my_sb); + } + + stringstreambase(const std::string& s, int which) : + __my_sb(s, which) + { + init (&__my_sb); + } + }; + + class istringstream : public stringstreambase, public istream { + public: + istringstream(int which=ios::in) : + stringstreambase(which) + { } + + istringstream(const std::string& s, int which=ios::in) : + stringstreambase(s, which) + { } + }; + + class ostringstream : public stringstreambase, public ostream { + public: + ostringstream(int which=ios::out) : + stringstreambase(which) + { } + + ostringstream(const std::string& s, int which=ios::out) : + stringstreambase(s, which) + { } + }; + + class stringstream : public stringstreambase, public iostream { + public: + stringstream(int which=ios::in|ios::out) : + stringstreambase(which) + { } + + stringstream(const std::string &s, int which=ios::in|ios::out) : + stringstreambase(s, which) + { } + }; +} + +inline int std::stringbuf::sync() +{ + if((mode & ios::out) == 0) + return EOF; + + streamsize n = pptr() - pbase(); + if(n) + { + buf.replace(rpos, std::string::npos, pbase(), n); + if(buf.size() - rpos != (std::string::size_type)n) + return EOF; + rpos += n; + pbump(-n); + gbump(egptr() - gptr()); + } + return 0; +} + +inline int std::stringbuf::overflow(int ch) +{ + if((mode & ios::out) == 0) + return EOF; + + streamsize n = pptr() - pbase(); + + if(n && sync()) + return EOF; + + if(ch != EOF) + { + std::string::size_type oldSize = buf.size(); + + buf.replace(rpos, std::string::npos, ch); + if(buf.size() - oldSize != 1) + return EOF; + ++rpos; + } + return 0; +} + +inline int std::stringbuf::underflow() +{ + sync(); + if((mode & ios::in) == 0) + { + return EOF; + } + if(rpos >= buf.size()) + { + return EOF; + } + + std::string::size_type n = egptr() - eback(); + std::string::size_type s; + + s = buf.copy(eback(), n, rpos); + pbump(pbase() - pptr()); + gbump(eback() - gptr()); + int res = (0377 & buf[rpos]); + rpos += s; + return res; +} + +#endif /* not __STRSTREAM__ */