|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Mifconv argument manager class. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "mifconv.h" |
|
20 #include "mifconv_argumentmanager.h" |
|
21 #include "mifconv_exception.h" |
|
22 #include "mifconv_util.h" |
|
23 |
|
24 // Static singleton initialization |
|
25 MifConvArgumentManager* MifConvArgumentManager::iInstance = 0; |
|
26 |
|
27 /** |
|
28 * Returns pointer to the singleton object |
|
29 */ |
|
30 MifConvArgumentManager* MifConvArgumentManager::Instance() |
|
31 { |
|
32 if( iInstance == 0 ) |
|
33 { |
|
34 iInstance = new MifConvArgumentManager(); |
|
35 } |
|
36 return iInstance; |
|
37 } |
|
38 |
|
39 /** |
|
40 * Free the allocated memory |
|
41 */ |
|
42 void MifConvArgumentManager::Reset() |
|
43 { |
|
44 delete iInstance; |
|
45 iInstance = 0; |
|
46 } |
|
47 |
|
48 /** |
|
49 * |
|
50 */ |
|
51 inline void MifConvArgumentManager::THROW_USAGE_EXCEPTION() const |
|
52 { |
|
53 MifConvString usageStr; |
|
54 SetUsageString(usageStr); |
|
55 throw MifConvException(usageStr, MifConvString(__FILE__), __LINE__); |
|
56 } |
|
57 |
|
58 inline void MifConvArgumentManager::THROW_ERROR( const MifConvString& errorMsg, const MifConvString& file, int line ) const |
|
59 { |
|
60 throw MifConvException( MifConvString("ERROR: " + errorMsg + "\nType mifconv -? for help\n"), file, line); |
|
61 } |
|
62 |
|
63 /** |
|
64 * |
|
65 */ |
|
66 MifConvArgumentManager::MifConvArgumentManager() |
|
67 : |
|
68 iEpocRoot(DEFAULT_EPOCROOT) |
|
69 { |
|
70 GetMifEnv(); |
|
71 } |
|
72 |
|
73 /** |
|
74 * |
|
75 */ |
|
76 MifConvArgumentManager::~MifConvArgumentManager() |
|
77 {} |
|
78 |
|
79 /** |
|
80 * This function checks if the given argument is boolean type of argument. |
|
81 * Boolean type arguments are listed in a <code>MifConvBooleanArguments</code> table |
|
82 * and this function checks if the given string matches any of those. Returns the length |
|
83 * of the argument name if found, zero otherwise. |
|
84 */ |
|
85 size_t MifConvArgumentManager::IsBooleanArgument( const MifConvString& argName ) const |
|
86 { |
|
87 if( IsArgument(argName) ) |
|
88 { |
|
89 try { |
|
90 int tblSize = sizeof(MifConvBooleanArguments) / sizeof(MifConvString); |
|
91 for( int i = 0; i < tblSize; ++i ) |
|
92 { |
|
93 size_t tmpLen = MifConvBooleanArguments[i].length(); |
|
94 if( argName.length() > tmpLen ) |
|
95 { |
|
96 if( MifConvUtil::CompareIgnoreCase(MifConvString(argName.begin()+1, argName.begin() + 1 + tmpLen), MifConvBooleanArguments[i]) == 0 ) |
|
97 { |
|
98 return tmpLen; |
|
99 } |
|
100 } |
|
101 } |
|
102 } |
|
103 catch(...) |
|
104 { |
|
105 THROW_USAGE_EXCEPTION(); |
|
106 } |
|
107 } |
|
108 return 0; |
|
109 } |
|
110 |
|
111 /** |
|
112 * This function checks if the given argument is a help argument. |
|
113 * Help arguments are listed in a <code>MifConvHelpArguments</code> table |
|
114 * and this function checks if the given string matches any of those. Returns the length |
|
115 * of the argument name if found, zero otherwise. |
|
116 */ |
|
117 size_t MifConvArgumentManager::IsHelpArgument( const MifConvString& argName ) const |
|
118 { |
|
119 if( IsArgument(argName) ) |
|
120 { |
|
121 try { |
|
122 int tblSize = sizeof(MifConvHelpArguments) / sizeof(MifConvString); |
|
123 for( int i = 0; i < tblSize; ++i ) |
|
124 { |
|
125 size_t tmpLen = MifConvHelpArguments[i].length(); |
|
126 |
|
127 // Following check separates -H from -Hheadername.mbg parameter: |
|
128 if( argName.length() == tmpLen+1 ) |
|
129 { |
|
130 if( MifConvUtil::CompareIgnoreCase(MifConvString(argName.begin()+1, argName.begin() + 1 + tmpLen), MifConvHelpArguments[i]) == 0 ) |
|
131 { |
|
132 return tmpLen; |
|
133 } |
|
134 } |
|
135 } |
|
136 } |
|
137 catch(...) |
|
138 { |
|
139 THROW_USAGE_EXCEPTION(); |
|
140 } |
|
141 } |
|
142 return 0; |
|
143 } |
|
144 |
|
145 /** |
|
146 * This function checks if the given argument is string type of argument. |
|
147 * String type arguments are listed in a <code>MifConvStringArguments</code> table |
|
148 * and this function checks if the given string matches any of those. Returns the length |
|
149 * of the argument name if found, zero otherwise. |
|
150 */ |
|
151 size_t MifConvArgumentManager::IsStringArgument( const MifConvString& argName ) const |
|
152 { |
|
153 if( IsArgument(argName) ) |
|
154 { |
|
155 try { |
|
156 int tblSize = sizeof(MifConvStringArguments) / sizeof(MifConvString); |
|
157 for( int i = 0; i < tblSize; ++i ) |
|
158 { |
|
159 size_t tmpLen = MifConvStringArguments[i].length(); |
|
160 if( argName.length() > tmpLen ) |
|
161 { |
|
162 if( MifConvUtil::CompareIgnoreCase(MifConvString(argName.begin()+1, argName.begin()+1+tmpLen), MifConvStringArguments[i]) == 0 ) |
|
163 { |
|
164 return tmpLen; |
|
165 } |
|
166 } |
|
167 } |
|
168 } |
|
169 catch(...) |
|
170 { |
|
171 THROW_USAGE_EXCEPTION(); |
|
172 } |
|
173 } |
|
174 return 0; |
|
175 } |
|
176 |
|
177 /** |
|
178 * This function checks if the given argument is string list type of argument. |
|
179 * String list type arguments are listed in a <code>MifConvStringListArguments</code> table |
|
180 * and this function checks if the given string matches any of those. Returns the length |
|
181 * of the argument name if found, zero otherwise. |
|
182 */ |
|
183 size_t MifConvArgumentManager::IsStringListArgument( const MifConvString& argName ) const |
|
184 { |
|
185 if( IsArgument(argName) ) |
|
186 { |
|
187 try { |
|
188 int tblSize = sizeof(MifConvStringListArguments) / sizeof(MifConvString); |
|
189 for( int i = 0; i < tblSize; ++i ) |
|
190 { |
|
191 size_t tmpLen = MifConvStringListArguments[i].length(); |
|
192 if( argName.length() > tmpLen ) |
|
193 { |
|
194 if( MifConvUtil::CompareIgnoreCase(MifConvString(argName.begin()+1, argName.begin()+1+tmpLen), MifConvStringListArguments[i]) == 0 ) |
|
195 { |
|
196 return tmpLen; |
|
197 } |
|
198 } |
|
199 } |
|
200 } |
|
201 catch(...) |
|
202 { |
|
203 THROW_USAGE_EXCEPTION(); |
|
204 } |
|
205 } |
|
206 return 0; |
|
207 } |
|
208 |
|
209 /** |
|
210 * |
|
211 */ |
|
212 bool MifConvArgumentManager::IsDepthArgument( const MifConvString& argName ) const |
|
213 { |
|
214 if( IsArgument(argName) ) |
|
215 { |
|
216 try { |
|
217 int tblSize = sizeof(MifConvDepthArguments) / sizeof(MifConvString); |
|
218 for( int i = 0; i < tblSize; ++i ) |
|
219 { |
|
220 size_t tmpLen = MifConvDepthArguments[i].length(); |
|
221 if( argName.length() > tmpLen ) |
|
222 { |
|
223 MifConvString trimmedArgument(argName.begin()+1, argName.begin() + 1 + tmpLen); |
|
224 if( MifConvUtil::CompareIgnoreCase(trimmedArgument, MifConvDepthArguments[i]) == 0 ) |
|
225 { |
|
226 return true; |
|
227 } |
|
228 } |
|
229 } |
|
230 } |
|
231 catch(...) |
|
232 { |
|
233 THROW_USAGE_EXCEPTION(); |
|
234 } |
|
235 } |
|
236 return false; |
|
237 } |
|
238 |
|
239 /** |
|
240 * |
|
241 */ |
|
242 bool MifConvArgumentManager::IsAnimatedFlag( const MifConvString& argName ) const |
|
243 { |
|
244 return IsArgument( argName ) && argName.length() > MifConvAnimatedIconArg.length() && |
|
245 MifConvUtil::CompareIgnoreCase(MifConvString(argName.begin()+1, argName.end() ), MifConvAnimatedIconArg ) == 0; |
|
246 } |
|
247 |
|
248 /** |
|
249 * |
|
250 */ |
|
251 void MifConvArgumentManager::SetTargetFile( const MifConvString& arg ) |
|
252 { |
|
253 iTargetFile = arg; |
|
254 } |
|
255 |
|
256 /** |
|
257 * |
|
258 */ |
|
259 const MifConvString& MifConvArgumentManager::TargetFile() const |
|
260 { |
|
261 return iTargetFile; |
|
262 } |
|
263 |
|
264 /** |
|
265 * |
|
266 */ |
|
267 IconDisplayMode MifConvArgumentManager::ConvertToDisplayMode(IconDepth depth) const |
|
268 { |
|
269 MifConvIconDisplayModeMap::const_iterator i = iDisplayModeMap.find(depth); |
|
270 if( i != iDisplayModeMap.end() ) |
|
271 return i->second; |
|
272 |
|
273 return DisplayMode_None; |
|
274 } |
|
275 |
|
276 /** |
|
277 * |
|
278 */ |
|
279 IconDisplayMode MifConvArgumentManager::ConvertToMaskDisplayMode(IconMaskDepth depth) const |
|
280 { |
|
281 MifConvMaskIconDisplayModeMap::const_iterator i = iMaskDisplayModeMap.find(depth); |
|
282 if( i != iMaskDisplayModeMap.end() ) |
|
283 return i->second; |
|
284 |
|
285 return DisplayMode_None; |
|
286 } |
|
287 |
|
288 /** |
|
289 * |
|
290 */ |
|
291 IconDepth MifConvArgumentManager::ConvertToDepth( const MifConvString& depthStr ) const |
|
292 { |
|
293 MifConvIconDepthMap::const_iterator i = iDepthMap.find(depthStr); |
|
294 if( i != iDepthMap.end() ) |
|
295 return i->second; |
|
296 |
|
297 return IconDepth_Undefined; |
|
298 } |
|
299 /** |
|
300 * |
|
301 */ |
|
302 IconMaskDepth MifConvArgumentManager::ConvertToMaskDepth( const MifConvString depthStr ) const |
|
303 { |
|
304 MifConvIconMaskDepthMap::const_iterator i = iMaskDepthMap.find(depthStr); |
|
305 if( i != iMaskDepthMap.end() ) |
|
306 return i->second; |
|
307 |
|
308 return IconMaskDepth_Undefined; |
|
309 } |
|
310 |
|
311 /** |
|
312 * |
|
313 */ |
|
314 void MifConvArgumentManager::Init( const MifConvStringList& argList ) |
|
315 { |
|
316 // Build maps for mapping depth, mask and displaymode constants: |
|
317 PopulateDepthAndMaskMaps(); |
|
318 // Allocate search paths where to search source files: |
|
319 MifConvString epocRoot(EpocRoot()); |
|
320 |
|
321 // Global icons folder can contain only .svg files: |
|
322 iSearchRules.push_back(MifConvSourceSearchRule(MifConvString(epocRoot + S60_ICONS_PATH), vector<MifConvString>(1, SVG_FILE_EXTENSION))); |
|
323 // Global bitmaps folder can contain only .bmp files: |
|
324 iSearchRules.push_back(MifConvSourceSearchRule(MifConvString(epocRoot + S60_BITMAPS_PATH), vector<MifConvString>(1, BMP_FILE_EXTENSION))); |
|
325 // EPOCROOT, if given in environment variables: |
|
326 if( epocRoot.length() > 0 ) |
|
327 { |
|
328 iSearchRules.push_back(MifConvSourceSearchRule(epocRoot+EPOC32_PATH, vector<MifConvString>(1, MIFCONV_WILDCARD))); |
|
329 } |
|
330 |
|
331 AddArguments(argList); |
|
332 |
|
333 // check if the parameter file is given: |
|
334 const MifConvString& paramFilename = StringValue(MifConvParameterFileArg); |
|
335 if( paramFilename.length() > 0 ) |
|
336 { |
|
337 // Add arguments from the parameter file: |
|
338 MifConvStringList paramListFromFile; |
|
339 ReadParameterFile( paramFilename, paramListFromFile ); |
|
340 if( paramListFromFile.size() > 0 ) |
|
341 { |
|
342 AddArguments(paramListFromFile, true); |
|
343 } |
|
344 } |
|
345 // Resolve file type extensions using given flags and investigating the existing files: |
|
346 FinalizeArguments(); |
|
347 } |
|
348 |
|
349 /** |
|
350 * Read string argument value: |
|
351 */ |
|
352 MifConvString MifConvArgumentManager::ReadStringArgument(const MifConvStringList& argList, MifConvStringList::const_iterator& i, unsigned int argNameLen) |
|
353 { |
|
354 // Take the actual argument value, for example /TmyTempDir --> myTempDir |
|
355 MifConvString argValue((*i).begin() + argNameLen, (*i).end()); |
|
356 if( argValue.length() > 0 ) |
|
357 { |
|
358 // String arguments can have spaces when they are enclosed with " marks (For example directory names). |
|
359 if( argValue[0] == '\"' ) |
|
360 { |
|
361 MifConvString quotedArgValue(argValue); |
|
362 // Check if the last char is also ": |
|
363 if( quotedArgValue[ quotedArgValue.length()-1 ] == '\"' ) |
|
364 { |
|
365 return quotedArgValue; |
|
366 } |
|
367 |
|
368 // See if the next string ends with \" mark, for example "My Folder" is presented with following argument list: |
|
369 // argList[0] = "My |
|
370 // argList[1] = Folder" |
|
371 while(++i != argList.end()) |
|
372 { |
|
373 MifConvString nextString((*i).begin(), (*i).end()); |
|
374 quotedArgValue += " " + nextString; |
|
375 if( nextString[ nextString.length()-1 ] == '\"' ) |
|
376 { |
|
377 return "\"" + quotedArgValue + "\""; |
|
378 } |
|
379 } |
|
380 } |
|
381 } |
|
382 return argValue; |
|
383 } |
|
384 |
|
385 /** |
|
386 * Read string argument value: |
|
387 */ |
|
388 void MifConvArgumentManager::ReadStringListArgument(MifConvStringList::const_iterator& i, unsigned int argNameLen, MifConvStringList& StringValueList) |
|
389 { |
|
390 // Take the actual argument value, for example /imyInputDir;myTempDir --> myTempDir |
|
391 MifConvString argValue((*i).begin() + argNameLen, (*i).end()); |
|
392 MifConvUtil::SplitString( argValue, STRING_LIST_ARGUMENT_SEPARATOR, StringValueList ); |
|
393 } |
|
394 |
|
395 /** |
|
396 * |
|
397 */ |
|
398 void MifConvArgumentManager::AddArguments( const MifConvStringList& argList, bool paramsFromFile ) |
|
399 { |
|
400 MifConvStringList::const_iterator i = argList.begin(); |
|
401 |
|
402 if( i == argList.end() ) |
|
403 { |
|
404 THROW_ERROR("No arguments", MifConvString(__FILE__), __LINE__); |
|
405 } |
|
406 |
|
407 // Check if help is needed: |
|
408 while( i != argList.end() ) |
|
409 { |
|
410 if( IsHelpArgument(*i) ) |
|
411 { |
|
412 THROW_USAGE_EXCEPTION(); |
|
413 } |
|
414 ++i; |
|
415 } |
|
416 |
|
417 i = argList.begin(); |
|
418 |
|
419 while( i != argList.end() ) |
|
420 { |
|
421 unsigned int argLen = 0; |
|
422 if( i == argList.begin() && paramsFromFile == false ) |
|
423 { |
|
424 // First command line argument must be the target file. |
|
425 // If the given list (argList) is read from the file, then |
|
426 // the first one is not target file. |
|
427 if( !IsArgument(*i) ) |
|
428 { |
|
429 MifConvString targetFile(ReadStringArgument( argList, i, 0 )); |
|
430 // Make sure that the file extension is .mif: |
|
431 targetFile = MifConvUtil::FilenameWithoutExtension(targetFile); |
|
432 targetFile += MifConvString(FILE_EXTENSION_SEPARATOR) + MifConvString(MIF_FILE_EXTENSION); |
|
433 SetTargetFile(targetFile); |
|
434 } |
|
435 else |
|
436 { |
|
437 THROW_ERROR( "Target file must be given as first argument.", MifConvString(__FILE__), __LINE__ ); |
|
438 } |
|
439 ++i; |
|
440 if( i == argList.end() ) |
|
441 { |
|
442 THROW_ERROR("Missing arguments", MifConvString(__FILE__), __LINE__); |
|
443 } |
|
444 } |
|
445 else if( IsBooleanArgument(*i) ) |
|
446 { |
|
447 // Insert boolean type argument to the boolean arguments list: |
|
448 MifConvString argName((*i).begin()+1, (*i).end()); |
|
449 MifConvUtil::ToLower(argName); // Lower the cases to make comparison easier later |
|
450 std::pair<BooleanArgMap::iterator, bool> res = iBooleanArguments.insert(std::make_pair<MifConvString, MifConvBooleanArgument>( |
|
451 argName, MifConvBooleanArgument( argName, true ))); |
|
452 if( res.second == false ) |
|
453 { |
|
454 // parameter already exists in the map, update the value: |
|
455 res.first->second = MifConvBooleanArgument( argName, true ); |
|
456 } |
|
457 ++i; |
|
458 } |
|
459 else if( (argLen = (unsigned int) IsStringArgument(*i) ) > 0 ) |
|
460 { |
|
461 MifConvString argName((*i).begin()+1, (*i).begin() + 1 + argLen); |
|
462 MifConvUtil::ToLower(argName); // Lower the cases to make comparison easier later |
|
463 MifConvString argValue(ReadStringArgument( argList, i, argLen+1 )); |
|
464 if( argValue.length() == 0 ) |
|
465 { |
|
466 // Do not accept string arguments with zero length (E.g. "/H") |
|
467 THROW_ERROR( "Missing argument value for " + *i, MifConvString(__FILE__), __LINE__ ); |
|
468 } |
|
469 // Insert string type argument to the string arguments list: |
|
470 std::pair<StringArgMap::iterator, bool> res = iStringArguments.insert(std::make_pair<MifConvString, MifConvStringArgument>( |
|
471 argName, MifConvStringArgument( argName, argValue ))); |
|
472 if( res.second == false ) |
|
473 { |
|
474 // parameter already exists in the map, update the value: |
|
475 res.first->second = MifConvStringArgument( argName, argValue ); |
|
476 } |
|
477 ++i; |
|
478 } |
|
479 else if( (argLen = (unsigned int) IsStringListArgument(*i)) > 0 ) |
|
480 { |
|
481 MifConvString argName((*i).begin()+1, (*i).begin() + 1 + argLen); |
|
482 MifConvUtil::ToLower(argName); // Lower the cases to make comparison easier later |
|
483 MifConvStringList argValue; |
|
484 ReadStringListArgument( i, argLen+1, argValue ); |
|
485 |
|
486 if( argValue.size() == 0 ) |
|
487 { |
|
488 // Do not accept string arguments with zero length (E.g. "/H") |
|
489 THROW_ERROR( "Missing argument value for " + *i, MifConvString(__FILE__), __LINE__ ); |
|
490 } |
|
491 // Insert string list type argument to the string arguments list: |
|
492 std::pair<StringListArgMap::iterator, bool> res = iStringListArguments.insert(std::make_pair<MifConvString, MifConvStringListArgument>( |
|
493 argName, MifConvStringListArgument( argName, argValue ))); |
|
494 if( res.second == false ) |
|
495 { |
|
496 // parameter already exists in the map, update the value: |
|
497 res.first->second = MifConvStringListArgument( argName, argValue ); |
|
498 } |
|
499 ++i; |
|
500 } |
|
501 else if( IsDepthArgument(*i) ) |
|
502 { |
|
503 // Let's build source file argument... |
|
504 // ... first is depth and mask: |
|
505 MifConvString depthAndMask(*i); |
|
506 MifConvUtil::ToLower(depthAndMask); // Lower the cases to make comparison easier later |
|
507 ++i; |
|
508 // Check that there is still an argument: |
|
509 if( i == argList.end() ) |
|
510 { |
|
511 THROW_ERROR( "Missing source file argument.", MifConvString(__FILE__), __LINE__ ); |
|
512 } |
|
513 |
|
514 // Then we check if animated flag is given next: |
|
515 bool isAnimated = IsAnimatedFlag(*i); |
|
516 |
|
517 if( isAnimated ) |
|
518 { |
|
519 // This was an animated flag, so next must be filename: |
|
520 ++i; |
|
521 // Check that there is still an argument: |
|
522 if( i == argList.end() ) |
|
523 { |
|
524 THROW_ERROR( "Missing source file argument.", MifConvString(__FILE__), __LINE__ ); |
|
525 //THROW_USAGE_EXCEPTION(); |
|
526 } |
|
527 } |
|
528 |
|
529 // One more check... Check that the next string is not an argument (starting with '-' or '/') |
|
530 // It should be a filename for the source icon. |
|
531 if( IsArgument(*i) ) |
|
532 { |
|
533 THROW_ERROR( "Missing source file argument.", MifConvString(__FILE__), __LINE__ ); |
|
534 } |
|
535 |
|
536 MifConvSourceFile srcFile; |
|
537 srcFile.SetDepthAndMask(depthAndMask); |
|
538 srcFile.SetDisplayMode(ConvertToDisplayMode(srcFile.Depth())); |
|
539 srcFile.SetMaskDisplayMode(ConvertToMaskDisplayMode(srcFile.MaskDepth())); |
|
540 srcFile.SetFilename(ReadStringArgument( argList, i, 0 )); |
|
541 srcFile.SetAnimated(isAnimated); |
|
542 iSourceFiles.push_back(srcFile); |
|
543 ++i; |
|
544 } |
|
545 else if( IsAnimatedFlag(*i) ) |
|
546 { |
|
547 // Icon animated flag found |
|
548 // Let's see if the next is depth argument: |
|
549 ++i; |
|
550 MifConvString depthAndMask; |
|
551 if( IsDepthArgument(*i) ) |
|
552 { |
|
553 depthAndMask = *i; |
|
554 MifConvUtil::ToLower(depthAndMask); |
|
555 ++i; |
|
556 } |
|
557 |
|
558 // One more check... Check that the next string is not an argument (starting with '-' or '/') |
|
559 if( IsArgument(*i) ) |
|
560 { |
|
561 THROW_ERROR( "Missing source file argument.", MifConvString(__FILE__), __LINE__ ); |
|
562 } |
|
563 |
|
564 MifConvSourceFile srcFile; |
|
565 srcFile.SetDepthAndMask(depthAndMask); |
|
566 srcFile.SetDisplayMode(ConvertToDisplayMode(srcFile.Depth())); |
|
567 srcFile.SetMaskDisplayMode(ConvertToMaskDisplayMode(srcFile.MaskDepth())); |
|
568 srcFile.SetFilename(*i); |
|
569 srcFile.SetAnimated(true); |
|
570 iSourceFiles.push_back(srcFile); |
|
571 ++i; |
|
572 } |
|
573 else |
|
574 { |
|
575 THROW_ERROR( "Invalid argument: " + *i, MifConvString(__FILE__), __LINE__ ); |
|
576 } |
|
577 } |
|
578 } |
|
579 |
|
580 /** |
|
581 * Resolves correct type for the source file. Sets also mask filenames for bmp-files: |
|
582 */ |
|
583 void MifConvArgumentManager::ResolveSourceFileTypes() |
|
584 { |
|
585 bool extensionFlag = BooleanValue(MifConvUseExtensionArg); |
|
586 |
|
587 // check if the input directory is given: |
|
588 const MifConvStringList& inputDirList = StringListValue(MifConvIconSourceDirectory); |
|
589 |
|
590 // Add user-defined input directory to search directory list, put MIFCONV_WILDCARD |
|
591 // as filetype rule, because user defined directory can contain all supported filetypes: |
|
592 int indexcounter = 0; |
|
593 for( MifConvStringList::const_iterator iDir = inputDirList.begin(); iDir != inputDirList.end(); ++iDir ) |
|
594 { |
|
595 MifConvSourceSearchRule customRule(*iDir, MifConvStringList(1, MIFCONV_WILDCARD)); |
|
596 MifConvUtil::ReplaceChar(customRule.SearchPath(), INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2); |
|
597 MifConvUtil::RemoveDuplicateDirSeparators(customRule.SearchPath()); |
|
598 iSearchRules.insert(iSearchRules.begin()+indexcounter, customRule); |
|
599 |
|
600 ++indexcounter; |
|
601 } |
|
602 |
|
603 for( MifConvSourceFileList::iterator src = iSourceFiles.begin(); src != iSourceFiles.end(); ++ src ) |
|
604 { |
|
605 if( extensionFlag ) |
|
606 { |
|
607 MifConvString extension = MifConvUtil::FileExtension(src->Filename()); |
|
608 if( !FindAndSetPathAndType( *src, extension ) ) |
|
609 { |
|
610 THROW_ERROR_COMMON("File not found " + src->Filename(), MifConvString(__FILE__), __LINE__ ); |
|
611 } |
|
612 } |
|
613 else |
|
614 { |
|
615 // "Use extension" -flag not given, so resolve extensions for source files |
|
616 if( !FindAndSetPathAndType( *src, SVGB_BINARY_FILE_EXTENSION ) ) |
|
617 { |
|
618 if( !FindAndSetPathAndType( *src, SVG_FILE_EXTENSION ) ) |
|
619 { |
|
620 if( !FindAndSetPathAndType( *src, BMP_FILE_EXTENSION ) ) |
|
621 { |
|
622 THROW_ERROR_COMMON("File not found " + src->Filename(), MifConvString(__FILE__), __LINE__ ); |
|
623 } |
|
624 } |
|
625 } |
|
626 } |
|
627 } |
|
628 } |
|
629 |
|
630 /** |
|
631 * |
|
632 */ |
|
633 void MifConvArgumentManager::GetMifEnv() |
|
634 { |
|
635 // Read EPOCROOT environment variable |
|
636 char* tmpPtr = 0; |
|
637 tmpPtr = getenv(EPOCROOT_ENV.c_str()); |
|
638 if( tmpPtr ) |
|
639 { |
|
640 iEpocRoot = MifConvString(tmpPtr); |
|
641 MifConvUtil::ReplaceChar(iEpocRoot, INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2); |
|
642 // Make sure that the last char is directory separator |
|
643 if( iEpocRoot.length() > 0 && iEpocRoot.at( iEpocRoot.length()-1) != DIR_SEPARATOR2 ) |
|
644 { |
|
645 iEpocRoot += DIR_SEPARATOR; |
|
646 } |
|
647 } |
|
648 } |
|
649 |
|
650 /** |
|
651 * |
|
652 */ |
|
653 const MifConvString& MifConvArgumentManager::EpocRoot() const |
|
654 { |
|
655 return iEpocRoot; |
|
656 } |
|
657 |
|
658 /** |
|
659 * |
|
660 */ |
|
661 bool MifConvArgumentManager::FindAndSetPathAndType( MifConvSourceFile& srcFile, const MifConvString& extension ) |
|
662 { |
|
663 // Search the filename first "as is": |
|
664 MifConvString tmp( MifConvUtil::FilenameWithoutExtension( srcFile.Filename() ) + MifConvString(FILE_EXTENSION_SEPARATOR) + extension ); |
|
665 if( MifConvUtil::FileExists(tmp) ) |
|
666 { |
|
667 srcFile.SetFilename(tmp); |
|
668 MifConvUtil::FindAndSetBitmapMaskFile(srcFile); |
|
669 return true; |
|
670 } |
|
671 |
|
672 // If the absolute path was given, return false, because the file was not found with given path and filename. |
|
673 // Otherwise continue searching. |
|
674 if( //(srcFile.Filename().length() > 0 && srcFile.Filename().at(0) == DIR_SEPARATOR2) || |
|
675 (srcFile.Filename().length() > 1 && srcFile.Filename().at(1) == ':') ) |
|
676 { |
|
677 return false; |
|
678 } |
|
679 |
|
680 // Search from the pre-defined locations: |
|
681 for( SearchRules::iterator i = iSearchRules.begin(); i != iSearchRules.end(); ++i ) |
|
682 { |
|
683 bool validPath = false; |
|
684 const MifConvStringList& allowedTypes = i->AllowedFileTypes(); |
|
685 |
|
686 // See if the file with given extension is allowed to locate in search path. |
|
687 // For example, epoc32\s60\icons folder can contain only .svg files and epoc32\s60\bitmaps |
|
688 // can contain only .bmp files: |
|
689 for( MifConvStringList::const_iterator typeIter = allowedTypes.begin(); typeIter != allowedTypes.end(); ++typeIter ) |
|
690 { |
|
691 if( *typeIter == MIFCONV_WILDCARD || *typeIter == extension ) |
|
692 { |
|
693 validPath = true; |
|
694 break; |
|
695 } |
|
696 } |
|
697 |
|
698 if( validPath ) |
|
699 { |
|
700 MifConvString searchPath(i->SearchPath()); |
|
701 |
|
702 // Make sure that the last char is directory separator |
|
703 if( searchPath.length() > 0 && searchPath.at( searchPath.length()-1) != DIR_SEPARATOR2 ) |
|
704 { |
|
705 searchPath += DIR_SEPARATOR; |
|
706 } |
|
707 |
|
708 searchPath += MifConvUtil::FilenameWithoutExtension( srcFile.Filename() ) + MifConvString(FILE_EXTENSION_SEPARATOR) + extension; |
|
709 |
|
710 MifConvUtil::RemoveDuplicateDirSeparators(searchPath); |
|
711 |
|
712 if( MifConvUtil::FileExists( searchPath ) ) |
|
713 { |
|
714 srcFile.SetFilename(searchPath); |
|
715 MifConvUtil::FindAndSetBitmapMaskFile(srcFile); |
|
716 return true; |
|
717 } |
|
718 } |
|
719 } |
|
720 return false; |
|
721 } |
|
722 |
|
723 /** |
|
724 * |
|
725 */ |
|
726 void MifConvArgumentManager::ProcessArgumentPaths() |
|
727 { |
|
728 // Fix directory separators first: |
|
729 for( StringArgMap::iterator i = iStringArguments.begin(); i != iStringArguments.end(); ++i ) |
|
730 { |
|
731 MifConvString tmp = i->second.Value(); |
|
732 MifConvUtil::ReplaceChar(tmp, INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2); |
|
733 MifConvUtil::RemoveDuplicateDirSeparators(tmp); |
|
734 i->second.SetValue(tmp); |
|
735 } |
|
736 |
|
737 // Fix directory separators in source filenames also: |
|
738 for( MifConvSourceFileList::iterator j = iSourceFiles.begin(); j != iSourceFiles.end(); ++j ) |
|
739 { |
|
740 MifConvString tmp = j->Filename(); |
|
741 MifConvUtil::ReplaceChar(tmp, INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2); |
|
742 MifConvUtil::RemoveDuplicateDirSeparators(tmp); |
|
743 j->SetFilename(tmp); |
|
744 } |
|
745 |
|
746 // Fix directory separators in search rule directories also: |
|
747 for( SearchRules::iterator k = iSearchRules.begin(); k != iSearchRules.end(); ++k ) |
|
748 { |
|
749 MifConvString& tmp = k->SearchPath(); |
|
750 MifConvUtil::ReplaceChar(tmp, INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2); |
|
751 MifConvUtil::RemoveDuplicateDirSeparators(tmp); |
|
752 } |
|
753 |
|
754 // Fix target file also: |
|
755 MifConvUtil::ReplaceChar(iTargetFile, INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2); |
|
756 MifConvUtil::RemoveDuplicateDirSeparators(iTargetFile); |
|
757 } |
|
758 |
|
759 /** |
|
760 * |
|
761 */ |
|
762 void MifConvArgumentManager::FinalizeArguments() |
|
763 { |
|
764 ProcessArgumentPaths(); |
|
765 ResolveSourceFileTypes(); |
|
766 } |
|
767 |
|
768 /** |
|
769 * |
|
770 */ |
|
771 void MifConvArgumentManager::SetUsageString( MifConvString& usageStr ) const |
|
772 { |
|
773 usageStr = ""; |
|
774 |
|
775 usageStr += "Copyright (c) " + MifConvYears + " Nokia Corporation and/or its subsidiary(-ies). All rights reserved.\n"; |
|
776 usageStr += "\n"; |
|
777 usageStr += "Usage: mifconv <MIFFILE> [-F<file>] <options> <sources>]\n"; |
|
778 usageStr += "\n"; |
|
779 usageStr += "Where:\n"; |
|
780 usageStr += " MIFFILE Specifies the target MIF file to be created\n"; |
|
781 usageStr += " -F<file> Specifies a parameter file, which can contain any of the options\n"; |
|
782 usageStr += " and sources separated by spaces or newlines\n"; |
|
783 usageStr += "\n"; |
|
784 usageStr += "Options:\n"; |
|
785 usageStr += " -H<file> Specifies a name of the MIF header file (default extension MBG)\n"; |
|
786 usageStr += " -I<dir;dir;...> Specifies a set of custom source directories where source files\n"; |
|
787 usageStr += " will be searched. As a fallback, global source directories are\n"; |
|
788 usageStr += " used\n"; |
|
789 usageStr += " -E Specifies that source icons are only loaded with given file\n"; |
|
790 usageStr += " extensions. By default, Mifconv prefers source icons with\n"; |
|
791 usageStr += " extension .SVG over .BMP, regardless of which is given as\n"; |
|
792 usageStr += " a parameter\n"; |
|
793 usageStr += " -X Disables SVG compression. If this flag is set, SVG icons are\n"; |
|
794 usageStr += " added to MIF file without compressing them first\n"; |
|
795 usageStr += " -P<file> Specifies a path to custom palette file for bitmap files\n"; |
|
796 usageStr += " -T<dir> Specifies a path where temporary files are created\n"; |
|
797 usageStr += " -B<file> Specifies a path for non-default BMConv utility\n"; |
|
798 usageStr += " -S<file> Specifies a path for non-default SVGTBinenCode utility\n"; |
|
799 usageStr += " -V<string> Specifies a non-platform default format version of SVGT binary\n"; |
|
800 usageStr += " conversion. It can be any of the following value:\n"; |
|
801 usageStr += " 1 BGR / float encoding\n"; |
|
802 usageStr += " 2 BGR / fixed point encoding\n"; |
|
803 usageStr += " 3 RGB / fixed point encoding\n"; |
|
804 usageStr += " 4 RGB / float encoding\n"; |
|
805 usageStr += "Sources:\n"; |
|
806 usageStr += " [-A] <DEPTH[,MASK]> <FILE> [ [-A] <DEPTH[,MASK]> <FILE> ... ]\n"; |
|
807 usageStr += " [-A] Specifies animated flag for the icon\n"; |
|
808 usageStr += " [DEPTH] Specifies icon depth, it can be any of these values\n"; |
|
809 usageStr += " -1,-2,-4,-8,-c4,-c8,-c12,-c16,-c24,-c32\n"; |
|
810 usageStr += " [MASK] Specifies icon mask depth, it can be any of these values\n"; |
|
811 usageStr += " 1,8\n"; |
|
812 usageStr += " [FILE] Specifies path to the input file, supported file extensions are\n"; |
|
813 usageStr += " SVG, SVGB, BMP\n"; |
|
814 usageStr += "\n"; |
|
815 usageStr += "Other info:\n"; |
|
816 #ifdef WIN32 |
|
817 usageStr += " * '-' or '/' can be used as parameter switch prefix\n"; |
|
818 #endif |
|
819 usageStr += " * Value of icon mask and depth is meaningful only for bitmap files, but the mask\n"; |
|
820 usageStr += " value defines if mask entry will be available or not in the header file\n"; |
|
821 usageStr += " * If mask parameter is defined for a BMP file, Mifconv automatically pics\n"; |
|
822 usageStr += " a file ending _mask_soft for value 8 and _mask for value 1 of mask\n"; |
|
823 usageStr += "\n"; |
|
824 usageStr += "Examples:\n"; |
|
825 usageStr += " mifconv mybuttons.mif -Hmybuttons.mbg -c8,8 button1 -c8,8 button2\n"; |
|
826 } |
|
827 |
|
828 /** |
|
829 * |
|
830 */ |
|
831 const MifConvString& MifConvArgumentManager::StringValue( const MifConvString& argName ) const |
|
832 { |
|
833 StringArgMap::const_iterator i = iStringArguments.find(argName); |
|
834 if( i != iStringArguments.end() ) |
|
835 { |
|
836 return i->second.Value(); |
|
837 } |
|
838 |
|
839 return iDummyString; |
|
840 } |
|
841 |
|
842 /** |
|
843 * |
|
844 */ |
|
845 const MifConvStringList& MifConvArgumentManager::StringListValue( const MifConvString& argName ) const |
|
846 { |
|
847 StringListArgMap::const_iterator i = iStringListArguments.find(argName); |
|
848 if( i != iStringListArguments.end() ) |
|
849 { |
|
850 return i->second.Value(); |
|
851 } |
|
852 |
|
853 return iDummyStringList; |
|
854 } |
|
855 |
|
856 /** |
|
857 * |
|
858 */ |
|
859 bool MifConvArgumentManager::BooleanValue( const MifConvString& argName ) const |
|
860 { |
|
861 BooleanArgMap::const_iterator i = iBooleanArguments.find(argName); |
|
862 if( i != iBooleanArguments.end() ) |
|
863 { |
|
864 return i->second.Value(); |
|
865 } |
|
866 |
|
867 return false; |
|
868 } |
|
869 |
|
870 /** |
|
871 * |
|
872 */ |
|
873 const MifConvSourceFileList& MifConvArgumentManager::SourceFiles() const |
|
874 { |
|
875 return iSourceFiles; |
|
876 } |
|
877 |
|
878 /** |
|
879 * |
|
880 */ |
|
881 bool MifConvArgumentManager::IsArgument( const MifConvString& str ) const |
|
882 { |
|
883 try { |
|
884 return str.at(0) == OPTION_PREFIX1_CHAR || str.at(0) == OPTION_PREFIX2_CHAR; |
|
885 } |
|
886 catch(...) |
|
887 { |
|
888 THROW_ERROR("Zero or corrupted string in MifConvArgumentManager::IsArgument()\n", MifConvString(__FILE__), __LINE__); |
|
889 } |
|
890 return false; |
|
891 } |
|
892 |
|
893 /** |
|
894 * |
|
895 */ |
|
896 void MifConvArgumentManager::PopulateDepthAndMaskMaps() |
|
897 { |
|
898 // Insert value-string pairs for the icon depths: |
|
899 iDepthMap.insert(std::make_pair(MifConvDepth_1, IconDepth_1)); |
|
900 iDepthMap.insert(std::make_pair(MifConvDepth_2, IconDepth_2)); |
|
901 iDepthMap.insert(std::make_pair(MifConvDepth_4, IconDepth_4)); |
|
902 iDepthMap.insert(std::make_pair(MifConvDepth_8, IconDepth_8)); |
|
903 iDepthMap.insert(std::make_pair(MifConvDepth_c4, IconDepth_c4)); |
|
904 iDepthMap.insert(std::make_pair(MifConvDepth_c8, IconDepth_c8)); |
|
905 iDepthMap.insert(std::make_pair(MifConvDepth_c12, IconDepth_c12)); |
|
906 iDepthMap.insert(std::make_pair(MifConvDepth_c16, IconDepth_c16)); |
|
907 iDepthMap.insert(std::make_pair(MifConvDepth_c24, IconDepth_c24)); |
|
908 iDepthMap.insert(std::make_pair(MifConvDepth_c32, IconDepth_c32)); |
|
909 |
|
910 // Insert value-string pairs for the icon masks: |
|
911 iMaskDepthMap.insert(std::make_pair(MifConvMaskDepth_1, IconMaskDepth_1)); |
|
912 iMaskDepthMap.insert(std::make_pair(MifConvMaskDepth_8, IconMaskDepth_8)); |
|
913 |
|
914 // Insert value-pairs for display modes: |
|
915 iDisplayModeMap.insert(std::make_pair(IconDepth_1, DisplayMode_Gray2)); |
|
916 iDisplayModeMap.insert(std::make_pair(IconDepth_2, DisplayMode_Gray4)); |
|
917 iDisplayModeMap.insert(std::make_pair(IconDepth_4, DisplayMode_Gray16)); |
|
918 iDisplayModeMap.insert(std::make_pair(IconDepth_8, DisplayMode_Gray256)); |
|
919 iDisplayModeMap.insert(std::make_pair(IconDepth_c4, DisplayMode_Color16)); |
|
920 iDisplayModeMap.insert(std::make_pair(IconDepth_c8, DisplayMode_Color256)); |
|
921 iDisplayModeMap.insert(std::make_pair(IconDepth_c12, DisplayMode_Color4K)); |
|
922 iDisplayModeMap.insert(std::make_pair(IconDepth_c16, DisplayMode_Color64K)); |
|
923 iDisplayModeMap.insert(std::make_pair(IconDepth_c24, DisplayMode_Color16M)); |
|
924 iDisplayModeMap.insert(std::make_pair(IconDepth_c32, DisplayMode_Color16MU)); |
|
925 |
|
926 iMaskDisplayModeMap.insert(std::make_pair(IconMaskDepth_1, DisplayMode_Gray2)); |
|
927 iMaskDisplayModeMap.insert(std::make_pair(IconMaskDepth_8, DisplayMode_Gray256)); |
|
928 } |
|
929 |
|
930 /** |
|
931 * |
|
932 */ |
|
933 void MifConvArgumentManager::ReadParameterFile(const MifConvString& paramFilename, MifConvStringList& paramList) |
|
934 { |
|
935 // Check if the file exists: |
|
936 if( MifConvUtil::FileExists(paramFilename) == false ) |
|
937 { |
|
938 THROW_ERROR_COMMON("Unable to open file for reading! " + paramFilename, MifConvString(__FILE__), __LINE__ ); |
|
939 } |
|
940 |
|
941 MifConvFileData paramFileData = MifConvUtil::FileContents(paramFilename); |
|
942 |
|
943 MifConvString tmpString; |
|
944 for(size_t i = 0; i < paramFileData.second; ++i ) |
|
945 { |
|
946 if( MifConvUtil::IsWhiteSpace(paramFileData.first[i]) == false ) |
|
947 { |
|
948 tmpString += paramFileData.first[i]; |
|
949 } |
|
950 else if( tmpString.length() > 0 ) |
|
951 { |
|
952 paramList.push_back( tmpString ); |
|
953 tmpString = MifConvString(); |
|
954 } |
|
955 } |
|
956 |
|
957 if( tmpString.length() > 0 ) |
|
958 { |
|
959 paramList.push_back( tmpString ); |
|
960 tmpString = MifConvString(); |
|
961 } |
|
962 delete[] paramFileData.first; |
|
963 } |
|
964 |
|
965 /** |
|
966 * Helper class for source search rules |
|
967 */ |
|
968 |
|
969 MifConvSourceSearchRule::MifConvSourceSearchRule(const MifConvString& path, const MifConvStringList& types) |
|
970 : |
|
971 iSearchPath(path), |
|
972 iAllowedFileTypes(types) |
|
973 {} |
|
974 |
|
975 MifConvSourceSearchRule::~MifConvSourceSearchRule() |
|
976 {} |
|
977 |
|
978 const MifConvString& MifConvSourceSearchRule::SearchPath() const |
|
979 { |
|
980 return iSearchPath; |
|
981 } |
|
982 |
|
983 MifConvString& MifConvSourceSearchRule::SearchPath() |
|
984 { |
|
985 return iSearchPath; |
|
986 } |
|
987 |
|
988 const MifConvStringList& MifConvSourceSearchRule::AllowedFileTypes() const |
|
989 { |
|
990 return iAllowedFileTypes; |
|
991 } |