void onFileChanged(FilePath sourceFilePath) { // ignore file changes while Packrat is running if (s_runningPackratAction != PACKRAT_ACTION_NONE) return; // we only care about mutations to files in the Packrat library directory // (and packrat.lock) FilePath libraryPath = projects::projectContext().directory().complete(kPackratLibPath); if (sourceFilePath.filename() == kPackratLockfile) { PACKRAT_TRACE("detected change to lockfile " << sourceFilePath); checkHashes(HASH_TYPE_LOCKFILE, HASH_STATE_OBSERVED, onLockfileUpdate); } else if (sourceFilePath.isWithin(libraryPath) && (sourceFilePath.isDirectory() || sourceFilePath.filename() == "DESCRIPTION")) { // ignore changes in the RStudio-managed manipulate and rstudio // directories and the files within them if (sourceFilePath.filename() == "manipulate" || sourceFilePath.filename() == "rstudio" || sourceFilePath.parent().filename() == "manipulate" || sourceFilePath.parent().filename() == "rstudio") { return; } PACKRAT_TRACE("detected change to library file " << sourceFilePath); checkHashes(HASH_TYPE_LIBRARY, HASH_STATE_OBSERVED, onLibraryUpdate); } }
FilePath projectFromDirectory(const FilePath& directoryPath) { // first use simple heuristic of a case sentitive match between // directory name and project file name FilePath projectFile = directoryPath.childPath( directoryPath.filename() + ".Rproj"); if (projectFile.exists()) return projectFile; // didn't satisfy it with simple check so do scan of directory std::vector<FilePath> children; Error error = directoryPath.children(&children); if (error) { LOG_ERROR(error); return FilePath(); } // build a vector of children with .rproj extensions. at the same // time allow for a case insensitive match with dir name and return that std::string projFileLower = string_utils::toLower(projectFile.filename()); std::vector<FilePath> rprojFiles; for (std::vector<FilePath>::const_iterator it = children.begin(); it != children.end(); ++it) { if (!it->isDirectory() && (it->extensionLowerCase() == ".rproj")) { if (string_utils::toLower(it->filename()) == projFileLower) return *it; else rprojFiles.push_back(*it); } } // if we found only one rproj file then return it if (rprojFiles.size() == 1) { return rprojFiles.at(0); } // more than one, take most recent else if (rprojFiles.size() > 1 ) { projectFile = rprojFiles.at(0); for (std::vector<FilePath>::const_iterator it = rprojFiles.begin(); it != rprojFiles.end(); ++it) { if (it->lastWriteTime() > projectFile.lastWriteTime()) projectFile = *it; } return projectFile; } // didn't find one else { return FilePath(); } }
FilePath Options::urlopenerPath() const { FilePath parentDir = scriptsPath(); // detect dev configuration if (parentDir.filename() == "desktop") parentDir = parentDir.complete("urlopener"); return parentDir.complete("urlopener.exe"); }
FilePath Options::rsinversePath() const { FilePath parentDir = scriptsPath(); // detect dev configuration if (parentDir.filename() == "desktop") parentDir = parentDir.complete("synctex/rsinverse"); return parentDir.complete("rsinverse.exe"); }
void enqueueChunkOutput(const std::string& docId, const std::string& chunkId, int outputType, const FilePath& path) { json::Object output; output[kChunkOutputType] = outputType; output[kChunkOutputValue] = kChunkOutputPath "/" + docId + "/" + chunkId + "/" + path.filename(); json::Object result; result[kChunkId] = chunkId; result[kChunkDocId] = docId; result[kChunkOutputPath] = output; ClientEvent event(client_events::kChunkOutput, result); module_context::enqueClientEvent(event); }
SEXP rs_pathInfo(SEXP pathSEXP) { try { // validate if (r::sexp::length(pathSEXP) != 1) { throw r::exec::RErrorException( "must pass a single file to get path info for"); } std::string path; Error error = r::sexp::extract(pathSEXP, &path); if (error) throw r::exec::RErrorException(r::endUserErrorMessage(error)); // resolve aliased path FilePath filePath = module_context::resolveAliasedPath(path); if (filePath.empty()) throw r::exec::RErrorException("invalid path: " + path); // create path info vector (use json repsesentation to force convertion // to VECSXP rather than STRSXP) json::Object pathInfo; pathInfo["path"] = filePath.absolutePath(); std::string parent = filePath.absolutePath(); FilePath parentPath = filePath.parent(); if (!parentPath.empty()) parent = parentPath.absolutePath(); pathInfo["directory"] = parent; pathInfo["name"] = filePath.filename(); pathInfo["stem"] = filePath.stem(); pathInfo["extension"] = filePath.extension(); // return it r::sexp::Protect rProtect; return r::sexp::create(pathInfo, &rProtect); } catch(r::exec::RErrorException e) { r::exec::error(e.message()); } CATCH_UNEXPECTED_EXCEPTION return R_NilValue; }
Error enqueueChunkOutput( const std::string& docPath, const std::string& docId, const std::string& chunkId, const std::string& contextId) { FilePath outputPath = chunkOutputPath(docPath, docId, chunkId, contextId); // scan the directory for output std::vector<FilePath> outputPaths; Error error = outputPath.children(&outputPaths); // non-fatal: if we can't list we'll safely return an empty array if (error) LOG_ERROR(error); // arrange by filename (use FilePath's < operator) std::sort(outputPaths.begin(), outputPaths.end()); // loop through each and build an array of the outputs json::Array outputs; BOOST_FOREACH(const FilePath& outputPath, outputPaths) { json::Object output; // ascertain chunk output type from file extension; skip if extension // unknown int outputType = chunkOutputType(outputPath); if (outputType == kChunkOutputNone) continue; // format/parse chunk output for client consumption output[kChunkOutputType] = outputType; if (outputType == kChunkOutputText) { json::Array consoleOutput; error = chunkConsoleContents(outputPath, &consoleOutput); output[kChunkOutputValue] = consoleOutput; } else if (outputType == kChunkOutputPlot || outputType == kChunkOutputHtml) { output[kChunkOutputValue] = kChunkOutputPath "/" + docId + "/" + chunkId + "/" + outputPath.filename(); } outputs.push_back(output); }
/// /// オーディオリソース生成 AudioResourcePtr AudioResource::create( FilePath& filepath ///< ファイルパス ) { // 未サポート判定 T3_ASSERT_MSG(filepath.ext() == ".wav", "%s is not support. only supported .wav", filepath.filename().c_str()); // とりあえず.wavだけサポート Wav wav; wav.load(filepath); // リソース生成 AudioResourcePtr res; res.reset(T3_SYS_NEW AudioResource); res->setupBuffer(wav); res->resourceName(filepath.filename().c_str()); res->createHandle(); return res; }
bool isHiddenFile(const FilePath& filePath) { std::string filename = filePath.filename() ; return (!filename.empty() && (filename[0] == '.')) ; }
void runLatexCompiler(const rnw_concordance::Concordances& concordances = rnw_concordance::Concordances()) { // configure pdflatex options pdflatex::PdfLatexOptions options; options.fileLineError = false; options.syncTex = true; options.shellEscape = userSettings().enableLaTeXShellEscape(); // get back-end version info core::system::ProcessResult result; Error error = core::system::runProgram( string_utils::utf8ToSystem(texProgramPath_.absolutePath()), core::shell_utils::ShellArgs() << "--version", "", core::system::ProcessOptions(), &result); if (error) LOG_ERROR(error); else if (result.exitStatus != EXIT_SUCCESS) LOG_ERROR_MESSAGE("Error probing for latex version: "+ result.stdErr); else options.versionInfo = result.stdOut; // compute tex file path FilePath texFilePath = targetFilePath_.parent().complete( targetFilePath_.stem() + ".tex"); // remove log files if they exist (avoids confusion created by parsing // old log files for errors) removeExistingLogs(texFilePath); // setup cleanup context if clean was specified if (userSettings().cleanTexi2DviOutput()) auxillaryFileCleanupContext_.init(texFilePath); // run latex compile // try to use texi2dvi if we can if (userSettings().useTexi2Dvi() && tex::texi2dvi::isAvailable()) { enqueOutputEvent("Running texi2dvi on " + texFilePath.filename() + "..."); Error error = tex::texi2dvi::texToPdf( texProgramPath_, texFilePath, options, boost::bind( &AsyncPdfCompiler::onLatexCompileCompleted, AsyncPdfCompiler::shared_from_this(), _1, texFilePath, concordances)); if (error) terminateWithError("Unable to compile pdf: " + error.summary()); } // call pdflatex directly (but still try to run bibtex as necessary) else { // this is our "simulated" texi2dvi -- this was originally // coded as a sequence of sync calls to pdflatex, bibtex, and // makeindex. re-coding it as async is going to be a bit // involved so considering that this is not the default // codepath we'll leave it sync for now (and then just call // the (typically) async callback function onLatexCompileCompleted // directly after the function returns enqueOutputEvent("Running " + texProgramPath_.filename() + " on " + texFilePath.filename() + "..."); Error error = tex::pdflatex::texToPdf(texProgramPath_, texFilePath, options, &result); if (error) { terminateWithError("Unable to compile pdf: " + error.summary()); } else { onLatexCompileCompleted(result.exitStatus, texFilePath, concordances); } } }