1254721Semaste//===-- OptionValueFileSpec.cpp ---------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#include "lldb/Interpreter/OptionValueFileSpec.h" 10254721Semaste 11254721Semaste#include "lldb/DataFormatters/FormatManager.h" 12314564Sdim#include "lldb/Host/FileSystem.h" 13254721Semaste#include "lldb/Interpreter/CommandCompletions.h" 14314564Sdim#include "lldb/Interpreter/CommandInterpreter.h" 15341825Sdim#include "lldb/Utility/Args.h" 16344779Sdim#include "lldb/Utility/State.h" 17254721Semaste 18254721Semasteusing namespace lldb; 19254721Semasteusing namespace lldb_private; 20254721Semaste 21314564SdimOptionValueFileSpec::OptionValueFileSpec(bool resolve) 22314564Sdim : OptionValue(), m_current_value(), m_default_value(), m_data_sp(), 23314564Sdim m_data_mod_time(), 24314564Sdim m_completion_mask(CommandCompletions::eDiskFileCompletion), 25314564Sdim m_resolve(resolve) {} 26254721Semaste 27314564SdimOptionValueFileSpec::OptionValueFileSpec(const FileSpec &value, bool resolve) 28314564Sdim : OptionValue(), m_current_value(value), m_default_value(value), 29314564Sdim m_data_sp(), m_data_mod_time(), 30314564Sdim m_completion_mask(CommandCompletions::eDiskFileCompletion), 31314564Sdim m_resolve(resolve) {} 32254721Semaste 33314564SdimOptionValueFileSpec::OptionValueFileSpec(const FileSpec ¤t_value, 34314564Sdim const FileSpec &default_value, 35314564Sdim bool resolve) 36314564Sdim : OptionValue(), m_current_value(current_value), 37314564Sdim m_default_value(default_value), m_data_sp(), m_data_mod_time(), 38314564Sdim m_completion_mask(CommandCompletions::eDiskFileCompletion), 39314564Sdim m_resolve(resolve) {} 40254721Semaste 41314564Sdimvoid OptionValueFileSpec::DumpValue(const ExecutionContext *exe_ctx, 42314564Sdim Stream &strm, uint32_t dump_mask) { 43314564Sdim if (dump_mask & eDumpOptionType) 44314564Sdim strm.Printf("(%s)", GetTypeAsCString()); 45314564Sdim if (dump_mask & eDumpOptionValue) { 46254721Semaste if (dump_mask & eDumpOptionType) 47314564Sdim strm.PutCString(" = "); 48254721Semaste 49314564Sdim if (m_current_value) { 50314564Sdim strm << '"' << m_current_value.GetPath().c_str() << '"'; 51254721Semaste } 52314564Sdim } 53254721Semaste} 54254721Semaste 55321369SdimStatus OptionValueFileSpec::SetValueFromString(llvm::StringRef value, 56321369Sdim VarSetOperationType op) { 57321369Sdim Status error; 58314564Sdim switch (op) { 59314564Sdim case eVarSetOperationClear: 60314564Sdim Clear(); 61314564Sdim NotifyValueChanged(); 62314564Sdim break; 63314564Sdim 64314564Sdim case eVarSetOperationReplace: 65314564Sdim case eVarSetOperationAssign: 66314564Sdim if (value.size() > 0) { 67314564Sdim // The setting value may have whitespace, double-quotes, or single-quotes 68341825Sdim // around the file path to indicate that internal spaces are not word 69341825Sdim // breaks. Strip off any ws & quotes from the start and end of the file 70341825Sdim // path - we aren't doing any word // breaking here so the quoting is 71341825Sdim // unnecessary. NB this will cause a problem if someone tries to specify 72314564Sdim // a file path that legitimately begins or ends with a " or ' character, 73314564Sdim // or whitespace. 74314564Sdim value = value.trim("\"' \t"); 75314564Sdim m_value_was_set = true; 76344779Sdim m_current_value.SetFile(value.str(), FileSpec::Style::native); 77344779Sdim if (m_resolve) 78344779Sdim FileSystem::Instance().Resolve(m_current_value); 79314564Sdim m_data_sp.reset(); 80314564Sdim m_data_mod_time = llvm::sys::TimePoint<>(); 81314564Sdim NotifyValueChanged(); 82314564Sdim } else { 83314564Sdim error.SetErrorString("invalid value string"); 84254721Semaste } 85314564Sdim break; 86314564Sdim 87314564Sdim case eVarSetOperationInsertBefore: 88314564Sdim case eVarSetOperationInsertAfter: 89314564Sdim case eVarSetOperationRemove: 90314564Sdim case eVarSetOperationAppend: 91314564Sdim case eVarSetOperationInvalid: 92314564Sdim error = OptionValue::SetValueFromString(value, op); 93314564Sdim break; 94314564Sdim } 95314564Sdim return error; 96254721Semaste} 97254721Semaste 98314564Sdimlldb::OptionValueSP OptionValueFileSpec::DeepCopy() const { 99314564Sdim return OptionValueSP(new OptionValueFileSpec(*this)); 100254721Semaste} 101254721Semaste 102360784Sdimvoid OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter, 103360784Sdim CompletionRequest &request) { 104314564Sdim CommandCompletions::InvokeCommonCompletionCallbacks( 105341825Sdim interpreter, m_completion_mask, request, nullptr); 106254721Semaste} 107254721Semaste 108327952Sdimconst lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() { 109314564Sdim if (m_current_value) { 110344779Sdim const auto file_mod_time = FileSystem::Instance().GetModificationTime(m_current_value); 111314564Sdim if (m_data_sp && m_data_mod_time == file_mod_time) 112314564Sdim return m_data_sp; 113344779Sdim m_data_sp = 114344779Sdim FileSystem::Instance().CreateDataBuffer(m_current_value.GetPath()); 115314564Sdim m_data_mod_time = file_mod_time; 116314564Sdim } 117314564Sdim return m_data_sp; 118254721Semaste} 119