0031570: Samples - add Qt samples similar to standard MFC samples
[occt.git] / samples / OCCTOverview / code / BaseSample.cxx
diff --git a/samples/OCCTOverview/code/BaseSample.cxx b/samples/OCCTOverview/code/BaseSample.cxx
new file mode 100644 (file)
index 0000000..b0aa8d2
--- /dev/null
@@ -0,0 +1,185 @@
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of the examples of the Open CASCADE Technology software library.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
+
+#include "BaseSample.h"
+
+#include <iostream>
+#include <regex>
+#include <exception>
+#include <stack>
+
+#include <AIS_ViewCube.hxx>
+#include <Message.hxx>
+#include <OSD_File.hxx>
+#include <OSD_Path.hxx>
+#include <OSD_Protection.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QDir>
+#include <Standard_WarningsRestore.hxx>
+
+const TCollection_AsciiString BaseSample::FILE_EXTENSION = "cxx";
+
+void BaseSample::Clear()
+{
+  myObject3d.Clear();
+  myObject2d.Clear();
+  myCode.Clear();
+  myResult.str("");
+}
+
+TCollection_AsciiString BaseSample::GetResult()
+{
+  TCollection_AsciiString aResult(myResult.str().c_str());
+  myResult.str("");
+  return aResult;
+}
+
+void BaseSample::AppendCube()
+{
+  Handle(AIS_ViewCube) aViewCube = new AIS_ViewCube();
+  myObject3d.Append(aViewCube);
+}
+
+void BaseSample::Process (const TCollection_AsciiString& theSampleName)
+{
+  myObject3d.Clear();
+  myObject2d.Clear();
+  myCode.Clear();
+  myIsProcessed = Standard_False;
+  try
+  {
+    ExecuteSample(theSampleName);
+    if (!myObject3d.IsEmpty())
+    {
+      Handle(AIS_ViewCube) aViewCube = new AIS_ViewCube();
+      myObject3d.Append(aViewCube);
+    }
+  }
+  catch (...)
+  {
+    TraceError(TCollection_AsciiString("Error in sample: ") + theSampleName);
+  }
+}
+
+void BaseSample::TraceError (const TCollection_AsciiString& theErrorMessage)
+{
+  Message::SendFail() << "\nERROR: " << theErrorMessage.ToCString() << std::endl;
+  myResult << "\nERROR: " << theErrorMessage << std::endl;
+}
+
+void BaseSample::FindSourceCode (const TCollection_AsciiString& theSampleName)
+{
+  TCollection_AsciiString aClassName = DynamicType()->Name();
+  char aSeparator = QDir::separator().toLatin1();
+  TCollection_AsciiString aCxxFilePach = myCodePath + aSeparator + aClassName + '.' + FILE_EXTENSION;
+  OSD_File aCxxFile(aCxxFilePach);
+  try
+  {
+    const Standard_Integer aFileBufferSize = 100 * 1024;
+    TCollection_AsciiString aReadedText(aFileBufferSize);
+    aCxxFile.Open(OSD_ReadOnly, OSD_Protection());
+    aCxxFile.Read(aReadedText, aFileBufferSize);
+    TCollection_AsciiString aRegexpTemplate = aClassName + "::" + theSampleName + "[\\n\\s]*\\([\\n\\s]*\\)[\\n\\s]*\\{";
+    Standard_Integer aOpeningBracketPosition = findEndOfPhrase (aReadedText, aRegexpTemplate);
+    Standard_Integer aClosingBracketPosition = findClosingBracket (aReadedText, aOpeningBracketPosition, '}');
+    myCode = aReadedText.SubString(aOpeningBracketPosition + 1, aClosingBracketPosition - 1);
+  }
+  catch (...)
+  {
+    TraceError(TCollection_AsciiString("Cannot open file: ") + aCxxFilePach);
+  }
+}
+
+Standard_Integer BaseSample::findEndOfPhrase (const TCollection_AsciiString& theText,
+                                              const TCollection_AsciiString& theRegexpTemplate)
+{
+  Standard_Integer aIndexOfLastFoundSymbol = -1;
+  std::string aStdText = theText.ToCString();
+  std::string aRegexpTemplate = theRegexpTemplate.ToCString();
+
+  try
+  {
+    std::regex aRegex(theRegexpTemplate.ToCString());
+
+    std::sregex_iterator aDetectIterator = std::sregex_iterator(aStdText.begin(), aStdText.end(), aRegex);
+    if (aDetectIterator != std::sregex_iterator())
+    {
+      std::smatch aMatch = *aDetectIterator;
+      std::string aFoundString = aMatch.str();
+      aIndexOfLastFoundSymbol = static_cast<Standard_Integer>(aStdText.find(aFoundString) + aFoundString.length());
+    }
+    else
+    {
+      TraceError(TCollection_AsciiString("No code found for template: ") + theRegexpTemplate);
+    }
+  }
+  catch (const std::regex_error& aRegError)
+  {
+    TraceError(TCollection_AsciiString("regex_error: ") + aRegError.what());
+  }
+  catch (const std::exception& aEx)
+  {
+    TraceError(TCollection_AsciiString("common error: ") + aEx.what());
+  }
+  catch (...)
+  {
+    TraceError("unknown error!");
+  }
+  return aIndexOfLastFoundSymbol;
+}
+
+Standard_Integer BaseSample::findClosingBracket (const TCollection_AsciiString& theText,
+                                                 const Standard_Integer theOpeningBracketIndex,
+                                                 Standard_Character theClosingBracketSymbol)
+{
+  // TODO this function not implemented at least 2 cases:
+  // - brackets in strings & chars
+  // - brackets in comments
+  Standard_Integer aClosingBracketIndex = -1;
+  Standard_Character anOpeningBracketSymbol = theText.Value(theOpeningBracketIndex);
+  TCollection_AsciiString aBracketsSet(theClosingBracketSymbol);
+  aBracketsSet += anOpeningBracketSymbol;
+  Standard_Integer aBracketDepth = 1;
+  Standard_Integer aStartFindIndex = theOpeningBracketIndex + 1;
+  //Standard_Character aStartFindChar = theText.Value(aStartFindIndex-1);
+  while (aBracketDepth)
+  {
+    aStartFindIndex = theText.FirstLocationInSet(aBracketsSet, aStartFindIndex, theText.Length());
+    if (!aStartFindIndex)
+    {
+      TraceError("No closing bracket found!");
+      break;
+    }
+    TCollection_AsciiString aRSubstr = theText.SubString(aStartFindIndex, theText.Length());
+    if (theText.Value(aStartFindIndex) == anOpeningBracketSymbol)
+      aBracketDepth++;
+    else if (theText.Value(aStartFindIndex) == theClosingBracketSymbol)
+      aBracketDepth--;
+    if (!aBracketDepth)
+    {
+      aClosingBracketIndex = aStartFindIndex;
+      break;
+    }
+    aStartFindIndex++;
+  }
+  return aClosingBracketIndex;
+}