|
1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "testframeparse.h" |
|
17 |
|
18 |
|
19 _LIT(KTestErrorUnknown, "No more details available"); |
|
20 _LIT(KInvalidNumberOfArguments, "[%4d] Invalid number of arguments, actual: %d, expected: %d"); |
|
21 _LIT(KGeneralParseError, "[%4d] Error in command: %S, section: %S"); |
|
22 _LIT(KNotParsedError, "[%4d] Command not recognised: %S, in section: %S"); |
|
23 |
|
24 CBaseCommandParser::~CBaseCommandParser() |
|
25 { |
|
26 delete iArgumentList; |
|
27 delete iSupportedCommands; |
|
28 delete iCurrentCommand; |
|
29 delete iLastError; |
|
30 } |
|
31 |
|
32 void CBaseCommandParser::ConstructL() |
|
33 { |
|
34 iArgumentList = new (ELeave) CDesCArrayFlat(3); |
|
35 iSupportedCommands = new (ELeave) CDesCArrayFlat(1); |
|
36 iLastError = HBufC::NewL(0); |
|
37 iCurrentCommand = 0; |
|
38 } |
|
39 |
|
40 // |
|
41 // Extract the command and any argments from the given string |
|
42 void CBaseCommandParser::ParseL(const TDesC& aCommand, TTestDebugInfo aDebugInfo) |
|
43 { |
|
44 iDebugInfo = aDebugInfo; |
|
45 iArgumentList->Reset(); |
|
46 |
|
47 delete iCurrentCommand; |
|
48 iCurrentCommand = 0; |
|
49 TInt commandIter = 0; |
|
50 TInt commandStart = 0; |
|
51 TBool inQuotes = EFalse; |
|
52 while (commandIter <= aCommand.Length()) |
|
53 { |
|
54 TBool commandFound = EFalse; |
|
55 if (commandIter < aCommand.Length()) |
|
56 { |
|
57 if (aCommand[commandIter] == '"') |
|
58 { |
|
59 // |
|
60 // We assume that quotes only occur at the beginning and end |
|
61 // of arguments. Hence, if we've just found a new quote, we should |
|
62 // not make it part of the argument. |
|
63 if (!inQuotes) |
|
64 { |
|
65 inQuotes = ETrue; |
|
66 commandStart++; |
|
67 } |
|
68 else |
|
69 { |
|
70 // |
|
71 // Assume we've got to the end of the argument and skip the |
|
72 // following space. |
|
73 commandFound = ETrue; |
|
74 commandIter++; |
|
75 } |
|
76 } |
|
77 else |
|
78 if ((aCommand[commandIter] == ' ') && (!inQuotes)) |
|
79 { |
|
80 commandFound = ETrue; |
|
81 } |
|
82 } |
|
83 else |
|
84 { |
|
85 commandFound = ETrue; |
|
86 } |
|
87 |
|
88 if (commandFound) |
|
89 { |
|
90 if (commandIter > commandStart) |
|
91 |
|
92 // |
|
93 // Command or argument found |
|
94 { |
|
95 TInt commandLength = commandIter - commandStart; |
|
96 |
|
97 // |
|
98 // If the argument ended in quotes, modify the length to exclude them. |
|
99 if (inQuotes) |
|
100 { |
|
101 inQuotes = EFalse; |
|
102 commandLength--; |
|
103 } |
|
104 |
|
105 if (iCurrentCommand == NULL) |
|
106 { |
|
107 iCurrentCommand = HBufC::NewL(commandLength); |
|
108 (*iCurrentCommand) = aCommand.Mid(commandStart, commandLength); |
|
109 } |
|
110 else |
|
111 { |
|
112 // |
|
113 // This is a command argument |
|
114 iArgumentList->AppendL(aCommand.Mid(commandStart, commandLength)); |
|
115 } |
|
116 |
|
117 // |
|
118 // Set the start of the next argument. |
|
119 commandStart = commandIter + 1; |
|
120 } |
|
121 } |
|
122 commandIter++; |
|
123 } |
|
124 ProcessL(); |
|
125 } |
|
126 |
|
127 TBool CBaseCommandParser::CanParse(const TDesC& aCommand) const |
|
128 { |
|
129 TBool canParse = EFalse; |
|
130 |
|
131 TInt commandCounter = iSupportedCommands->Count(); |
|
132 while ((commandCounter-- > 0) && (!canParse)) |
|
133 { |
|
134 // |
|
135 // Scan through each of the supported commands |
|
136 TInt commandSize = (*iSupportedCommands)[commandCounter].Length(); |
|
137 if (commandSize <= aCommand.Length()) |
|
138 { |
|
139 // |
|
140 // The given command must be at least as long as the one it is being compared to |
|
141 if (aCommand.Left(commandSize) == (*iSupportedCommands)[commandCounter]) |
|
142 { |
|
143 // |
|
144 // Check that there are no more characters or that the next one is a whitespace |
|
145 if (commandSize < aCommand.Length()) |
|
146 { |
|
147 if (aCommand[commandSize] == ' ') |
|
148 { |
|
149 canParse = ETrue; |
|
150 } |
|
151 } |
|
152 else |
|
153 { |
|
154 canParse = ETrue; |
|
155 } |
|
156 } |
|
157 } |
|
158 } |
|
159 return canParse; |
|
160 } |
|
161 |
|
162 void CBaseCommandParser::AddCommandL(const TDesC& aCommand) |
|
163 { |
|
164 iSupportedCommands->AppendL(aCommand); |
|
165 } |
|
166 |
|
167 TDesC& CBaseCommandParser::ErrorL() |
|
168 { |
|
169 if (iLastError->Length() == 0) |
|
170 { |
|
171 delete iLastError; |
|
172 iLastError = 0; |
|
173 iLastError = HBufC::NewL(KTestErrorUnknown().Length()); |
|
174 (*iLastError) = KTestErrorUnknown; |
|
175 } |
|
176 return *iLastError; |
|
177 } |
|
178 |
|
179 void CBaseCommandParser::CheckNumberOfArgumentsL(TInt aNumberOfArguments) |
|
180 { |
|
181 if (iArgumentList->Count() != aNumberOfArguments) |
|
182 { |
|
183 TBuf<128> errorString; |
|
184 errorString.Format(KInvalidNumberOfArguments, iDebugInfo.LineNumber(), iArgumentList->Count(), aNumberOfArguments); |
|
185 SetErrorL(errorString); |
|
186 User::Leave(KErrArgument); |
|
187 } |
|
188 } |
|
189 |
|
190 void CBaseCommandParser::SetErrorL(const TDesC& aError) |
|
191 { |
|
192 delete iLastError; |
|
193 iLastError = 0; |
|
194 iLastError = HBufC::NewL(aError.Length()); |
|
195 (*iLastError) = aError; |
|
196 } |
|
197 |
|
198 |
|
199 |
|
200 // |
|
201 // CBaseSectionParser |
|
202 void CBaseSectionParser::SetSectionL(const TDesC& aSectionName) |
|
203 { |
|
204 delete iSection; |
|
205 iSection = 0; |
|
206 iSection = iScript.GetSectionL(aSectionName); |
|
207 } |
|
208 |
|
209 void CBaseSectionParser::ParseL() |
|
210 { |
|
211 // |
|
212 // Go through each command in the section and parse it |
|
213 TBool parsed = EFalse; |
|
214 TBuf<512> currentCommand; |
|
215 TBool commandNotRecognised = EFalse; |
|
216 TInt lineNumber = 0; |
|
217 |
|
218 while (((lineNumber = iSection->GetCurrentCommand(currentCommand)) > 0) && (!commandNotRecognised)) |
|
219 { |
|
220 TInt commandParserIndex = iCommandParsers->Count(); |
|
221 parsed = EFalse; |
|
222 while (commandParserIndex--) |
|
223 { |
|
224 // |
|
225 // Look for a command parser that can parse the current command |
|
226 if ((*iCommandParsers)[commandParserIndex]->CanParse(currentCommand)) |
|
227 { |
|
228 TTestDebugInfo debugInfo(iScript, iSection->SectionPosition(), iSection->CurrentCommandPosition(), lineNumber); |
|
229 TRAPD(err, (*iCommandParsers)[commandParserIndex]->ParseL(currentCommand, debugInfo)); |
|
230 if (err != KErrNone) |
|
231 { |
|
232 TBuf<128> errorString; |
|
233 errorString.Format(KGeneralParseError, lineNumber, ¤tCommand, &(iSection->SectionName())); |
|
234 LogComment(errorString); |
|
235 LogComment((*iCommandParsers)[commandParserIndex]->ErrorL()); |
|
236 User::Leave(err); |
|
237 } |
|
238 parsed = ETrue; |
|
239 } |
|
240 } |
|
241 if (!parsed) |
|
242 { |
|
243 commandNotRecognised = ETrue; |
|
244 TBuf<256> aError; |
|
245 aError.Format(KNotParsedError, lineNumber, ¤tCommand, &(iSection->SectionName())); |
|
246 LogComment(aError); |
|
247 User::Leave(KErrNotFound); |
|
248 } |
|
249 iSection->NextCommand(); |
|
250 } |
|
251 } |
|
252 |
|
253 CBaseSectionParser::~CBaseSectionParser() |
|
254 { |
|
255 iCommandParsers->ResetAndDestroy(); |
|
256 delete iCommandParsers; |
|
257 delete iSection; |
|
258 } |
|
259 |
|
260 void CBaseSectionParser::AddCommandParserL(CBaseCommandParser* aParser) |
|
261 { |
|
262 TRAPD(err, iCommandParsers->AppendL(aParser)); |
|
263 |
|
264 // |
|
265 // If the parser can't be appended then delete it. |
|
266 // Then leave with the original error. |
|
267 if (err != KErrNone) |
|
268 { |
|
269 delete aParser; |
|
270 User::Leave(err); |
|
271 } |
|
272 } |
|
273 |
|
274 void CBaseSectionParser::ConstructL(const TDesC& aSectionName) |
|
275 { |
|
276 iCommandParsers = new (ELeave) CArrayPtrFlat<CBaseCommandParser>(5); |
|
277 SetSectionL(aSectionName); |
|
278 } |
|
279 |