1 //===-- MICmdArgValFile.cpp -------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // In-house headers:
11 #include "MICmdArgValFile.h"
12 #include "MICmdArgContext.h"
13
14 //++
15 //------------------------------------------------------------------------------------
16 // Details: CMICmdArgValFile constructor.
17 // Type: Method.
18 // Args: None.
19 // Return: None.
20 // Throws: None.
21 //--
CMICmdArgValFile()22 CMICmdArgValFile::CMICmdArgValFile() {}
23
24 //++
25 //------------------------------------------------------------------------------------
26 // Details: CMICmdArgValFile constructor.
27 // Type: Method.
28 // Args: vrArgName - (R) Argument's name to search by.
29 // vbMandatory - (R) True = Yes must be present, false = optional
30 // argument.
31 // vbHandleByCmd - (R) True = Command processes *this option, false =
32 // not handled.
33 // Return: None.
34 // Throws: None.
35 //--
CMICmdArgValFile(const CMIUtilString & vrArgName,const bool vbMandatory,const bool vbHandleByCmd)36 CMICmdArgValFile::CMICmdArgValFile(const CMIUtilString &vrArgName,
37 const bool vbMandatory,
38 const bool vbHandleByCmd)
39 : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd) {}
40
41 //++
42 //------------------------------------------------------------------------------------
43 // Details: CMICmdArgValFile destructor.
44 // Type: Overridden.
45 // Args: None.
46 // Return: None.
47 // Throws: None.
48 //--
~CMICmdArgValFile()49 CMICmdArgValFile::~CMICmdArgValFile() {}
50
51 //++
52 //------------------------------------------------------------------------------------
53 // Details: Parse the command's argument options string and try to extract the
54 // value *this
55 // argument is looking for.
56 // Type: Overridden.
57 // Args: vwArgContext - (R) The command's argument options string.
58 // Return: MIstatus::success - Functional succeeded.
59 // MIstatus::failure - Functional failed.
60 // Throws: None.
61 //--
Validate(CMICmdArgContext & vwArgContext)62 bool CMICmdArgValFile::Validate(CMICmdArgContext &vwArgContext) {
63 if (vwArgContext.IsEmpty())
64 return m_bMandatory ? MIstatus::failure : MIstatus::success;
65
66 // The GDB/MI spec suggests there is only parameter
67
68 if (vwArgContext.GetNumberArgsPresent() == 1) {
69 const CMIUtilString &rFile(vwArgContext.GetArgsLeftToParse());
70 if (IsFilePath(rFile)) {
71 m_bFound = true;
72 m_bValid = true;
73 m_argValue = rFile.Trim('"');
74 vwArgContext.RemoveArg(rFile);
75 return MIstatus::success;
76 } else
77 return MIstatus::failure;
78 }
79
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)) {
87 m_bFound = true;
88
89 if (vwArgContext.RemoveArg(rTxt)) {
90 m_bValid = true;
91 m_argValue = rTxt.Trim('"');
92 return MIstatus::success;
93 } else
94 return MIstatus::success;
95 }
96
97 // Next
98 ++it;
99 }
100
101 return MIstatus::failure;
102 }
103
104 //++
105 //------------------------------------------------------------------------------------
106 // Details: Given some text extract the file name path from it. If a space is
107 // found in
108 // path done return the path surrounded in quotes.
109 // Type: Method.
110 // Args: vrTxt - (R) The text to extract the file name path from.
111 // Return: CMIUtilString - File name and or path.
112 // Throws: None.
113 //--
114 CMIUtilString
GetFileNamePath(const CMIUtilString & vrTxt) const115 CMICmdArgValFile::GetFileNamePath(const CMIUtilString &vrTxt) const {
116 CMIUtilString fileNamePath(vrTxt);
117
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());
123
124 return fileNamePath;
125 }
126
127 //++
128 //------------------------------------------------------------------------------------
129 // Details: Examine the string and determine if it is a valid file name path.
130 // Type: Method.
131 // Args: vrFileNamePath - (R) File's name and directory path.
132 // Return: bool - True = yes valid file path, false = no.
133 // Throws: None.
134 //--
IsFilePath(const CMIUtilString & vrFileNamePath) const135 bool CMICmdArgValFile::IsFilePath(const CMIUtilString &vrFileNamePath) const {
136 if (vrFileNamePath.empty())
137 return false;
138
139 const bool bHavePosSlash = (vrFileNamePath.find('/') != std::string::npos);
140 const bool bHaveBckSlash = (vrFileNamePath.find('\\') != std::string::npos);
141
142 // Look for --someLongOption
143 size_t nPos = vrFileNamePath.find("--");
144 const bool bLong = (nPos == 0);
145 if (bLong)
146 return false;
147
148 // Look for -f type short parameters
149 nPos = vrFileNamePath.find('-');
150 const bool bShort = (nPos == 0);
151 if (bShort)
152 return false;
153
154 // Look for i1 i2 i3....
155 nPos = vrFileNamePath.find('i');
156 const bool bFoundI1 = ((nPos == 0) && (::isdigit(vrFileNamePath[1])));
157 if (bFoundI1)
158 return false;
159
160 const bool bValidChars = IsValidChars(vrFileNamePath);
161 return bValidChars || bHavePosSlash || bHaveBckSlash;
162 }
163
164 //++
165 //------------------------------------------------------------------------------------
166 // Details: Determine if the path contains valid characters for a file path.
167 // Letters can be
168 // either upper or lower case.
169 // Type: Method.
170 // Args: vrText - (R) The text data to examine.
171 // Return: bool - True = yes valid, false = one or more chars is valid.
172 // Throws: None.
173 //--
IsValidChars(const CMIUtilString & vrText) const174 bool CMICmdArgValFile::IsValidChars(const CMIUtilString &vrText) const {
175 static CMIUtilString s_strSpecialCharacters(".'\"`@#$%^&*()_+-={}[]| ");
176 const char *pPtr = vrText.c_str();
177 for (MIuint i = 0; i < vrText.length(); i++, pPtr++) {
178 const char c = *pPtr;
179 if (::isalnum((int)c) == 0) {
180 if (s_strSpecialCharacters.find(c) == CMIUtilString::npos)
181 return false;
182 }
183 }
184
185 return true;
186 }
187