1 //===-- MICmdArgValFile.cpp -------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "MICmdArgValFile.h"
12 #include "MICmdArgContext.h"
15 //------------------------------------------------------------------------------------
16 // Details: CMICmdArgValFile constructor.
22 CMICmdArgValFile::CMICmdArgValFile() {}
25 //------------------------------------------------------------------------------------
26 // Details: CMICmdArgValFile constructor.
28 // Args: vrArgName - (R) Argument's name to search by.
29 // vbMandatory - (R) True = Yes must be present, false = optional
31 // vbHandleByCmd - (R) True = Command processes *this option, false =
36 CMICmdArgValFile::CMICmdArgValFile(const CMIUtilString &vrArgName,
37 const bool vbMandatory,
38 const bool vbHandleByCmd)
39 : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd) {}
42 //------------------------------------------------------------------------------------
43 // Details: CMICmdArgValFile destructor.
49 CMICmdArgValFile::~CMICmdArgValFile() {}
52 //------------------------------------------------------------------------------------
53 // Details: Parse the command's argument options string and try to extract the
55 // argument is looking for.
57 // Args: vwArgContext - (R) The command's argument options string.
58 // Return: MIstatus::success - Functional succeeded.
59 // MIstatus::failure - Functional failed.
62 bool CMICmdArgValFile::Validate(CMICmdArgContext &vwArgContext) {
63 if (vwArgContext.IsEmpty())
64 return m_bMandatory ? MIstatus::failure : MIstatus::success;
66 // The GDB/MI spec suggests there is only parameter
68 if (vwArgContext.GetNumberArgsPresent() == 1) {
69 const CMIUtilString &rFile(vwArgContext.GetArgsLeftToParse());
70 if (IsFilePath(rFile)) {
73 m_argValue = rFile.Trim('"');
74 vwArgContext.RemoveArg(rFile);
75 return MIstatus::success;
77 return MIstatus::failure;
80 // In reality there are more than one option, if so the file option
81 // is the last one (don't handle that here - find the best looking one)
82 const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs());
83 CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
84 while (it != vecOptions.end()) {
85 const CMIUtilString &rTxt(*it);
86 if (IsFilePath(rTxt)) {
89 if (vwArgContext.RemoveArg(rTxt)) {
91 m_argValue = rTxt.Trim('"');
92 return MIstatus::success;
94 return MIstatus::success;
101 return MIstatus::failure;
105 //------------------------------------------------------------------------------------
106 // Details: Given some text extract the file name path from it. If a space is
108 // path done return the path surrounded in quotes.
110 // Args: vrTxt - (R) The text to extract the file name path from.
111 // Return: CMIUtilString - File name and or path.
115 CMICmdArgValFile::GetFileNamePath(const CMIUtilString &vrTxt) const {
116 CMIUtilString fileNamePath(vrTxt);
118 // Look for a space in the path
119 const char cSpace = ' ';
120 const size_t nPos = fileNamePath.find(cSpace);
121 if (nPos != std::string::npos)
122 fileNamePath = CMIUtilString::Format("\"%s\"", fileNamePath.c_str());
128 //------------------------------------------------------------------------------------
129 // Details: Examine the string and determine if it is a valid file name path.
131 // Args: vrFileNamePath - (R) File's name and directory path.
132 // Return: bool - True = yes valid file path, false = no.
135 bool CMICmdArgValFile::IsFilePath(const CMIUtilString &vrFileNamePath) const {
136 if (vrFileNamePath.empty())
139 const bool bHavePosSlash = (vrFileNamePath.find('/') != std::string::npos);
140 const bool bHaveBckSlash = (vrFileNamePath.find('\\') != std::string::npos);
142 // Look for --someLongOption
143 size_t nPos = vrFileNamePath.find("--");
144 const bool bLong = (nPos == 0);
148 // Look for -f type short parameters
149 nPos = vrFileNamePath.find('-');
150 const bool bShort = (nPos == 0);
154 // Look for i1 i2 i3....
155 nPos = vrFileNamePath.find('i');
156 const bool bFoundI1 = ((nPos == 0) && (::isdigit(vrFileNamePath[1])));
160 const bool bValidChars = IsValidChars(vrFileNamePath);
161 if (bValidChars || bHavePosSlash || bHaveBckSlash)
168 //------------------------------------------------------------------------------------
169 // Details: Determine if the path contains valid characters for a file path.
171 // either upper or lower case.
173 // Args: vrText - (R) The text data to examine.
174 // Return: bool - True = yes valid, false = one or more chars is valid.
177 bool CMICmdArgValFile::IsValidChars(const CMIUtilString &vrText) const {
178 static CMIUtilString s_strSpecialCharacters(".'\"`@#$%^&*()_+-={}[]| ");
179 const char *pPtr = vrText.c_str();
180 for (MIuint i = 0; i < vrText.length(); i++, pPtr++) {
181 const char c = *pPtr;
182 if (::isalnum((int)c) == 0) {
183 if (s_strSpecialCharacters.find(c) == CMIUtilString::npos)