| /* | |
| Copyright 2019 Alain Dargelas | |
| Licensed under the Apache License, Version 2.0 (the "License"); | |
| you may not use this file except in compliance with the License. | |
| You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| */ | |
| /* | |
| * File: PythonAPICache.cpp | |
| * Author: alain | |
| * | |
| * Created on May 28, 2017, 10:49 PM | |
| */ | |
| #include "CommandLine/CommandLineParser.h" | |
| #include "ErrorReporting/ErrorContainer.h" | |
| #include "SourceCompile/SymbolTable.h" | |
| #include "SourceCompile/CompilationUnit.h" | |
| #include "SourceCompile/PreprocessFile.h" | |
| #include "SourceCompile/CompileSourceFile.h" | |
| #include "SourceCompile/Compiler.h" | |
| #include "SourceCompile/ParseFile.h" | |
| #include "Utils/StringUtils.h" | |
| #include "Utils/FileUtils.h" | |
| #include "Cache/Cache.h" | |
| #include "flatbuffers/util.h" | |
| #include <cstdio> | |
| #include <ctime> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include "antlr4-runtime.h" | |
| using namespace antlr4; | |
| #include "API/PythonAPI.h" | |
| #include "Cache/PythonAPICache.h" | |
| #include "SourceCompile/PythonListen.h" | |
| using namespace SURELOG; | |
| static std::string FlbSchemaVersion = "1.0"; | |
| PythonAPICache::PythonAPICache(PythonListen* listener) : m_listener(listener) {} | |
| PythonAPICache::PythonAPICache(const PythonAPICache& orig) {} | |
| PythonAPICache::~PythonAPICache() {} | |
| std::string PythonAPICache::getCacheFileName_(std::string svFileName) { | |
| SymbolId cacheDirId = | |
| m_listener->getCompileSourceFile()->getCommandLineParser()->getCacheDir(); | |
| std::string cacheDirName = m_listener->getParseFile()->getSymbol(cacheDirId); | |
| if (svFileName == "") | |
| svFileName = m_listener->getParseFile()->getFileName(LINE1); | |
| svFileName = StringUtils::getRootFileName(svFileName); | |
| Library* lib = m_listener->getCompileSourceFile()->getLibrary(); | |
| std::string libName = lib->getName() + "/"; | |
| std::string cacheFileName = cacheDirName + libName + svFileName + ".slpy"; | |
| return cacheFileName; | |
| } | |
| bool PythonAPICache::restore_(std::string cacheFileName) { | |
| uint8_t* buffer_pointer = openFlatBuffers(cacheFileName); | |
| if (buffer_pointer == NULL) return false; | |
| const PYTHONAPICACHE::PythonAPICache* ppcache = | |
| PYTHONAPICACHE::GetPythonAPICache(buffer_pointer); | |
| SymbolTable canonicalSymbols; | |
| restoreErrors(ppcache->m_errors(), ppcache->m_symbols(), canonicalSymbols, | |
| m_listener->getCompileSourceFile()->getErrorContainer(), | |
| m_listener->getCompileSourceFile()->getSymbolTable()); | |
| delete[] buffer_pointer; | |
| return true; | |
| } | |
| bool PythonAPICache::checkCacheIsValid_(std::string cacheFileName) { | |
| uint8_t* buffer_pointer = openFlatBuffers(cacheFileName); | |
| if (buffer_pointer == NULL) return false; | |
| if (!PYTHONAPICACHE::PythonAPICacheBufferHasIdentifier(buffer_pointer)) { | |
| delete[] buffer_pointer; | |
| return false; | |
| } | |
| const PYTHONAPICACHE::PythonAPICache* ppcache = | |
| PYTHONAPICACHE::GetPythonAPICache(buffer_pointer); | |
| auto header = ppcache->m_header(); | |
| auto scriptFile = ppcache->m_python_script_file()->c_str(); | |
| if (scriptFile) { | |
| time_t ct = get_mtime(cacheFileName.c_str()); | |
| time_t ft = get_mtime(scriptFile); | |
| if (ft == -1) { | |
| delete[] buffer_pointer; | |
| return false; | |
| } | |
| if (ct == -1) { | |
| delete[] buffer_pointer; | |
| return false; | |
| } | |
| if (ct < ft) { | |
| delete[] buffer_pointer; | |
| return false; | |
| } | |
| } | |
| if (!checkIfCacheIsValid(header, FlbSchemaVersion, cacheFileName)) { | |
| delete[] buffer_pointer; | |
| return false; | |
| } | |
| delete[] buffer_pointer; | |
| return true; | |
| } | |
| bool PythonAPICache::isValid() { | |
| std::string cacheFileName = getCacheFileName_(); | |
| return checkCacheIsValid_(cacheFileName); | |
| } | |
| bool PythonAPICache::restore() { | |
| bool cacheAllowed = m_listener->getCompileSourceFile() | |
| ->getCommandLineParser() | |
| ->cacheAllowed(); | |
| if (!cacheAllowed) return false; | |
| std::string cacheFileName = getCacheFileName_(); | |
| if (!checkCacheIsValid_(cacheFileName)) { | |
| return false; | |
| } | |
| return restore_(cacheFileName); | |
| } | |
| bool PythonAPICache::save() { | |
| bool cacheAllowed = m_listener->getCompileSourceFile() | |
| ->getCommandLineParser() | |
| ->cacheAllowed(); | |
| if (!cacheAllowed) return false; | |
| std::string svFileName = m_listener->getParseFile()->getPpFileName(); | |
| std::string origFileName = svFileName; | |
| std::string cacheFileName = getCacheFileName_(); | |
| flatbuffers::FlatBufferBuilder builder(1024); | |
| /* Create header section */ | |
| auto header = createHeader(builder, FlbSchemaVersion, origFileName); | |
| std::string pythonScriptFile = PythonAPI::getListenerScript(); | |
| auto scriptFile = builder.CreateString(pythonScriptFile); | |
| /* Cache the errors and canonical symbols */ | |
| ErrorContainer* errorContainer = | |
| m_listener->getCompileSourceFile()->getErrorContainer(); | |
| SymbolId subjectFileId = m_listener->getParseFile()->getFileId(LINE1); | |
| SymbolTable canonicalSymbols; | |
| auto errorSymbolPair = cacheErrors( | |
| builder, canonicalSymbols, errorContainer, | |
| m_listener->getCompileSourceFile()->getSymbolTable(), subjectFileId); | |
| /* Create Flatbuffers */ | |
| auto ppcache = PYTHONAPICACHE::CreatePythonAPICache( | |
| builder, header, scriptFile, errorSymbolPair.first, | |
| errorSymbolPair.second); | |
| FinishPythonAPICacheBuffer(builder, ppcache); | |
| /* Save Flatbuffer */ | |
| bool status = saveFlatbuffers(builder, cacheFileName); | |
| return status; | |
| } |