Browse Source

Implement GetLineFromStream that actually works and use it instead of getline

Andy Cedilnik 22 years ago
parent
commit
a9875aa62f

+ 6 - 6
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;

+ 20 - 27
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());
     }
 }
 
-  
+

+ 13 - 19
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<cmListFileArgument>& arguments = function.m_Arguments;
   name = "";
   arguments = std::vector<cmListFileArgument>();
-  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

+ 7 - 12
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;
     }
 }

+ 3 - 3
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);

+ 3 - 4
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;

+ 34 - 3
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<size_t>(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 <crtdbg.h>
 # include <stdio.h>

+ 9 - 0
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
   /**

+ 14 - 19
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();