Added freeldr and hal from PPC branch, along with needed headers and
[reactos.git] / reactos / tools / rbuild / module.cpp
1 /*
2 * Copyright (C) 2005 Casper S. Hornstrup
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18 #include "pch.h"
19 #include <assert.h>
20
21 #include "rbuild.h"
22
23 using std::string;
24 using std::vector;
25
26 string
27 Right ( const string& s, size_t n )
28 {
29 if ( n > s.size() )
30 return s;
31 return string ( &s[s.size()-n] );
32 }
33
34 string
35 Replace ( const string& s, const string& find, const string& with )
36 {
37 string ret;
38 const char* p = s.c_str();
39 while ( p )
40 {
41 const char* p2 = strstr ( p, find.c_str() );
42 if ( !p2 )
43 break;
44 if ( p2 > p )
45 ret += string ( p, p2-p );
46 ret += with;
47 p = p2 + find.size();
48 }
49 if ( *p )
50 ret += p;
51 return ret;
52 }
53
54 string
55 ChangeSeparator ( const string& s,
56 const char fromSeparator,
57 const char toSeparator )
58 {
59 string s2(s);
60 char* p = strchr ( &s2[0], fromSeparator );
61 while ( p )
62 {
63 *p++ = toSeparator;
64 p = strchr ( p, fromSeparator );
65 }
66 return s2;
67 }
68
69 string
70 FixSeparator ( const string& s )
71 {
72 return ChangeSeparator ( s, cBadSep, cSep );
73 }
74
75 string
76 FixSeparatorForSystemCommand ( const string& s )
77 {
78 string s2(s);
79 char* p = strchr ( &s2[0], DEF_CBAD_SEP );
80 while ( p )
81 {
82 *p++ = DEF_CSEP;
83 p = strchr ( p, DEF_CBAD_SEP );
84 }
85 return s2;
86 }
87
88 string
89 DosSeparator ( const string& s )
90 {
91 string s2(s);
92 char* p = strchr ( &s2[0], '/' );
93 while ( p )
94 {
95 *p++ = '\\';
96 p = strchr ( p, '/' );
97 }
98 return s2;
99 }
100
101 string
102 ReplaceExtension (
103 const string& filename,
104 const string& newExtension )
105 {
106 size_t index = filename.find_last_of ( '/' );
107 if ( index == string::npos )
108 index = 0;
109 size_t index2 = filename.find_last_of ( '\\' );
110 if ( index2 != string::npos && index2 > index )
111 index = index2;
112 string tmp = filename.substr( index /*, filename.size() - index*/ );
113 size_t ext_index = tmp.find_last_of( '.' );
114 if ( ext_index != string::npos )
115 return filename.substr ( 0, index + ext_index ) + newExtension;
116 return filename + newExtension;
117 }
118
119 string
120 GetSubPath (
121 const Project& project,
122 const string& location,
123 const string& path,
124 const string& att_value )
125 {
126 if ( !att_value.size() )
127 throw XMLInvalidBuildFileException (
128 location,
129 "<directory> tag has empty 'name' attribute" );
130 if ( strpbrk ( att_value.c_str (), "/\\?*:<>|" ) )
131 throw XMLInvalidBuildFileException (
132 location,
133 "<directory> tag has invalid characters in 'name' attribute" );
134 if ( !path.size() )
135 return att_value;
136
137 return FixSeparator(path + cSep + att_value);
138 }
139
140 string
141 GetExtension ( const string& filename )
142 {
143 size_t index = filename.find_last_of ( '/' );
144 if (index == string::npos) index = 0;
145 string tmp = filename.substr( index, filename.size() - index );
146 size_t ext_index = tmp.find_last_of( '.' );
147 if (ext_index != string::npos)
148 return filename.substr ( index + ext_index, filename.size() );
149 return "";
150 }
151
152 string
153 GetDirectory ( const string& filename )
154 {
155 size_t index = filename.find_last_of ( cSep );
156 if ( index == string::npos )
157 return "";
158 else
159 return filename.substr ( 0, index );
160 }
161
162 string
163 GetFilename ( const string& filename )
164 {
165 size_t index = filename.find_last_of ( cSep );
166 if ( index == string::npos )
167 return filename;
168 else
169 return filename.substr ( index + 1, filename.length () - index );
170 }
171
172 string
173 NormalizeFilename ( const string& filename )
174 {
175 if ( filename == "" )
176 return "";
177 Path path;
178 string normalizedPath = path.Fixup ( filename, true );
179 string relativeNormalizedPath = path.RelativeFromWorkingDirectory ( normalizedPath );
180 return FixSeparator ( relativeNormalizedPath );
181 }
182
183 bool
184 GetBooleanValue ( const string& value )
185 {
186 if ( value == "1" )
187 return true;
188 else
189 return false;
190 }
191
192 string
193 ToLower ( string filename )
194 {
195 for ( size_t i = 1; i < filename.length (); i++ )
196 filename[i] = tolower ( filename[i] );
197 return filename;
198 }
199
200 void IfableData::ExtractModules( std::vector<Module*> &modules )
201 {
202 size_t i;
203 for ( i = 0; i < this->modules.size (); i++ )
204 modules.push_back(this->modules[i]);
205 }
206
207 IfableData::~IfableData()
208 {
209 size_t i;
210 for ( i = 0; i < includes.size (); i++ )
211 delete includes[i];
212 for ( i = 0; i < defines.size (); i++ )
213 delete defines[i];
214 for ( i = 0; i < libraries.size (); i++ )
215 delete libraries[i];
216 for ( i = 0; i < properties.size (); i++ )
217 delete properties[i];
218 for ( i = 0; i < compilerFlags.size (); i++ )
219 delete compilerFlags[i];
220 for ( i = 0; i < modules.size(); i++ )
221 delete modules[i];
222 for ( i = 0; i < ifs.size (); i++ )
223 delete ifs[i];
224 for ( i = 0; i < compilationUnits.size (); i++ )
225 delete compilationUnits[i];
226 }
227
228 void IfableData::ProcessXML ()
229 {
230 size_t i;
231 for ( i = 0; i < includes.size (); i++ )
232 includes[i]->ProcessXML ();
233 for ( i = 0; i < defines.size (); i++ )
234 defines[i]->ProcessXML ();
235 for ( i = 0; i < libraries.size (); i++ )
236 libraries[i]->ProcessXML ();
237 for ( i = 0; i < properties.size(); i++ )
238 properties[i]->ProcessXML ();
239 for ( i = 0; i < compilerFlags.size(); i++ )
240 compilerFlags[i]->ProcessXML ();
241 for ( i = 0; i < ifs.size (); i++ )
242 ifs[i]->ProcessXML ();
243 for ( i = 0; i < compilationUnits.size (); i++ )
244 compilationUnits[i]->ProcessXML ();
245 }
246
247 Module::Module ( const Project& project,
248 const XMLElement& moduleNode,
249 const string& modulePath )
250 : project (project),
251 node (moduleNode),
252 importLibrary (NULL),
253 metadata (NULL),
254 bootstrap (NULL),
255 autoRegister(NULL),
256 linkerScript (NULL),
257 pch (NULL),
258 cplusplus (false),
259 host (HostDefault)
260 {
261 if ( node.name != "module" )
262 throw InvalidOperationException ( __FILE__,
263 __LINE__,
264 "Module created with non-<module> node" );
265
266 xmlbuildFile = Path::RelativeFromWorkingDirectory ( moduleNode.xmlFile->filename () );
267
268 path = FixSeparator ( modulePath );
269
270 enabled = true;
271
272 const XMLAttribute* att = moduleNode.GetAttribute ( "if", false );
273 if ( att != NULL )
274 enabled = GetBooleanValue ( project.ResolveProperties ( att->value ) );
275
276 att = moduleNode.GetAttribute ( "ifnot", false );
277 if ( att != NULL )
278 enabled = !GetBooleanValue ( project.ResolveProperties ( att->value ) );
279
280 att = moduleNode.GetAttribute ( "name", true );
281 assert(att);
282 name = att->value;
283
284 att = moduleNode.GetAttribute ( "type", true );
285 assert(att);
286 type = GetModuleType ( node.location, *att );
287
288 att = moduleNode.GetAttribute ( "extension", false );
289 if ( att != NULL )
290 extension = att->value;
291 else
292 extension = GetDefaultModuleExtension ();
293
294 att = moduleNode.GetAttribute ( "unicode", false );
295 if ( att != NULL )
296 {
297 const char* p = att->value.c_str();
298 if ( !stricmp ( p, "true" ) || !stricmp ( p, "yes" ) )
299 isUnicode = true;
300 else if ( !stricmp ( p, "false" ) || !stricmp ( p, "no" ) )
301 isUnicode = false;
302 else
303 {
304 throw InvalidAttributeValueException (
305 moduleNode.location,
306 "unicode",
307 att->value );
308 }
309 }
310 else
311 isUnicode = false;
312
313 att = moduleNode.GetAttribute ( "stdlib", false );
314 if ( att != NULL )
315 {
316 const char* p = att->value.c_str();
317 if ( !stricmp ( p, "host" ) )
318 useHostStdlib = true;
319 else if ( !stricmp ( p, "default" ) )
320 useHostStdlib = false;
321 else
322 {
323 throw InvalidAttributeValueException (
324 moduleNode.location,
325 "stdlib",
326 att->value );
327 }
328 }
329 else
330 useHostStdlib = false;
331
332 if (isUnicode)
333 {
334 // Always define UNICODE and _UNICODE
335 Define* pDefine = new Define ( project, this, "UNICODE" );
336 non_if_data.defines.push_back ( pDefine );
337
338 pDefine = new Define ( project, this, "_UNICODE" );
339 non_if_data.defines.push_back ( pDefine );
340 }
341
342 att = moduleNode.GetAttribute ( "entrypoint", false );
343 if ( att != NULL )
344 {
345 if ( att->value == "" )
346 {
347 throw InvalidAttributeValueException (
348 moduleNode.location,
349 "entrypoint",
350 att->value );
351 }
352
353 entrypoint = att->value;
354 isDefaultEntryPoint = false;
355 }
356 else
357 {
358 entrypoint = GetDefaultModuleEntrypoint ();
359 isDefaultEntryPoint = true;
360 }
361
362 att = moduleNode.GetAttribute ( "baseaddress", false );
363 if ( att != NULL )
364 baseaddress = att->value;
365 else
366 baseaddress = GetDefaultModuleBaseaddress ();
367
368 att = moduleNode.GetAttribute ( "mangledsymbols", false );
369 if ( att != NULL )
370 {
371 const char* p = att->value.c_str();
372 if ( !stricmp ( p, "true" ) || !stricmp ( p, "yes" ) )
373 mangledSymbols = true;
374 else if ( !stricmp ( p, "false" ) || !stricmp ( p, "no" ) )
375 mangledSymbols = false;
376 else
377 {
378 throw InvalidAttributeValueException (
379 moduleNode.location,
380 "mangledsymbols",
381 att->value );
382 }
383 }
384 else
385 mangledSymbols = false;
386
387 att = moduleNode.GetAttribute ( "underscoresymbols", false );
388 if ( att != NULL )
389 underscoreSymbols = att->value == "true";
390 else
391 underscoreSymbols = false;
392
393 att = moduleNode.GetAttribute ( "host", false );
394 if ( att != NULL )
395 {
396 const char* p = att->value.c_str();
397 if ( !stricmp ( p, "true" ) || !stricmp ( p, "yes" ) )
398 host = HostTrue;
399 else if ( !stricmp ( p, "false" ) || !stricmp ( p, "no" ) )
400 host = HostFalse;
401 else
402 {
403 throw InvalidAttributeValueException (
404 moduleNode.location,
405 "host",
406 att->value );
407 }
408 }
409
410 att = moduleNode.GetAttribute ( "isstartuplib", false );
411 if ( att != NULL )
412 {
413 const char* p = att->value.c_str();
414 if ( !stricmp ( p, "true" ) || !stricmp ( p, "yes" ) )
415 isStartupLib = true;
416 else if ( !stricmp ( p, "false" ) || !stricmp ( p, "no" ) )
417 isStartupLib = false;
418 else
419 {
420 throw InvalidAttributeValueException (
421 moduleNode.location,
422 "host",
423 att->value );
424 }
425 }
426 else
427 isStartupLib = false;
428
429 att = moduleNode.GetAttribute ( "prefix", false );
430 if ( att != NULL )
431 prefix = att->value;
432
433 att = moduleNode.GetAttribute ( "installbase", false );
434 if ( att != NULL )
435 installBase = att->value;
436 else
437 installBase = "";
438
439 att = moduleNode.GetAttribute ( "installname", false );
440 if ( att != NULL )
441 installName = att->value;
442 else
443 installName = "";
444
445 att = moduleNode.GetAttribute ( "usewrc", false );
446 if ( att != NULL )
447 useWRC = att->value == "true";
448 else
449 useWRC = true;
450
451 att = moduleNode.GetAttribute ( "allowwarnings", false );
452 if ( att == NULL )
453 {
454 att = moduleNode.GetAttribute ( "warnings", false );
455 if ( att != NULL )
456 {
457 printf ( "%s: WARNING: 'warnings' attribute of <module> is deprecated, use 'allowwarnings' instead\n",
458 moduleNode.location.c_str() );
459 }
460 }
461 if ( att != NULL )
462 allowWarnings = att->value == "true";
463 else
464 allowWarnings = false;
465
466 att = moduleNode.GetAttribute ( "aliasof", false );
467 if ( type == Alias && att != NULL )
468 aliasedModuleName = att->value;
469 else
470 aliasedModuleName = "";
471
472 if ( type == BootProgram )
473 {
474 att = moduleNode.GetAttribute ( "payload", true );
475 payload = att->value;
476 }
477
478 if ( type == BootProgram || type == ElfExecutable )
479 {
480 att = moduleNode.GetAttribute ( "buildtype", false );
481 if ( att != NULL )
482 {
483 buildtype = att->value;
484 }
485 else
486 {
487 buildtype = "BOOTPROG";
488 }
489 }
490 }
491
492 Module::~Module ()
493 {
494 size_t i;
495 for ( i = 0; i < invocations.size(); i++ )
496 delete invocations[i];
497 for ( i = 0; i < dependencies.size(); i++ )
498 delete dependencies[i];
499 for ( i = 0; i < compilerFlags.size(); i++ )
500 delete compilerFlags[i];
501 for ( i = 0; i < linkerFlags.size(); i++ )
502 delete linkerFlags[i];
503 for ( i = 0; i < stubbedComponents.size(); i++ )
504 delete stubbedComponents[i];
505 if ( linkerScript )
506 delete linkerScript;
507 if ( pch )
508 delete pch;
509 }
510
511 void
512 Module::ProcessXML()
513 {
514 if ( type == Alias )
515 {
516 if ( aliasedModuleName == name )
517 {
518 throw XMLInvalidBuildFileException (
519 node.location,
520 "module '%s' cannot link against itself",
521 name.c_str() );
522 }
523 const Module* m = project.LocateModule ( aliasedModuleName );
524 if ( !m )
525 {
526 throw XMLInvalidBuildFileException (
527 node.location,
528 "module '%s' trying to alias non-existant module '%s'",
529 name.c_str(),
530 aliasedModuleName.c_str() );
531 }
532 }
533
534 size_t i;
535 for ( i = 0; i < node.subElements.size(); i++ )
536 {
537 ParseContext parseContext;
538 ProcessXMLSubElement ( *node.subElements[i], path, "", parseContext );
539 }
540 for ( i = 0; i < invocations.size(); i++ )
541 invocations[i]->ProcessXML ();
542 for ( i = 0; i < dependencies.size(); i++ )
543 dependencies[i]->ProcessXML ();
544 for ( i = 0; i < compilerFlags.size(); i++ )
545 compilerFlags[i]->ProcessXML();
546 for ( i = 0; i < linkerFlags.size(); i++ )
547 linkerFlags[i]->ProcessXML();
548 for ( i = 0; i < stubbedComponents.size(); i++ )
549 stubbedComponents[i]->ProcessXML();
550 non_if_data.ProcessXML();
551 if ( linkerScript )
552 linkerScript->ProcessXML();
553 if ( pch )
554 pch->ProcessXML();
555 if ( autoRegister )
556 autoRegister->ProcessXML();
557 }
558
559 void
560 Module::ProcessXMLSubElement ( const XMLElement& e,
561 const string& path,
562 const string& path_prefix,
563 ParseContext& parseContext )
564 {
565 If* pOldIf = parseContext.ifData;
566 CompilationUnit* pOldCompilationUnit = parseContext.compilationUnit;
567 bool subs_invalid = false;
568 string subpath ( path );
569 string subpath_prefix ( "" );
570 if ( e.name == "file" && e.value.size () > 0 )
571 {
572 bool first = false;
573 const XMLAttribute* att = e.GetAttribute ( "first", false );
574 if ( att != NULL )
575 {
576 if ( !stricmp ( att->value.c_str(), "true" ) )
577 first = true;
578 else if ( stricmp ( att->value.c_str(), "false" ) )
579 {
580 throw XMLInvalidBuildFileException (
581 e.location,
582 "attribute 'first' of <file> element can only be 'true' or 'false'" );
583 }
584 }
585 string switches = "";
586 att = e.GetAttribute ( "switches", false );
587 if ( att != NULL )
588 switches = att->value;
589 if ( !cplusplus )
590 {
591 // check for c++ file
592 string ext = GetExtension ( e.value );
593 if ( !stricmp ( ext.c_str(), ".cpp" ) )
594 cplusplus = true;
595 else if ( !stricmp ( ext.c_str(), ".cc" ) )
596 cplusplus = true;
597 else if ( !stricmp ( ext.c_str(), ".cxx" ) )
598 cplusplus = true;
599 }
600 File* pFile = new File ( FixSeparator ( path + cSep + e.value ),
601 path_prefix,
602 first,
603 switches,
604 false );
605 if ( parseContext.compilationUnit )
606 parseContext.compilationUnit->files.push_back ( pFile );
607 else
608 {
609 CompilationUnit* pCompilationUnit = new CompilationUnit ( pFile );
610 if ( parseContext.ifData )
611 parseContext.ifData->data.compilationUnits.push_back ( pCompilationUnit );
612 else
613 {
614 string ext = GetExtension ( e.value );
615 if ( !stricmp ( ext.c_str(), ".idl" ) )
616 non_if_data.compilationUnits.insert ( non_if_data.compilationUnits.begin(), pCompilationUnit );
617 else
618 non_if_data.compilationUnits.push_back ( pCompilationUnit );
619 }
620 }
621 if ( parseContext.ifData )
622 parseContext.ifData->data.files.push_back ( pFile );
623 else
624 non_if_data.files.push_back ( pFile );
625 subs_invalid = true;
626 }
627 else if ( e.name == "library" && e.value.size () )
628 {
629 Library* pLibrary = new Library ( e, *this, e.value );
630 if ( parseContext.ifData )
631 parseContext.ifData->data.libraries.push_back ( pLibrary );
632 else
633 non_if_data.libraries.push_back ( pLibrary );
634 subs_invalid = true;
635 }
636 else if ( e.name == "directory" )
637 {
638 const XMLAttribute* att = e.GetAttribute ( "name", true );
639 const XMLAttribute* root = e.GetAttribute ( "root", false );
640 assert(att);
641 if ( root )
642 {
643 if ( root->value == "intermediate" )
644 subpath_prefix = "$(INTERMEDIATE)";
645 else if ( root->value == "output" )
646 subpath_prefix = "$(OUTPUT)";
647 else
648 {
649 throw InvalidAttributeValueException (
650 e.location,
651 "root",
652 root->value );
653 }
654 }
655 subpath = GetSubPath ( this->project, e.location, path, att->value );
656 }
657 else if ( e.name == "include" )
658 {
659 Include* include = new Include ( project, this, &e );
660 if ( parseContext.ifData )
661 parseContext.ifData->data.includes.push_back ( include );
662 else
663 non_if_data.includes.push_back ( include );
664 subs_invalid = true;
665 }
666 else if ( e.name == "define" )
667 {
668 Define* pDefine = new Define ( project, this, e );
669 if ( parseContext.ifData )
670 parseContext.ifData->data.defines.push_back ( pDefine );
671 else
672 non_if_data.defines.push_back ( pDefine );
673 subs_invalid = true;
674 }
675 else if ( e.name == "metadata" )
676 {
677 if ( parseContext.ifData )
678 {
679 throw XMLInvalidBuildFileException (
680 e.location,
681 "<metadata> is not a valid sub-element of <if>" );
682 }
683 metadata = new Metadata ( e, *this );
684 subs_invalid = false;
685 }
686 else if ( e.name == "invoke" )
687 {
688 if ( parseContext.ifData )
689 {
690 throw XMLInvalidBuildFileException (
691 e.location,
692 "<invoke> is not a valid sub-element of <if>" );
693 }
694 invocations.push_back ( new Invoke ( e, *this ) );
695 subs_invalid = false;
696 }
697 else if ( e.name == "dependency" )
698 {
699 if ( parseContext.ifData )
700 {
701 throw XMLInvalidBuildFileException (
702 e.location,
703 "<dependency> is not a valid sub-element of <if>" );
704 }
705 dependencies.push_back ( new Dependency ( e, *this ) );
706 subs_invalid = true;
707 }
708 else if ( e.name == "importlibrary" )
709 {
710 if ( parseContext.ifData )
711 {
712 throw XMLInvalidBuildFileException (
713 e.location,
714 "<importlibrary> is not a valid sub-element of <if>" );
715 }
716 if ( importLibrary )
717 {
718 throw XMLInvalidBuildFileException (
719 e.location,
720 "Only one <importlibrary> is valid per module" );
721 }
722 importLibrary = new ImportLibrary ( e, *this );
723 subs_invalid = true;
724 }
725 else if ( e.name == "if" )
726 {
727 parseContext.ifData = new If ( e, project, this );
728 if ( pOldIf )
729 pOldIf->data.ifs.push_back ( parseContext.ifData );
730 else
731 non_if_data.ifs.push_back ( parseContext.ifData );
732 subs_invalid = false;
733 }
734 else if ( e.name == "ifnot" )
735 {
736 parseContext.ifData = new If ( e, project, this, true );
737 if ( pOldIf )
738 pOldIf->data.ifs.push_back ( parseContext.ifData );
739 else
740 non_if_data.ifs.push_back ( parseContext.ifData );
741 subs_invalid = false;
742 }
743 else if ( e.name == "compilerflag" )
744 {
745 CompilerFlag* pCompilerFlag = new CompilerFlag ( project, this, e );
746 if ( parseContext.ifData )
747 parseContext.ifData->data.compilerFlags.push_back ( pCompilerFlag );
748 else
749 non_if_data.compilerFlags.push_back ( pCompilerFlag );
750 subs_invalid = true;
751 }
752 else if ( e.name == "linkerflag" )
753 {
754 linkerFlags.push_back ( new LinkerFlag ( project, this, e ) );
755 subs_invalid = true;
756 }
757 else if ( e.name == "linkerscript" )
758 {
759 if ( linkerScript )
760 {
761 throw XMLInvalidBuildFileException (
762 e.location,
763 "Only one <linkerscript> is valid per module" );
764 }
765 linkerScript = new LinkerScript ( project, this, e );
766 subs_invalid = true;
767 }
768 else if ( e.name == "component" )
769 {
770 stubbedComponents.push_back ( new StubbedComponent ( this, e ) );
771 subs_invalid = false;
772 }
773 else if ( e.name == "property" )
774 {
775 throw XMLInvalidBuildFileException (
776 e.location,
777 "<property> is not a valid sub-element of <module>" );
778 }
779 else if ( e.name == "bootstrap" )
780 {
781 bootstrap = new Bootstrap ( project, this, e );
782 subs_invalid = true;
783 }
784 else if ( e.name == "pch" )
785 {
786 if ( parseContext.ifData )
787 {
788 throw XMLInvalidBuildFileException (
789 e.location,
790 "<pch> is not a valid sub-element of <if>" );
791 }
792 if ( pch )
793 {
794 throw XMLInvalidBuildFileException (
795 e.location,
796 "Only one <pch> is valid per module" );
797 }
798 pch = new PchFile (
799 e, *this, File ( FixSeparator ( path + cSep + e.value ), false, "", true ) );
800 subs_invalid = true;
801 }
802 else if ( e.name == "compilationunit" )
803 {
804 if ( project.configuration.CompilationUnitsEnabled )
805 {
806 CompilationUnit* pCompilationUnit = new CompilationUnit ( &project, this, &e );
807 if ( parseContext.ifData )
808 parseContext.ifData->data.compilationUnits.push_back ( pCompilationUnit );
809 else
810 non_if_data.compilationUnits.push_back ( pCompilationUnit );
811 parseContext.compilationUnit = pCompilationUnit;
812 }
813 subs_invalid = false;
814 }
815 else if ( e.name == "autoregister" )
816 {
817 if ( autoRegister != NULL)
818 {
819 throw XMLInvalidBuildFileException (
820 e.location,
821 "there can be only one <%s> element for a module",
822 e.name.c_str() );
823 }
824 autoRegister = new AutoRegister ( project, this, e );
825 subs_invalid = true;
826 }
827 if ( subs_invalid && e.subElements.size() > 0 )
828 {
829 throw XMLInvalidBuildFileException (
830 e.location,
831 "<%s> cannot have sub-elements",
832 e.name.c_str() );
833 }
834 for ( size_t i = 0; i < e.subElements.size (); i++ )
835 ProcessXMLSubElement ( *e.subElements[i], subpath, subpath_prefix, parseContext );
836 parseContext.ifData = pOldIf;
837 parseContext.compilationUnit = pOldCompilationUnit;
838 }
839
840 ModuleType
841 Module::GetModuleType ( const string& location, const XMLAttribute& attribute )
842 {
843 if ( attribute.value == "buildtool" )
844 return BuildTool;
845 if ( attribute.value == "staticlibrary" )
846 return StaticLibrary;
847 if ( attribute.value == "objectlibrary" )
848 return ObjectLibrary;
849 if ( attribute.value == "kernel" )
850 return Kernel;
851 if ( attribute.value == "kernelmodedll" )
852 return KernelModeDLL;
853 if ( attribute.value == "kernelmodedriver" )
854 return KernelModeDriver;
855 if ( attribute.value == "nativedll" )
856 return NativeDLL;
857 if ( attribute.value == "nativecui" )
858 return NativeCUI;
859 if ( attribute.value == "win32dll" )
860 return Win32DLL;
861 if ( attribute.value == "win32ocx" )
862 return Win32OCX;
863 if ( attribute.value == "win32cui" )
864 return Win32CUI;
865 if ( attribute.value == "win32gui" )
866 return Win32GUI;
867 if ( attribute.value == "win32scr" )
868 return Win32SCR;
869 if ( attribute.value == "bootloader" )
870 return BootLoader;
871 if ( attribute.value == "bootsector" )
872 return BootSector;
873 if ( attribute.value == "bootprogram" )
874 return BootProgram;
875 if ( attribute.value == "iso" )
876 return Iso;
877 if ( attribute.value == "liveiso" )
878 return LiveIso;
879 if ( attribute.value == "isoregtest" )
880 return IsoRegTest;
881 if ( attribute.value == "liveisoregtest" )
882 return LiveIsoRegTest;
883 if ( attribute.value == "test" )
884 return Test;
885 if ( attribute.value == "rpcserver" )
886 return RpcServer;
887 if ( attribute.value == "rpcclient" )
888 return RpcClient;
889 if ( attribute.value == "alias" )
890 return Alias;
891 if ( attribute.value == "idlheader" )
892 return IdlHeader;
893 if ( attribute.value == "embeddedtypelib" )
894 return EmbeddedTypeLib;
895 if ( attribute.value == "elfexecutable" )
896 return ElfExecutable;
897 throw InvalidAttributeValueException ( location,
898 attribute.name,
899 attribute.value );
900 }
901
902 string
903 Module::GetDefaultModuleExtension () const
904 {
905 switch (type)
906 {
907 case BuildTool:
908 return ExePostfix;
909 case BootProgram:
910 case StaticLibrary:
911 return ".a";
912 case ObjectLibrary:
913 return ".o";
914 case Kernel:
915 case NativeCUI:
916 case Win32CUI:
917 case Win32GUI:
918 return ".exe";
919 case Win32SCR:
920 return ".scr";
921
922 case KernelModeDLL:
923 case NativeDLL:
924 case Win32DLL:
925 return ".dll";
926 case Win32OCX:
927 return ".ocx";
928 case KernelModeDriver:
929 case BootLoader:
930 return ".sys";
931 case BootSector:
932 return ".o";
933 case Iso:
934 case LiveIso:
935 case IsoRegTest:
936 case LiveIsoRegTest:
937 return ".iso";
938 case Test:
939 return ".exe";
940 case RpcServer:
941 return ".o";
942 case RpcClient:
943 return ".o";
944 case Alias:
945 case ElfExecutable:
946 case IdlHeader:
947 return "";
948 case EmbeddedTypeLib:
949 return ".tlb";
950 }
951 throw InvalidOperationException ( __FILE__,
952 __LINE__ );
953 }
954
955 string
956 Module::GetDefaultModuleEntrypoint () const
957 {
958 switch ( type )
959 {
960 case Kernel:
961 return "NtProcessStartup";
962 case KernelModeDLL:
963 case KernelModeDriver:
964 return "DriverEntry@8";
965 case NativeDLL:
966 return "DllMainCRTStartup@12";
967 case NativeCUI:
968 return "NtProcessStartup@4";
969 case Win32DLL:
970 case Win32OCX:
971 return "DllMain@12";
972 case Win32CUI:
973 case Test:
974 if ( isUnicode )
975 return "wmainCRTStartup";
976 else
977 return "mainCRTStartup";
978 case Win32SCR:
979 case Win32GUI:
980 if ( isUnicode )
981 return "wWinMainCRTStartup";
982 else
983 return "WinMainCRTStartup";
984 case BuildTool:
985 case StaticLibrary:
986 case ObjectLibrary:
987 case BootLoader:
988 case BootSector:
989 case Iso:
990 case LiveIso:
991 case IsoRegTest:
992 case LiveIsoRegTest:
993 case RpcServer:
994 case RpcClient:
995 case Alias:
996 case BootProgram:
997 case IdlHeader:
998 case ElfExecutable:
999 case EmbeddedTypeLib:
1000 return "";
1001 }
1002 throw InvalidOperationException ( __FILE__,
1003 __LINE__ );
1004 }
1005
1006 string
1007 Module::GetDefaultModuleBaseaddress () const
1008 {
1009 switch ( type )
1010 {
1011 case Kernel:
1012 return "0x80800000";
1013 case Win32DLL:
1014 case Win32OCX:
1015 return "0x10000000";
1016 case NativeDLL:
1017 case NativeCUI:
1018 case Win32CUI:
1019 case Test:
1020 return "0x00400000";
1021 case Win32SCR:
1022 case Win32GUI:
1023 return "0x00400000";
1024 case KernelModeDLL:
1025 case KernelModeDriver:
1026 return "0x00010000";
1027 case ElfExecutable:
1028 return "0xe00000";
1029 case BuildTool:
1030 case StaticLibrary:
1031 case ObjectLibrary:
1032 case BootLoader:
1033 case BootSector:
1034 case Iso:
1035 case LiveIso:
1036 case IsoRegTest:
1037 case LiveIsoRegTest:
1038 case RpcServer:
1039 case RpcClient:
1040 case Alias:
1041 case BootProgram:
1042 case IdlHeader:
1043 case EmbeddedTypeLib:
1044 return "";
1045 }
1046 throw InvalidOperationException ( __FILE__,
1047 __LINE__ );
1048 }
1049
1050 bool
1051 Module::HasImportLibrary () const
1052 {
1053 return importLibrary != NULL && type != StaticLibrary;
1054 }
1055
1056 bool
1057 Module::IsDLL () const
1058 {
1059 switch ( type )
1060 {
1061 case Kernel:
1062 case KernelModeDLL:
1063 case NativeDLL:
1064 case Win32DLL:
1065 case Win32OCX:
1066 case KernelModeDriver:
1067 return true;
1068 case NativeCUI:
1069 case Win32CUI:
1070 case Test:
1071 case Win32SCR:
1072 case Win32GUI:
1073 case BuildTool:
1074 case StaticLibrary:
1075 case ObjectLibrary:
1076 case BootLoader:
1077 case BootSector:
1078 case BootProgram:
1079 case Iso:
1080 case LiveIso:
1081 case IsoRegTest:
1082 case LiveIsoRegTest:
1083 case RpcServer:
1084 case RpcClient:
1085 case Alias:
1086 case IdlHeader:
1087 case EmbeddedTypeLib:
1088 case ElfExecutable:
1089 return false;
1090 }
1091 throw InvalidOperationException ( __FILE__,
1092 __LINE__ );
1093 }
1094
1095 bool
1096 Module::GenerateInOutputTree () const
1097 {
1098 switch ( type )
1099 {
1100 case Kernel:
1101 case KernelModeDLL:
1102 case NativeDLL:
1103 case Win32DLL:
1104 case Win32OCX:
1105 case KernelModeDriver:
1106 case NativeCUI:
1107 case Win32CUI:
1108 case Test:
1109 case Win32SCR:
1110 case Win32GUI:
1111 case BuildTool:
1112 case BootLoader:
1113 case BootSector:
1114 case Iso:
1115 case LiveIso:
1116 case IsoRegTest:
1117 case LiveIsoRegTest:
1118 case EmbeddedTypeLib:
1119 case ElfExecutable:
1120 return true;
1121 case StaticLibrary:
1122 case ObjectLibrary:
1123 case RpcServer:
1124 case RpcClient:
1125 case Alias:
1126 case BootProgram:
1127 case IdlHeader:
1128 return false;
1129 }
1130 throw InvalidOperationException ( __FILE__,
1131 __LINE__ );
1132 }
1133
1134 string
1135 Module::GetTargetName () const
1136 {
1137 return name + extension;
1138 }
1139
1140 string
1141 Module::GetDependencyPath () const
1142 {
1143 if ( HasImportLibrary () )
1144 return ReplaceExtension ( GetPathWithPrefix ( "lib" ), ".a" );
1145 else
1146 return GetPath();
1147 }
1148
1149 string
1150 Module::GetBasePath () const
1151 {
1152 return path;
1153 }
1154
1155 string
1156 Module::GetPath () const
1157 {
1158 if ( path.length() > 0 )
1159 return path + cSep + GetTargetName ();
1160 else
1161 return GetTargetName ();
1162 }
1163
1164 string
1165 Module::GetPathWithPrefix ( const string& prefix ) const
1166 {
1167 return path + cSep + prefix + GetTargetName ();
1168 }
1169
1170 string
1171 Module::GetPathToBaseDir () const
1172 {
1173 string temp_path = path;
1174 string result = "..\\";
1175 while(temp_path.find ('\\') != string::npos)
1176 {
1177 temp_path.erase (0, temp_path.find('\\')+1);
1178 result += "..\\";
1179 }
1180 return result;
1181 }
1182
1183 string
1184 Module::GetInvocationTarget ( const int index ) const
1185 {
1186 return ssprintf ( "%s_invoke_%d",
1187 name.c_str (),
1188 index );
1189 }
1190
1191 string
1192 Module::GetEntryPoint(bool leadingUnderscore) const
1193 {
1194 string result = "";
1195 if (entrypoint == "0" || entrypoint == "0x0")
1196 return "0";
1197 if (leadingUnderscore)
1198 result = "_";
1199
1200 result += entrypoint;
1201 return result;
1202 }
1203
1204 bool
1205 Module::HasFileWithExtension (
1206 const IfableData& data,
1207 const std::string& extension ) const
1208 {
1209 size_t i;
1210 for ( i = 0; i < data.compilationUnits.size (); i++ )
1211 {
1212 CompilationUnit* compilationUnit = data.compilationUnits[i];
1213 if ( compilationUnit->HasFileWithExtension ( extension ) )
1214 return true;
1215 }
1216 for ( i = 0; i < data.ifs.size (); i++ )
1217 {
1218 if ( HasFileWithExtension ( data.ifs[i]->data, extension ) )
1219 return true;
1220 }
1221 return false;
1222 }
1223
1224 void
1225 Module::InvokeModule () const
1226 {
1227 for ( size_t i = 0; i < invocations.size (); i++ )
1228 {
1229 Invoke& invoke = *invocations[i];
1230 string command = FixSeparatorForSystemCommand(invoke.invokeModule->GetPath ()) + " " + invoke.GetParameters ();
1231 printf ( "Executing '%s'\n\n", command.c_str () );
1232 int exitcode = system ( command.c_str () );
1233 if ( exitcode != 0 )
1234 throw InvocationFailedException ( command,
1235 exitcode );
1236 }
1237 }
1238
1239
1240 File::File ( const string& _name,
1241 bool _first,
1242 std::string _switches,
1243 bool _isPreCompiledHeader )
1244 : name(_name),
1245 path_prefix(""),
1246 first(_first),
1247 switches(_switches),
1248 isPreCompiledHeader(_isPreCompiledHeader)
1249 {
1250 }
1251
1252
1253 File::File ( const string& _name,
1254 const string& _path_prefix,
1255 bool _first,
1256 std::string _switches,
1257 bool _isPreCompiledHeader )
1258 : name(_name),
1259 path_prefix(_path_prefix),
1260 first(_first),
1261 switches(_switches),
1262 isPreCompiledHeader(_isPreCompiledHeader)
1263 {
1264 }
1265
1266 void
1267 File::ProcessXML()
1268 {
1269 }
1270
1271
1272 std::string File::GetFullPath () const
1273 {
1274 if ( path_prefix.length () > 0 )
1275 return path_prefix + sSep + name;
1276 else
1277 return name;
1278 }
1279
1280
1281 Library::Library ( const XMLElement& _node,
1282 const Module& _module,
1283 const string& _name )
1284 : node(&_node),
1285 module(_module),
1286 name(_name),
1287 importedModule(_module.project.LocateModule(_name))
1288 {
1289 if ( module.name == name )
1290 {
1291 throw XMLInvalidBuildFileException (
1292 node->location,
1293 "module '%s' cannot link against itself",
1294 name.c_str() );
1295 }
1296 if ( !importedModule )
1297 {
1298 throw XMLInvalidBuildFileException (
1299 node->location,
1300 "module '%s' trying to import non-existant module '%s'",
1301 module.name.c_str(),
1302 name.c_str() );
1303 }
1304 }
1305
1306 Library::Library ( const Module& _module,
1307 const string& _name )
1308 : node(NULL),
1309 module(_module),
1310 name(_name),
1311 importedModule(_module.project.LocateModule(_name))
1312 {
1313 }
1314
1315 void
1316 Library::ProcessXML()
1317 {
1318 if ( node && !module.project.LocateModule ( name ) )
1319 {
1320 throw XMLInvalidBuildFileException (
1321 node->location,
1322 "module '%s' is trying to link against non-existant module '%s'",
1323 module.name.c_str(),
1324 name.c_str() );
1325 }
1326 }
1327
1328
1329 Invoke::Invoke ( const XMLElement& _node,
1330 const Module& _module )
1331 : node (_node),
1332 module (_module)
1333 {
1334 }
1335
1336 void
1337 Invoke::ProcessXML()
1338 {
1339 const XMLAttribute* att = node.GetAttribute ( "module", false );
1340 if (att == NULL)
1341 invokeModule = &module;
1342 else
1343 {
1344 invokeModule = module.project.LocateModule ( att->value );
1345 if ( invokeModule == NULL )
1346 {
1347 throw XMLInvalidBuildFileException (
1348 node.location,
1349 "module '%s' is trying to invoke non-existant module '%s'",
1350 module.name.c_str(),
1351 att->value.c_str() );
1352 }
1353 }
1354
1355 for ( size_t i = 0; i < node.subElements.size (); i++ )
1356 ProcessXMLSubElement ( *node.subElements[i] );
1357 }
1358
1359 void
1360 Invoke::ProcessXMLSubElement ( const XMLElement& e )
1361 {
1362 bool subs_invalid = false;
1363 if ( e.name == "input" )
1364 {
1365 for ( size_t i = 0; i < e.subElements.size (); i++ )
1366 ProcessXMLSubElementInput ( *e.subElements[i] );
1367 }
1368 else if ( e.name == "output" )
1369 {
1370 for ( size_t i = 0; i < e.subElements.size (); i++ )
1371 ProcessXMLSubElementOutput ( *e.subElements[i] );
1372 }
1373 if ( subs_invalid && e.subElements.size() > 0 )
1374 {
1375 throw XMLInvalidBuildFileException (
1376 e.location,
1377 "<%s> cannot have sub-elements",
1378 e.name.c_str() );
1379 }
1380 }
1381
1382 void
1383 Invoke::ProcessXMLSubElementInput ( const XMLElement& e )
1384 {
1385 bool subs_invalid = false;
1386 if ( e.name == "inputfile" && e.value.size () > 0 )
1387 {
1388 input.push_back ( new InvokeFile (
1389 e, FixSeparator ( module.path + cSep + e.value ) ) );
1390 subs_invalid = true;
1391 }
1392 if ( subs_invalid && e.subElements.size() > 0 )
1393 {
1394 throw XMLInvalidBuildFileException (
1395 e.location,
1396 "<%s> cannot have sub-elements",
1397 e.name.c_str() );
1398 }
1399 }
1400
1401 void
1402 Invoke::ProcessXMLSubElementOutput ( const XMLElement& e )
1403 {
1404 bool subs_invalid = false;
1405 if ( e.name == "outputfile" && e.value.size () > 0 )
1406 {
1407 output.push_back ( new InvokeFile (
1408 e, FixSeparator ( module.path + cSep + e.value ) ) );
1409 subs_invalid = true;
1410 }
1411 if ( subs_invalid && e.subElements.size() > 0 )
1412 {
1413 throw XMLInvalidBuildFileException (
1414 e.location,
1415 "<%s> cannot have sub-elements",
1416 e.name.c_str() );
1417 }
1418 }
1419
1420 void
1421 Invoke::GetTargets ( string_list& targets ) const
1422 {
1423 for ( size_t i = 0; i < output.size (); i++ )
1424 {
1425 InvokeFile& file = *output[i];
1426 targets.push_back ( NormalizeFilename ( file.name ) );
1427 }
1428 }
1429
1430 string
1431 Invoke::GetParameters () const
1432 {
1433 string parameters ( "" );
1434 size_t i;
1435 for ( i = 0; i < output.size (); i++ )
1436 {
1437 if ( parameters.length () > 0)
1438 parameters += " ";
1439 InvokeFile& invokeFile = *output[i];
1440 if ( invokeFile.switches.length () > 0 )
1441 {
1442 parameters += invokeFile.switches + " ";
1443 }
1444 parameters += invokeFile.name;
1445 }
1446
1447 for ( i = 0; i < input.size (); i++ )
1448 {
1449 if ( parameters.length () > 0 )
1450 parameters += " ";
1451 InvokeFile& invokeFile = *input[i];
1452 if ( invokeFile.switches.length () > 0 )
1453 {
1454 parameters += invokeFile.switches;
1455 parameters += " ";
1456 }
1457 parameters += invokeFile.name ;
1458 }
1459
1460 return parameters;
1461 }
1462
1463
1464 InvokeFile::InvokeFile ( const XMLElement& _node,
1465 const string& _name )
1466 : node (_node),
1467 name (_name)
1468 {
1469 const XMLAttribute* att = _node.GetAttribute ( "switches", false );
1470 if (att != NULL)
1471 switches = att->value;
1472 else
1473 switches = "";
1474 }
1475
1476 void
1477 InvokeFile::ProcessXML()
1478 {
1479 }
1480
1481
1482 Dependency::Dependency ( const XMLElement& _node,
1483 const Module& _module )
1484 : node (_node),
1485 module (_module),
1486 dependencyModule (NULL)
1487 {
1488 }
1489
1490 void
1491 Dependency::ProcessXML()
1492 {
1493 dependencyModule = module.project.LocateModule ( node.value );
1494 if ( dependencyModule == NULL )
1495 {
1496 throw XMLInvalidBuildFileException (
1497 node.location,
1498 "module '%s' depend on non-existant module '%s'",
1499 module.name.c_str(),
1500 node.value.c_str() );
1501 }
1502 }
1503
1504
1505 Metadata::Metadata ( const XMLElement& _node,
1506 const Module& _module )
1507 : node (_node),
1508 module (_module)
1509 {
1510 /* The module name */
1511 const XMLAttribute* att = _node.GetAttribute ( "name", false );
1512 if (att != NULL)
1513 name = att->value;
1514 else
1515 name = module.name;
1516
1517 /* The module description */
1518 att = _node.GetAttribute ( "description", false );
1519 if (att != NULL)
1520 description = att->value;
1521 else
1522 description = "";
1523
1524 /* The module version */
1525 att = _node.GetAttribute ( "version", false );
1526 if (att != NULL)
1527 version = att->value;
1528 else
1529 version = "";
1530
1531 /* The module copyright */
1532 att = _node.GetAttribute ( "copyright", false );
1533 if (att != NULL)
1534 copyright = att->value;
1535 else
1536 copyright = "";
1537
1538 att = _node.GetAttribute ( "url", false );
1539 if (att != NULL)
1540 url = att->value;
1541 else
1542 url = "";
1543
1544 /* When was this module updated */
1545 att = _node.GetAttribute ( "date", false );
1546 if (att != NULL)
1547 date = att->value;
1548 else
1549 date = "?";
1550
1551 /* When was this module updated */
1552 att = _node.GetAttribute ( "owner", false );
1553 if (att != NULL)
1554 owner = att->value;
1555 else
1556 owner = "ReactOS";
1557 }
1558
1559
1560 ImportLibrary::ImportLibrary ( const XMLElement& _node,
1561 const Module& _module )
1562 : node (_node),
1563 module (_module)
1564 {
1565 const XMLAttribute* att = _node.GetAttribute ( "basename", false );
1566 if (att != NULL)
1567 basename = att->value;
1568 else
1569 basename = module.name;
1570
1571 att = _node.GetAttribute ( "dllname", false );
1572 if (att != NULL)
1573 dllname = att->value;
1574 else
1575 {
1576 if ( _module.type == StaticLibrary )
1577 {
1578 throw XMLInvalidBuildFileException (
1579 node.location,
1580 "<importlibrary> dllname attribute required." );
1581 }
1582
1583 dllname = "";
1584 }
1585
1586 att = _node.GetAttribute ( "definition", true );
1587 assert (att);
1588 definition = FixSeparator(att->value);
1589 }
1590
1591
1592 If::If ( const XMLElement& node_,
1593 const Project& project_,
1594 const Module* module_,
1595 const bool negated_ )
1596 : node(node_), project(project_), module(module_), negated(negated_)
1597 {
1598 const XMLAttribute* att;
1599
1600 att = node.GetAttribute ( "property", true );
1601 assert(att);
1602 property = att->value;
1603
1604 att = node.GetAttribute ( "value", true );
1605 assert(att);
1606 value = att->value;
1607 }
1608
1609 If::~If ()
1610 {
1611 }
1612
1613 void
1614 If::ProcessXML()
1615 {
1616
1617 }
1618
1619
1620 Property::Property ( const XMLElement& node_,
1621 const Project& project_,
1622 const Module* module_ )
1623 : project(project_), module(module_)
1624 {
1625 const XMLAttribute* att;
1626
1627 att = node_.GetAttribute ( "name", true );
1628 assert(att);
1629 name = att->value;
1630
1631 att = node_.GetAttribute ( "value", true );
1632 assert(att);
1633 value = att->value;
1634 }
1635
1636 Property::Property ( const Project& project_,
1637 const Module* module_,
1638 const std::string& name_,
1639 const std::string& value_ )
1640 : project(project_), module(module_), name(name_), value(value_)
1641 {
1642 }
1643
1644 void
1645 Property::ProcessXML()
1646 {
1647 }
1648
1649
1650 PchFile::PchFile (
1651 const XMLElement& node_,
1652 const Module& module_,
1653 const File file_ )
1654 : node(node_), module(module_), file(file_)
1655 {
1656 }
1657
1658 void
1659 PchFile::ProcessXML()
1660 {
1661 }
1662
1663
1664 AutoRegister::AutoRegister ( const Project& project_,
1665 const Module* module_,
1666 const XMLElement& node_ )
1667 : project(project_),
1668 module(module_),
1669 node(node_)
1670 {
1671 Initialize();
1672 }
1673
1674 AutoRegister::~AutoRegister ()
1675 {
1676 }
1677
1678 bool
1679 AutoRegister::IsSupportedModuleType ( ModuleType type )
1680 {
1681 switch ( type )
1682 {
1683 case Win32DLL:
1684 case Win32OCX:
1685 return true;
1686 case Kernel:
1687 case KernelModeDLL:
1688 case NativeDLL:
1689 case NativeCUI:
1690 case Win32CUI:
1691 case Win32GUI:
1692 case Win32SCR:
1693 case KernelModeDriver:
1694 case BootSector:
1695 case BootLoader:
1696 case BootProgram:
1697 case BuildTool:
1698 case StaticLibrary:
1699 case ObjectLibrary:
1700 case Iso:
1701 case LiveIso:
1702 case IsoRegTest:
1703 case LiveIsoRegTest:
1704 case Test:
1705 case RpcServer:
1706 case RpcClient:
1707 case Alias:
1708 case IdlHeader:
1709 case EmbeddedTypeLib:
1710 case ElfExecutable:
1711 return false;
1712 }
1713 throw InvalidOperationException ( __FILE__,
1714 __LINE__ );
1715 }
1716
1717 AutoRegisterType
1718 AutoRegister::GetAutoRegisterType( string type )
1719 {
1720 if ( type == "DllRegisterServer" )
1721 return DllRegisterServer;
1722 if ( type == "DllInstall" )
1723 return DllInstall;
1724 if ( type == "Both" )
1725 return Both;
1726 throw XMLInvalidBuildFileException (
1727 node.location,
1728 "<autoregister> type attribute must be DllRegisterServer, DllInstall or Both." );
1729 }
1730
1731 void
1732 AutoRegister::Initialize ()
1733 {
1734 if ( !IsSupportedModuleType ( module->type ) )
1735 {
1736 throw XMLInvalidBuildFileException (
1737 node.location,
1738 "<autoregister> is not applicable for this module type." );
1739 }
1740
1741 const XMLAttribute* att = node.GetAttribute ( "infsection", true );
1742 infSection = att->value;
1743
1744 att = node.GetAttribute ( "type", true );
1745 type = GetAutoRegisterType ( att->value );
1746 }
1747
1748 void
1749 AutoRegister::ProcessXML()
1750 {
1751 }