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