// 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 #include #include #include #include #include #include #include #include #include #include #include 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(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; }