8bfd035343795dbc1c981e3269213485e4aa6bd9
[reactos.git] / reactos / tools / rbuild / module.cpp
1 #include "pch.h"
2 #include <assert.h>
3
4 #include "rbuild.h"
5
6 using std::string;
7 using std::vector;
8
9 string
10 FixSeparator ( const string& s )
11 {
12 string s2(s);
13 char* p = strchr ( &s2[0], CBAD_SEP );
14 while ( p )
15 {
16 *p++ = CSEP;
17 p = strchr ( p, CBAD_SEP );
18 }
19 return s2;
20 }
21
22 string
23 ReplaceExtension (
24 const string& filename,
25 const string& newExtension )
26 {
27 size_t index = filename.find_last_of ( '/' );
28 if ( index == string::npos )
29 index = 0;
30 size_t index2 = filename.find_last_of ( '\\' );
31 if ( index2 != string::npos && index2 > index )
32 index = index2;
33 string tmp = filename.substr( index /*, filename.size() - index*/ );
34 size_t ext_index = tmp.find_last_of( '.' );
35 if ( ext_index != string::npos )
36 return filename.substr ( 0, index + ext_index ) + newExtension;
37 return filename + newExtension;
38 }
39
40 string
41 GetSubPath (
42 const string& location,
43 const string& path,
44 const string& att_value )
45 {
46 if ( !att_value.size() )
47 throw InvalidBuildFileException (
48 location,
49 "<directory> tag has empty 'name' attribute" );
50 if ( strpbrk ( att_value.c_str (), "/\\?*:<>|" ) )
51 throw InvalidBuildFileException (
52 location,
53 "<directory> tag has invalid characters in 'name' attribute" );
54 if ( !path.size() )
55 return att_value;
56 return FixSeparator(path + CSEP + att_value);
57 }
58
59 string
60 GetExtension ( const string& filename )
61 {
62 size_t index = filename.find_last_of ( '/' );
63 if (index == string::npos) index = 0;
64 string tmp = filename.substr( index, filename.size() - index );
65 size_t ext_index = tmp.find_last_of( '.' );
66 if (ext_index != string::npos)
67 return filename.substr ( index + ext_index, filename.size() );
68 return "";
69 }
70
71 string
72 GetDirectory ( const string& filename )
73 {
74 size_t index = filename.find_last_of ( CSEP );
75 if ( index == string::npos )
76 return filename;
77 else
78 return filename.substr ( 0, index );
79 }
80
81 string
82 NormalizeFilename ( const string& filename )
83 {
84 Path path;
85 string normalizedPath = path.Fixup ( filename, true );
86 string relativeNormalizedPath = path.RelativeFromWorkingDirectory ( normalizedPath );
87 return FixSeparator ( relativeNormalizedPath );
88 }
89
90 IfableData::~IfableData()
91 {
92 size_t i;
93 for ( i = 0; i < files.size(); i++ )
94 delete files[i];
95 for ( i = 0; i < includes.size(); i++ )
96 delete includes[i];
97 for ( i = 0; i < defines.size(); i++ )
98 delete defines[i];
99 for ( i = 0; i < libraries.size(); i++ )
100 delete libraries[i];
101 for ( i = 0; i < properties.size(); i++ )
102 delete properties[i];
103 for ( i = 0; i < ifs.size(); i++ )
104 delete ifs[i];
105 }
106
107 void IfableData::ProcessXML ()
108 {
109 size_t i;
110 for ( i = 0; i < files.size (); i++ )
111 files[i]->ProcessXML ();
112 for ( i = 0; i < includes.size (); i++ )
113 includes[i]->ProcessXML ();
114 for ( i = 0; i < defines.size (); i++ )
115 defines[i]->ProcessXML ();
116 for ( i = 0; i < libraries.size (); i++ )
117 libraries[i]->ProcessXML ();
118 for ( i = 0; i < properties.size(); i++ )
119 properties[i]->ProcessXML ();
120 for ( i = 0; i < ifs.size (); i++ )
121 ifs[i]->ProcessXML ();
122 }
123
124 Module::Module ( const Project& project,
125 const XMLElement& moduleNode,
126 const string& modulePath )
127 : project (project),
128 node (moduleNode),
129 importLibrary (NULL),
130 bootstrap (NULL),
131 pch (NULL),
132 cplusplus (false),
133 host (HostDefault)
134 {
135 if ( node.name != "module" )
136 throw InvalidOperationException ( __FILE__,
137 __LINE__,
138 "Module created with non-<module> node" );
139
140 path = FixSeparator ( modulePath );
141
142 const XMLAttribute* att = moduleNode.GetAttribute ( "name", true );
143 assert(att);
144 name = att->value;
145
146 att = moduleNode.GetAttribute ( "type", true );
147 assert(att);
148 type = GetModuleType ( node.location, *att );
149
150 att = moduleNode.GetAttribute ( "extension", false );
151 if ( att != NULL )
152 extension = att->value;
153 else
154 extension = GetDefaultModuleExtension ();
155
156 att = moduleNode.GetAttribute ( "entrypoint", false );
157 if ( att != NULL )
158 entrypoint = att->value;
159 else
160 entrypoint = GetDefaultModuleEntrypoint ();
161
162 att = moduleNode.GetAttribute ( "baseaddress", false );
163 if ( att != NULL )
164 baseaddress = att->value;
165 else
166 baseaddress = GetDefaultModuleBaseaddress ();
167
168 att = moduleNode.GetAttribute ( "mangledsymbols", false );
169 if ( att != NULL )
170 {
171 const char* p = att->value.c_str();
172 if ( !stricmp ( p, "true" ) || !stricmp ( p, "yes" ) )
173 mangledSymbols = true;
174 else if ( !stricmp ( p, "false" ) || !stricmp ( p, "no" ) )
175 mangledSymbols = false;
176 else
177 {
178 throw InvalidAttributeValueException (
179 moduleNode.location,
180 "mangledsymbols",
181 att->value );
182 }
183 }
184 else
185 mangledSymbols = false;
186
187 att = moduleNode.GetAttribute ( "host", false );
188 if ( att != NULL )
189 {
190 const char* p = att->value.c_str();
191 if ( !stricmp ( p, "true" ) || !stricmp ( p, "yes" ) )
192 host = HostTrue;
193 else if ( !stricmp ( p, "false" ) || !stricmp ( p, "no" ) )
194 host = HostFalse;
195 else
196 {
197 throw InvalidAttributeValueException (
198 moduleNode.location,
199 "host",
200 att->value );
201 }
202 }
203
204 att = moduleNode.GetAttribute ( "prefix", false );
205 if ( att != NULL )
206 prefix = att->value;
207
208 att = moduleNode.GetAttribute ( "installbase", false );
209 if ( att != NULL )
210 installBase = att->value;
211 else
212 installBase = "";
213
214 att = moduleNode.GetAttribute ( "installname", false );
215 if ( att != NULL )
216 installName = att->value;
217 else
218 installName = "";
219
220 att = moduleNode.GetAttribute ( "usewrc", false );
221 if ( att != NULL )
222 useWRC = att->value == "true";
223 else
224 useWRC = true;
225 }
226
227 Module::~Module ()
228 {
229 size_t i;
230 for ( i = 0; i < invocations.size(); i++ )
231 delete invocations[i];
232 for ( i = 0; i < dependencies.size(); i++ )
233 delete dependencies[i];
234 for ( i = 0; i < compilerFlags.size(); i++ )
235 delete compilerFlags[i];
236 for ( i = 0; i < linkerFlags.size(); i++ )
237 delete linkerFlags[i];
238 for ( i = 0; i < stubbedComponents.size(); i++ )
239 delete stubbedComponents[i];
240 if ( pch )
241 delete pch;
242 }
243
244 void
245 Module::ProcessXML()
246 {
247 size_t i;
248 for ( i = 0; i < node.subElements.size(); i++ )
249 ProcessXMLSubElement ( *node.subElements[i], path );
250 for ( i = 0; i < invocations.size(); i++ )
251 invocations[i]->ProcessXML ();
252 for ( i = 0; i < dependencies.size(); i++ )
253 dependencies[i]->ProcessXML ();
254 for ( i = 0; i < compilerFlags.size(); i++ )
255 compilerFlags[i]->ProcessXML();
256 for ( i = 0; i < linkerFlags.size(); i++ )
257 linkerFlags[i]->ProcessXML();
258 for ( i = 0; i < stubbedComponents.size(); i++ )
259 stubbedComponents[i]->ProcessXML();
260 non_if_data.ProcessXML();
261 if ( pch )
262 pch->ProcessXML();
263 }
264
265 void
266 Module::ProcessXMLSubElement ( const XMLElement& e,
267 const string& path,
268 If* pIf /*= NULL*/ )
269 {
270 bool subs_invalid = false;
271 string subpath ( path );
272 if ( e.name == "file" && e.value.size () > 0 )
273 {
274 bool first = false;
275 const XMLAttribute* att = e.GetAttribute ( "first", false );
276 if ( att )
277 {
278 if ( !stricmp ( att->value.c_str(), "true" ) )
279 first = true;
280 else if ( stricmp ( att->value.c_str(), "false" ) )
281 throw InvalidBuildFileException (
282 e.location,
283 "attribute 'first' of <file> element can only be 'true' or 'false'" );
284 }
285 if ( !cplusplus )
286 {
287 // check for c++ file
288 string ext = GetExtension ( e.value );
289 if ( !stricmp ( ext.c_str(), ".cpp" ) )
290 cplusplus = true;
291 else if ( !stricmp ( ext.c_str(), ".cc" ) )
292 cplusplus = true;
293 else if ( !stricmp ( ext.c_str(), ".cxx" ) )
294 cplusplus = true;
295 }
296 File* pFile = new File ( FixSeparator ( path + CSEP + e.value ), first );
297 if ( pIf )
298 pIf->data.files.push_back ( pFile );
299 else
300 non_if_data.files.push_back ( pFile );
301 subs_invalid = true;
302 }
303 else if ( e.name == "library" && e.value.size () )
304 {
305 Library* pLibrary = new Library ( e, *this, e.value );
306 if ( pIf )
307 pIf->data.libraries.push_back ( pLibrary );
308 else
309 non_if_data.libraries.push_back ( pLibrary );
310 subs_invalid = true;
311 }
312 else if ( e.name == "directory" )
313 {
314 const XMLAttribute* att = e.GetAttribute ( "name", true );
315 assert(att);
316 subpath = GetSubPath ( e.location, path, att->value );
317 }
318 else if ( e.name == "include" )
319 {
320 Include* include = new Include ( project, this, e );
321 if ( pIf )
322 pIf->data.includes.push_back ( include );
323 else
324 non_if_data.includes.push_back ( include );
325 subs_invalid = true;
326 }
327 else if ( e.name == "define" )
328 {
329 Define* pDefine = new Define ( project, this, e );
330 if ( pIf )
331 pIf->data.defines.push_back ( pDefine );
332 else
333 non_if_data.defines.push_back ( pDefine );
334 subs_invalid = true;
335 }
336 else if ( e.name == "invoke" )
337 {
338 if ( pIf )
339 throw InvalidBuildFileException (
340 e.location,
341 "<invoke> is not a valid sub-element of <if>" );
342 invocations.push_back ( new Invoke ( e, *this ) );
343 subs_invalid = false;
344 }
345 else if ( e.name == "dependency" )
346 {
347 if ( pIf )
348 throw InvalidBuildFileException (
349 e.location,
350 "<dependency> is not a valid sub-element of <if>" );
351 dependencies.push_back ( new Dependency ( e, *this ) );
352 subs_invalid = true;
353 }
354 else if ( e.name == "importlibrary" )
355 {
356 if ( pIf )
357 throw InvalidBuildFileException (
358 e.location,
359 "<importlibrary> is not a valid sub-element of <if>" );
360 if ( importLibrary )
361 throw InvalidBuildFileException (
362 e.location,
363 "Only one <importlibrary> is valid per module" );
364 importLibrary = new ImportLibrary ( e, *this );
365 subs_invalid = true;
366 }
367 else if ( e.name == "if" )
368 {
369 If* pOldIf = pIf;
370 pIf = new If ( e, project, this );
371 if ( pOldIf )
372 pOldIf->data.ifs.push_back ( pIf );
373 else
374 non_if_data.ifs.push_back ( pIf );
375 subs_invalid = false;
376 }
377 else if ( e.name == "compilerflag" )
378 {
379 compilerFlags.push_back ( new CompilerFlag ( project, this, e ) );
380 subs_invalid = true;
381 }
382 else if ( e.name == "linkerflag" )
383 {
384 linkerFlags.push_back ( new LinkerFlag ( project, this, e ) );
385 subs_invalid = true;
386 }
387 else if ( e.name == "component" )
388 {
389 stubbedComponents.push_back ( new StubbedComponent ( this, e ) );
390 subs_invalid = false;
391 }
392 else if ( e.name == "property" )
393 {
394 throw InvalidBuildFileException (
395 e.location,
396 "<property> is not a valid sub-element of <module>" );
397 }
398 else if ( e.name == "bootstrap" )
399 {
400 bootstrap = new Bootstrap ( project, this, e );
401 subs_invalid = true;
402 }
403 else if ( e.name == "pch" )
404 {
405 if ( pIf )
406 throw InvalidBuildFileException (
407 e.location,
408 "<pch> is not a valid sub-element of <if>" );
409 if ( pch )
410 throw InvalidBuildFileException (
411 e.location,
412 "Only one <pch> is valid per module" );
413 pch = new PchFile (
414 e, *this, FixSeparator ( path + CSEP + e.value ) );
415 subs_invalid = true;
416 }
417 if ( subs_invalid && e.subElements.size() > 0 )
418 throw InvalidBuildFileException (
419 e.location,
420 "<%s> cannot have sub-elements",
421 e.name.c_str() );
422 for ( size_t i = 0; i < e.subElements.size (); i++ )
423 ProcessXMLSubElement ( *e.subElements[i], subpath, pIf );
424 }
425
426 ModuleType
427 Module::GetModuleType ( const string& location, const XMLAttribute& attribute )
428 {
429 if ( attribute.value == "buildtool" )
430 return BuildTool;
431 if ( attribute.value == "staticlibrary" )
432 return StaticLibrary;
433 if ( attribute.value == "objectlibrary" )
434 return ObjectLibrary;
435 if ( attribute.value == "kernel" )
436 return Kernel;
437 if ( attribute.value == "kernelmodedll" )
438 return KernelModeDLL;
439 if ( attribute.value == "kernelmodedriver" )
440 return KernelModeDriver;
441 if ( attribute.value == "nativedll" )
442 return NativeDLL;
443 if ( attribute.value == "nativecui" )
444 return NativeCUI;
445 if ( attribute.value == "win32dll" )
446 return Win32DLL;
447 if ( attribute.value == "win32cui" )
448 return Win32CUI;
449 if ( attribute.value == "win32gui" )
450 return Win32GUI;
451 if ( attribute.value == "bootloader" )
452 return BootLoader;
453 if ( attribute.value == "bootsector" )
454 return BootSector;
455 if ( attribute.value == "iso" )
456 return Iso;
457 if ( attribute.value == "test" )
458 return Test;
459 if ( attribute.value == "rpcserver" )
460 return RpcServer;
461 if ( attribute.value == "rpcclient" )
462 return RpcClient;
463 throw InvalidAttributeValueException ( location,
464 attribute.name,
465 attribute.value );
466 }
467
468 string
469 Module::GetDefaultModuleExtension () const
470 {
471 switch (type)
472 {
473 case BuildTool:
474 return EXEPOSTFIX;
475 case StaticLibrary:
476 return ".a";
477 case ObjectLibrary:
478 return ".o";
479 case Kernel:
480 case NativeCUI:
481 case Win32CUI:
482 case Win32GUI:
483 return ".exe";
484 case KernelModeDLL:
485 case NativeDLL:
486 case Win32DLL:
487 return ".dll";
488 case KernelModeDriver:
489 case BootLoader:
490 return ".sys";
491 case BootSector:
492 return ".o";
493 case Iso:
494 return ".iso";
495 case Test:
496 return ".exe";
497 case RpcServer:
498 return ".o";
499 case RpcClient:
500 return ".o";
501 }
502 throw InvalidOperationException ( __FILE__,
503 __LINE__ );
504 }
505
506 string
507 Module::GetDefaultModuleEntrypoint () const
508 {
509 switch (type)
510 {
511 case Kernel:
512 return "_NtProcessStartup";
513 case KernelModeDLL:
514 return "_DriverEntry@8";
515 case NativeDLL:
516 return "_DllMainCRTStartup@12";
517 case NativeCUI:
518 return "_NtProcessStartup@4";
519 case Win32DLL:
520 return "_DllMain@12";
521 case Win32CUI:
522 case Test:
523 return "_mainCRTStartup";
524 case Win32GUI:
525 return "_WinMainCRTStartup";
526 case KernelModeDriver:
527 return "_DriverEntry@8";
528 case BuildTool:
529 case StaticLibrary:
530 case ObjectLibrary:
531 case BootLoader:
532 case BootSector:
533 case Iso:
534 case RpcServer:
535 case RpcClient:
536 return "";
537 }
538 throw InvalidOperationException ( __FILE__,
539 __LINE__ );
540 }
541
542 string
543 Module::GetDefaultModuleBaseaddress () const
544 {
545 switch (type)
546 {
547 case Kernel:
548 return "0xc0000000";
549 case KernelModeDLL:
550 return "0x10000";
551 case NativeDLL:
552 return "0x10000";
553 case NativeCUI:
554 return "0x10000";
555 case Win32DLL:
556 return "0x10000";
557 case Win32CUI:
558 case Test:
559 return "0x00400000";
560 case Win32GUI:
561 return "0x00400000";
562 case KernelModeDriver:
563 return "0x10000";
564 case BuildTool:
565 case StaticLibrary:
566 case ObjectLibrary:
567 case BootLoader:
568 case BootSector:
569 case Iso:
570 case RpcServer:
571 case RpcClient:
572 return "";
573 }
574 throw InvalidOperationException ( __FILE__,
575 __LINE__ );
576 }
577
578 bool
579 Module::HasImportLibrary () const
580 {
581 return importLibrary != NULL;
582 }
583
584 string
585 Module::GetTargetName () const
586 {
587 return name + extension;
588 }
589
590 string
591 Module::GetDependencyPath () const
592 {
593 if ( HasImportLibrary () )
594 {
595 return ReplaceExtension ( GetPath(), ".a" );
596 }
597 else
598 return GetPath();
599 }
600
601 string
602 Module::GetBasePath () const
603 {
604 return path;
605 }
606
607 string
608 Module::GetPath () const
609 {
610 if ( path.length() > 0 )
611 return path + CSEP + GetTargetName ();
612 else
613 return GetTargetName ();
614 }
615
616 string
617 Module::GetPathWithPrefix ( const string& prefix ) const
618 {
619 return path + CSEP + prefix + GetTargetName ();
620 }
621
622 string
623 Module::GetInvocationTarget ( const int index ) const
624 {
625 return ssprintf ( "%s_invoke_%d",
626 name.c_str (),
627 index );
628 }
629
630 bool
631 Module::HasFileWithExtension (
632 const IfableData& data,
633 const std::string& extension ) const
634 {
635 size_t i;
636 for ( i = 0; i < data.files.size (); i++ )
637 {
638 File& file = *data.files[i];
639 string file_ext = GetExtension ( file.name );
640 if ( !stricmp ( file_ext.c_str (), extension.c_str () ) )
641 return true;
642 }
643 for ( i = 0; i < data.ifs.size (); i++ )
644 {
645 if ( HasFileWithExtension ( data.ifs[i]->data, extension ) )
646 return true;
647 }
648 return false;
649 }
650
651 void
652 Module::InvokeModule () const
653 {
654 for ( size_t i = 0; i < invocations.size (); i++ )
655 {
656 Invoke& invoke = *invocations[i];
657 string command = invoke.invokeModule->GetPath () + " " + invoke.GetParameters ();
658 printf ( "Executing '%s'\n\n", command.c_str () );
659 int exitcode = system ( command.c_str () );
660 if ( exitcode != 0 )
661 throw InvocationFailedException ( command,
662 exitcode );
663 }
664 }
665
666
667 File::File ( const string& _name, bool _first )
668 : name(_name), first(_first)
669 {
670 }
671
672 void
673 File::ProcessXML()
674 {
675 }
676
677
678 Library::Library ( const XMLElement& _node,
679 const Module& _module,
680 const string& _name )
681 : node(_node),
682 module(_module),
683 name(_name),
684 imported_module(_module.project.LocateModule(_name))
685 {
686 if ( module.name == name )
687 throw InvalidBuildFileException (
688 node.location,
689 "module '%s' cannot link against itself",
690 name.c_str() );
691 if ( !imported_module )
692 throw InvalidBuildFileException (
693 node.location,
694 "module '%s' trying to import non-existant module '%s'",
695 module.name.c_str(),
696 name.c_str() );
697 }
698
699 void
700 Library::ProcessXML()
701 {
702 if ( !module.project.LocateModule ( name ) )
703 throw InvalidBuildFileException (
704 node.location,
705 "module '%s' is trying to link against non-existant module '%s'",
706 module.name.c_str(),
707 name.c_str() );
708 }
709
710
711 Invoke::Invoke ( const XMLElement& _node,
712 const Module& _module )
713 : node (_node),
714 module (_module)
715 {
716 }
717
718 void
719 Invoke::ProcessXML()
720 {
721 const XMLAttribute* att = node.GetAttribute ( "module", false );
722 if (att == NULL)
723 invokeModule = &module;
724 else
725 {
726 invokeModule = module.project.LocateModule ( att->value );
727 if ( invokeModule == NULL )
728 throw InvalidBuildFileException (
729 node.location,
730 "module '%s' is trying to invoke non-existant module '%s'",
731 module.name.c_str(),
732 att->value.c_str() );
733 }
734
735 for ( size_t i = 0; i < node.subElements.size (); i++ )
736 ProcessXMLSubElement ( *node.subElements[i] );
737 }
738
739 void
740 Invoke::ProcessXMLSubElement ( const XMLElement& e )
741 {
742 bool subs_invalid = false;
743 if ( e.name == "input" )
744 {
745 for ( size_t i = 0; i < e.subElements.size (); i++ )
746 ProcessXMLSubElementInput ( *e.subElements[i] );
747 }
748 else if ( e.name == "output" )
749 {
750 for ( size_t i = 0; i < e.subElements.size (); i++ )
751 ProcessXMLSubElementOutput ( *e.subElements[i] );
752 }
753 if ( subs_invalid && e.subElements.size() > 0 )
754 throw InvalidBuildFileException ( e.location,
755 "<%s> cannot have sub-elements",
756 e.name.c_str() );
757 }
758
759 void
760 Invoke::ProcessXMLSubElementInput ( const XMLElement& e )
761 {
762 bool subs_invalid = false;
763 if ( e.name == "inputfile" && e.value.size () > 0 )
764 {
765 input.push_back ( new InvokeFile ( e, FixSeparator ( module.path + CSEP + e.value ) ) );
766 subs_invalid = true;
767 }
768 if ( subs_invalid && e.subElements.size() > 0 )
769 throw InvalidBuildFileException ( e.location,
770 "<%s> cannot have sub-elements",
771 e.name.c_str() );
772 }
773
774 void
775 Invoke::ProcessXMLSubElementOutput ( const XMLElement& e )
776 {
777 bool subs_invalid = false;
778 if ( e.name == "outputfile" && e.value.size () > 0 )
779 {
780 output.push_back ( new InvokeFile ( e, FixSeparator ( module.path + CSEP + e.value ) ) );
781 subs_invalid = true;
782 }
783 if ( subs_invalid && e.subElements.size() > 0 )
784 throw InvalidBuildFileException (
785 e.location,
786 "<%s> cannot have sub-elements",
787 e.name.c_str() );
788 }
789
790 void
791 Invoke::GetTargets ( string_list& targets ) const
792 {
793 for ( size_t i = 0; i < output.size (); i++ )
794 {
795 InvokeFile& file = *output[i];
796 targets.push_back ( NormalizeFilename ( file.name ) );
797 }
798 }
799
800 string
801 Invoke::GetParameters () const
802 {
803 string parameters ( "" );
804 size_t i;
805 for ( i = 0; i < output.size (); i++ )
806 {
807 if ( parameters.length () > 0)
808 parameters += " ";
809 InvokeFile& invokeFile = *output[i];
810 if ( invokeFile.switches.length () > 0 )
811 {
812 parameters += invokeFile.switches + " ";
813 }
814 parameters += invokeFile.name;
815 }
816
817 for ( i = 0; i < input.size (); i++ )
818 {
819 if ( parameters.length () > 0 )
820 parameters += " ";
821 InvokeFile& invokeFile = *input[i];
822 if ( invokeFile.switches.length () > 0 )
823 {
824 parameters += invokeFile.switches;
825 parameters += " ";
826 }
827 parameters += invokeFile.name ;
828 }
829
830 return parameters;
831 }
832
833
834 InvokeFile::InvokeFile ( const XMLElement& _node,
835 const string& _name )
836 : node (_node),
837 name (_name)
838 {
839 const XMLAttribute* att = _node.GetAttribute ( "switches", false );
840 if (att != NULL)
841 switches = att->value;
842 else
843 switches = "";
844 }
845
846 void
847 InvokeFile::ProcessXML()
848 {
849 }
850
851
852 Dependency::Dependency ( const XMLElement& _node,
853 const Module& _module )
854 : node (_node),
855 module (_module),
856 dependencyModule (NULL)
857 {
858 }
859
860 void
861 Dependency::ProcessXML()
862 {
863 dependencyModule = module.project.LocateModule ( node.value );
864 if ( dependencyModule == NULL )
865 throw InvalidBuildFileException ( node.location,
866 "module '%s' depend on non-existant module '%s'",
867 module.name.c_str(),
868 node.value.c_str() );
869 }
870
871
872 ImportLibrary::ImportLibrary ( const XMLElement& _node,
873 const Module& _module )
874 : node (_node),
875 module (_module)
876 {
877 const XMLAttribute* att = _node.GetAttribute ( "basename", false );
878 if (att != NULL)
879 basename = att->value;
880 else
881 basename = module.name;
882
883 att = _node.GetAttribute ( "definition", true );
884 assert (att);
885 definition = FixSeparator(att->value);
886 }
887
888
889 If::If ( const XMLElement& node_,
890 const Project& project_,
891 const Module* module_ )
892 : node(node_), project(project_), module(module_)
893 {
894 const XMLAttribute* att;
895
896 att = node.GetAttribute ( "property", true );
897 assert(att);
898 property = att->value;
899
900 att = node.GetAttribute ( "value", true );
901 assert(att);
902 value = att->value;
903 }
904
905 If::~If ()
906 {
907 }
908
909 void
910 If::ProcessXML()
911 {
912 }
913
914
915 Property::Property ( const XMLElement& node_,
916 const Project& project_,
917 const Module* module_ )
918 : node(node_), project(project_), module(module_)
919 {
920 const XMLAttribute* att;
921
922 att = node.GetAttribute ( "name", true );
923 assert(att);
924 name = att->value;
925
926 att = node.GetAttribute ( "value", true );
927 assert(att);
928 value = att->value;
929 }
930
931 void
932 Property::ProcessXML()
933 {
934 }
935
936
937 PchFile::PchFile (
938 const XMLElement& node_,
939 const Module& module_,
940 const string& header_ )
941 : node(node_), module(module_), header(header_)
942 {
943 }
944
945 void
946 PchFile::ProcessXML()
947 {
948 }