From a9875aa62f41ed13b54ea9f92c65ade9f0df6845 Mon Sep 17 00:00:00 2001 From: Andy Cedilnik Date: Thu, 27 Mar 2003 12:24:30 -0500 Subject: [PATCH] Implement GetLineFromStream that actually works and use it instead of getline --- Source/cmCacheManager.cxx | 12 +++--- Source/cmConfigureFileCommand.cxx | 47 ++++++++++-------------- Source/cmListFileCache.cxx | 32 +++++++--------- Source/cmLocalVisualStudio6Generator.cxx | 19 ++++------ Source/cmMakeDepend.cxx | 6 +-- Source/cmOutputRequiredFilesCommand.cxx | 7 ++-- Source/cmSystemTools.cxx | 37 +++++++++++++++++-- Source/cmSystemTools.h | 9 +++++ Source/cmUseMangledMesaCommand.cxx | 33 +++++++---------- 9 files changed, 109 insertions(+), 93 deletions(-) diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 581f1188f..7b213a030 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -125,16 +125,15 @@ bool cmCacheManager::LoadCache(const char* path, { return false; } - const int bsize = 4096; - char buffer[bsize]; - char *realbuffer; + const char *realbuffer; + std::string buffer; std::string entryKey; while(fin) { // Format is key:type=value CacheEntry e; - fin.getline(buffer, bsize); - realbuffer = buffer; + cmSystemTools::GetLineFromStream(fin, buffer); + realbuffer = buffer.c_str(); while(*realbuffer != '0' && (*realbuffer == ' ' || *realbuffer == '\t' || @@ -150,7 +149,8 @@ bool cmCacheManager::LoadCache(const char* path, while(realbuffer[0] == '/' && realbuffer[1] == '/') { e.m_Properties["HELPSTRING"] += &realbuffer[2]; - fin.getline(realbuffer, bsize); + cmSystemTools::GetLineFromStream(fin, buffer); + realbuffer = buffer.c_str(); if(!fin) { continue; diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index d34586dc5..e43fc15d3 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -105,49 +105,42 @@ void cmConfigureFileCommand::ConfigureFile() // now copy input to output and expand variables in the // input file at the same time - const int bufSize = 4096; - char buffer[bufSize]; std::string inLine; cmRegularExpression cmdefine("#cmakedefine[ \t]*([A-Za-z_0-9]*)"); - while(fin) + while( cmSystemTools::GetLineFromStream(fin, inLine) ) { - fin.getline(buffer, bufSize); - if(fin) + m_Makefile->ExpandVariablesInString(inLine, m_EscapeQuotes, m_AtOnly); + m_Makefile->RemoveVariablesInString(inLine, m_AtOnly); + // look for special cmakedefine symbol and handle it + // is the symbol defined + if (cmdefine.find(inLine)) { - inLine = buffer; - m_Makefile->ExpandVariablesInString(inLine, m_EscapeQuotes, m_AtOnly); - m_Makefile->RemoveVariablesInString(inLine, m_AtOnly); - // look for special cmakedefine symbol and handle it - // is the symbol defined - if (cmdefine.find(inLine)) + const char *def = m_Makefile->GetDefinition(cmdefine.match(1).c_str()); + if(!cmSystemTools::IsOff(def)) { - const char *def = m_Makefile->GetDefinition(cmdefine.match(1).c_str()); - if(!cmSystemTools::IsOff(def)) - { - cmSystemTools::ReplaceString(inLine, - "#cmakedefine", "#define"); - fout << inLine << "\n"; - } - else - { - cmSystemTools::ReplaceString(inLine, - "#cmakedefine", "#undef"); - fout << "/* " << inLine << " */\n"; - } + cmSystemTools::ReplaceString(inLine, + "#cmakedefine", "#define"); + fout << inLine << "\n"; } else { - fout << inLine << "\n"; + cmSystemTools::ReplaceString(inLine, + "#cmakedefine", "#undef"); + fout << "/* " << inLine << " */\n"; } } + else + { + fout << inLine << "\n"; + } } // close the files before attempting to copy fin.close(); fout.close(); cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(), - m_OuputFile.c_str()); + m_OuputFile.c_str()); cmSystemTools::RemoveFile(tempOutputFile.c_str()); } } - + diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index d5dc5746c..7d4751421 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -145,16 +145,12 @@ void cmListFileCache::FlushCache(const char* path) } } -inline void RemoveComments(char* ptr) +inline void RemoveComments(std::string& line) { - while(*ptr) + std::string::size_type pos = line.find("#"); + if (pos != std::string::npos ) { - if(*ptr == '#') - { - *ptr = 0; - break; - } - ++ptr; + line.erase(pos); } } @@ -169,13 +165,12 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, std::vector& arguments = function.m_Arguments; name = ""; arguments = std::vector(); - const int BUFFER_SIZE = 4096; - char inbuffer[BUFFER_SIZE]; + std::string inbuffer; if(!fin) { return false; } - if(fin.getline(inbuffer, BUFFER_SIZE ) ) + if(cmSystemTools::GetLineFromStream(fin, inbuffer) ) { ++line; RemoveComments(inbuffer); @@ -185,12 +180,12 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, cmRegularExpression lastLine("^(.*)\\)[ \t\r]*$"); // check for blank line or comment - if(blankLine.find(inbuffer) ) + if(blankLine.find(inbuffer.c_str()) ) { return false; } // look for a oneline fun(arg arg2) - else if(oneLiner.find(inbuffer)) + else if(oneLiner.find(inbuffer.c_str())) { // the arguments are the second match std::string args = oneLiner.match(2); @@ -201,7 +196,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, return true; } // look for a start of a multiline with no trailing ")" fun(arg arg2 - else if(multiLine.find(inbuffer)) + else if(multiLine.find(inbuffer.c_str())) { name = multiLine.match(1); std::string args = multiLine.match(2); @@ -212,15 +207,15 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, while(!done) { // read lines until the end paren is found - if(fin.getline(inbuffer, BUFFER_SIZE ) ) + if(cmSystemTools::GetLineFromStream(fin, inbuffer) ) { ++line; RemoveComments(inbuffer); // Check for comment lines and ignore them. - if(blankLine.find(inbuffer)) + if(blankLine.find(inbuffer.c_str())) { continue; } // Is this the last line? - if(lastLine.find(inbuffer)) + if(lastLine.find(inbuffer.c_str())) { done = true; std::string gargs = lastLine.match(1); @@ -228,8 +223,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin, } else { - std::string lineB = inbuffer; - cmListFileCache::GetArguments(lineB, arguments); + cmListFileCache::GetArguments(inbuffer, arguments); } } else diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index d2fa74cbf..3ca1e5185 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -532,10 +532,9 @@ void cmLocalVisualStudio6Generator::SetBuildType(BuildType b, m_Configurations.erase(m_Configurations.begin(), m_Configurations.end()); // now add all the configurations possible char buffer[2048]; - while(fin) + std::string line; + while(cmSystemTools::GetLineFromStream(fin, line)) { - fin.getline(buffer, 2048); - std::string line = buffer; cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME_EXPORTS", exportSymbol.c_str()); cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME",libName); @@ -844,10 +843,9 @@ void cmLocalVisualStudio6Generator::WriteDSPHeader(std::ostream& fout, const cha } char buffer[2048]; - while(fin) + std::string line; + while(cmSystemTools::GetLineFromStream(fin, line)) { - fin.getline(buffer, 2048); - std::string line = buffer; const char* mfcFlag = m_Makefile->GetDefinition("CMAKE_MFC_FLAG"); if(!mfcFlag) { @@ -935,8 +933,6 @@ void cmLocalVisualStudio6Generator::WriteDSPHeader(std::ostream& fout, const cha } } - - void cmLocalVisualStudio6Generator::WriteDSPFooter(std::ostream& fout) { std::ifstream fin(m_DSPFooterTemplate.c_str()); @@ -945,10 +941,9 @@ void cmLocalVisualStudio6Generator::WriteDSPFooter(std::ostream& fout) cmSystemTools::Error("Error Reading ", m_DSPFooterTemplate.c_str()); } - char buffer[2048]; - while(fin) + std::string line; + while(cmSystemTools::GetLineFromStream(fin, line)) { - fin.getline(buffer, 2048); - fout << buffer << std::endl; + fout << line << std::endl; } } diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx index 61354b5d3..2d13cf918 100644 --- a/Source/cmMakeDepend.cxx +++ b/Source/cmMakeDepend.cxx @@ -198,10 +198,10 @@ void cmMakeDepend::DependWalk(cmDependInformation* info) } // TODO: Write real read loop (see cmSystemTools::CopyFile). - char line[255]; - for(fin.getline(line, 255); fin; fin.getline(line, 255)) + std::string line; + while( cmSystemTools::GetLineFromStream(fin, line) ) { - if(includeLine.find(line)) + if(includeLine.find(line.c_str())) { // extract the file being included std::string includeFile = includeLine.match(1); diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index a34d6db78..766124c14 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -34,11 +34,10 @@ void cmLBDepend::DependWalk(cmDependInformation* info) return; } - char line[255]; - while(!fin.eof() && !fin.fail()) + std::string line; + while(cmSystemTools::GetLineFromStream(fin, line)) { - fin.getline(line, 255); - if(!strncmp(line, "#include", 8)) + if(!strncmp(line.c_str(), "#include", 8)) { // if it is an include line then create a string class std::string currentline = line; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 7a5025601..d18550925 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1330,10 +1330,10 @@ bool RunCommandViaSystem(const char* command, return false; } bool multiLine = false; - while(fin) + std::string line; + while(cmSystemTools::GetLineFromStream(fin, line)) { - fin.getline(buffer, BUFFER_SIZE); - output += buffer; + output += line; if(multiLine) { output += "\n"; @@ -2404,6 +2404,37 @@ std::string cmSystemTools::MakeCindentifier(const char* s) return str; } +// Due to a buggy stream library on the HP and another on Mac OSX, we +// need this very carefully written version of getline. Returns true +// if any data were read before the end-of-file was reached. +bool cmSystemTools::GetLineFromStream(std::istream& is, std::string& line) +{ + const int bufferSize = 1024; + char buffer[bufferSize]; + line = ""; + bool haveData = false; + + // If no characters are read from the stream, the end of file has + // been reached. + while((is.getline(buffer, bufferSize), is.gcount() > 0)) + { + haveData = true; + line.append(buffer); + + // If newline character was read, the gcount includes the + // character, but the buffer does not. The end of line has been + // reached. + if(strlen(buffer) == static_cast(is.gcount()-1)) + { + break; + } + + // The fail bit may be set. Clear it. + is.clear(is.rdstate() & ~std::ios::failbit); + } + return haveData; +} + #if defined(_MSC_VER) && defined(_DEBUG) # include # include diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index a66d7929b..24ac737b3 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -377,6 +377,15 @@ public: * DART. */ static void EnableMSVCDebugHook(); + + /** + * Read line from file. Make sure to get everything. Due to a buggy stream + * library on the HP and another on Mac OSX, we need this very carefully + * written version of getline. Returns true if any data were read before the + * end-of-file was reached. + */ + static bool GetLineFromStream(std::istream& istr, std::string& line); + protected: // these two functions can be called from ConvertToOutputPath /** diff --git a/Source/cmUseMangledMesaCommand.cxx b/Source/cmUseMangledMesaCommand.cxx index 734865efd..57f7fb08a 100644 --- a/Source/cmUseMangledMesaCommand.cxx +++ b/Source/cmUseMangledMesaCommand.cxx @@ -98,34 +98,29 @@ CopyAndFullPathMesaHeader(const char* source, cmRegularExpression glDirLine("(gl|GL)(/|\\\\)([^<\"]+)"); // regular expression for gl GL or xmesa in a file (match(1) of above) cmRegularExpression glLine("(gl|GL|xmesa)"); - while(fin) + while(cmSystemTools::GetLineFromStream(fin,inLine)) { - fin.getline(buffer, bufSize); - if(fin) + if(includeLine.find(inLine.c_str())) { - inLine = buffer; - if(includeLine.find(inLine.c_str())) + std::string includeFile = includeLine.match(1); + if(glDirLine.find(includeFile.c_str())) { - std::string includeFile = includeLine.match(1); - if(glDirLine.find(includeFile.c_str())) - { - std::string gfile = glDirLine.match(3); - fout << "#include \"" << outdir << "/" << gfile.c_str() << "\"\n"; - } - else if(glLine.find(includeFile.c_str())) - { - fout << "#include \"" << outdir << "/" << includeLine.match(1).c_str() << "\"\n"; - } - else - { - fout << inLine << "\n"; - } + std::string gfile = glDirLine.match(3); + fout << "#include \"" << outdir << "/" << gfile.c_str() << "\"\n"; + } + else if(glLine.find(includeFile.c_str())) + { + fout << "#include \"" << outdir << "/" << includeLine.match(1).c_str() << "\"\n"; } else { fout << inLine << "\n"; } } + else + { + fout << inLine << "\n"; + } } // close the files before attempting to copy fin.close();