2 * Copyright (C) 2005 Casper S. Hornstrup
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.
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.
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.
27 Right ( const string
& s
, size_t n
)
31 return string ( &s
[s
.size()-n
] );
35 Replace ( const string
& s
, const string
& find
, const string
& with
)
38 const char* p
= s
.c_str();
41 const char* p2
= strstr ( p
, find
.c_str() );
45 ret
+= string ( p
, p2
-p
);
55 FixSeparator ( const string
& s
)
58 char* p
= strchr ( &s2
[0], CBAD_SEP
);
62 p
= strchr ( p
, CBAD_SEP
);
68 DosSeparator ( const string
& s
)
71 char* p
= strchr ( &s2
[0], '/' );
75 p
= strchr ( p
, '/' );
82 const string
& filename
,
83 const string
& newExtension
)
85 size_t index
= filename
.find_last_of ( '/' );
86 if ( index
== string::npos
)
88 size_t index2
= filename
.find_last_of ( '\\' );
89 if ( index2
!= string::npos
&& index2
> index
)
91 string tmp
= filename
.substr( index
/*, filename.size() - index*/ );
92 size_t ext_index
= tmp
.find_last_of( '.' );
93 if ( ext_index
!= string::npos
)
94 return filename
.substr ( 0, index
+ ext_index
) + newExtension
;
95 return filename
+ newExtension
;
100 const string
& location
,
102 const string
& att_value
)
104 if ( !att_value
.size() )
105 throw InvalidBuildFileException (
107 "<directory> tag has empty 'name' attribute" );
108 if ( strpbrk ( att_value
.c_str (), "/\\?*:<>|" ) )
109 throw InvalidBuildFileException (
111 "<directory> tag has invalid characters in 'name' attribute" );
114 return FixSeparator(path
+ CSEP
+ att_value
);
118 GetExtension ( const string
& filename
)
120 size_t index
= filename
.find_last_of ( '/' );
121 if (index
== string::npos
) index
= 0;
122 string tmp
= filename
.substr( index
, filename
.size() - index
);
123 size_t ext_index
= tmp
.find_last_of( '.' );
124 if (ext_index
!= string::npos
)
125 return filename
.substr ( index
+ ext_index
, filename
.size() );
130 GetDirectory ( const string
& filename
)
132 size_t index
= filename
.find_last_of ( CSEP
);
133 if ( index
== string::npos
)
136 return filename
.substr ( 0, index
);
140 GetFilename ( const string
& filename
)
142 size_t index
= filename
.find_last_of ( CSEP
);
143 if ( index
== string::npos
)
146 return filename
.substr ( index
+ 1, filename
.length () - index
);
150 NormalizeFilename ( const string
& filename
)
152 if ( filename
== "" )
155 string normalizedPath
= path
.Fixup ( filename
, true );
156 string relativeNormalizedPath
= path
.RelativeFromWorkingDirectory ( normalizedPath
);
157 return FixSeparator ( relativeNormalizedPath
);
161 GetBooleanValue ( const string
& value
)
169 IfableData::~IfableData()
172 for ( i
= 0; i
< files
.size(); i
++ )
174 for ( i
= 0; i
< includes
.size(); i
++ )
176 for ( i
= 0; i
< defines
.size(); i
++ )
178 for ( i
= 0; i
< libraries
.size(); i
++ )
180 for ( i
= 0; i
< properties
.size(); i
++ )
181 delete properties
[i
];
182 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
183 delete compilerFlags
[i
];
184 for ( i
= 0; i
< ifs
.size(); i
++ )
188 void IfableData::ProcessXML ()
191 for ( i
= 0; i
< files
.size (); i
++ )
192 files
[i
]->ProcessXML ();
193 for ( i
= 0; i
< includes
.size (); i
++ )
194 includes
[i
]->ProcessXML ();
195 for ( i
= 0; i
< defines
.size (); i
++ )
196 defines
[i
]->ProcessXML ();
197 for ( i
= 0; i
< libraries
.size (); i
++ )
198 libraries
[i
]->ProcessXML ();
199 for ( i
= 0; i
< properties
.size(); i
++ )
200 properties
[i
]->ProcessXML ();
201 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
202 compilerFlags
[i
]->ProcessXML ();
203 for ( i
= 0; i
< ifs
.size (); i
++ )
204 ifs
[i
]->ProcessXML ();
207 Module::Module ( const Project
& project
,
208 const XMLElement
& moduleNode
,
209 const string
& modulePath
)
212 importLibrary (NULL
),
218 if ( node
.name
!= "module" )
219 throw InvalidOperationException ( __FILE__
,
221 "Module created with non-<module> node" );
223 xmlbuildFile
= Path::RelativeFromWorkingDirectory ( moduleNode
.xmlFile
->filename () );
225 path
= FixSeparator ( modulePath
);
229 const XMLAttribute
* att
= moduleNode
.GetAttribute ( "if", false );
231 enabled
= GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
233 att
= moduleNode
.GetAttribute ( "ifnot", false );
235 enabled
= !GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
237 att
= moduleNode
.GetAttribute ( "name", true );
241 att
= moduleNode
.GetAttribute ( "type", true );
243 type
= GetModuleType ( node
.location
, *att
);
245 att
= moduleNode
.GetAttribute ( "extension", false );
247 extension
= att
->value
;
249 extension
= GetDefaultModuleExtension ();
251 att
= moduleNode
.GetAttribute ( "unicode", false );
254 const char* p
= att
->value
.c_str();
255 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
257 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
261 throw InvalidAttributeValueException (
270 att
= moduleNode
.GetAttribute ( "entrypoint", false );
272 entrypoint
= att
->value
;
274 entrypoint
= GetDefaultModuleEntrypoint ();
276 att
= moduleNode
.GetAttribute ( "baseaddress", false );
278 baseaddress
= att
->value
;
280 baseaddress
= GetDefaultModuleBaseaddress ();
282 att
= moduleNode
.GetAttribute ( "mangledsymbols", false );
285 const char* p
= att
->value
.c_str();
286 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
287 mangledSymbols
= true;
288 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
289 mangledSymbols
= false;
292 throw InvalidAttributeValueException (
299 mangledSymbols
= false;
301 att
= moduleNode
.GetAttribute ( "host", false );
304 const char* p
= att
->value
.c_str();
305 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
307 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
311 throw InvalidAttributeValueException (
318 att
= moduleNode
.GetAttribute ( "prefix", false );
322 att
= moduleNode
.GetAttribute ( "installbase", false );
324 installBase
= att
->value
;
328 att
= moduleNode
.GetAttribute ( "installname", false );
330 installName
= att
->value
;
334 att
= moduleNode
.GetAttribute ( "usewrc", false );
336 useWRC
= att
->value
== "true";
340 att
= moduleNode
.GetAttribute ( "allowwarnings", false );
343 att
= moduleNode
.GetAttribute ( "warnings", false );
346 printf ( "%s: WARNING: 'warnings' attribute of <module> is deprecated, use 'allowwarnings' instead\n",
347 moduleNode
.location
.c_str() );
351 allowWarnings
= att
->value
== "true";
353 allowWarnings
= false;
355 att
= moduleNode
.GetAttribute ( "aliasof", false );
356 if ( type
== Alias
&& att
!= NULL
)
357 aliasedModuleName
= att
->value
;
359 aliasedModuleName
= "";
365 for ( i
= 0; i
< invocations
.size(); i
++ )
366 delete invocations
[i
];
367 for ( i
= 0; i
< dependencies
.size(); i
++ )
368 delete dependencies
[i
];
369 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
370 delete compilerFlags
[i
];
371 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
372 delete linkerFlags
[i
];
373 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
374 delete stubbedComponents
[i
];
384 if ( aliasedModuleName
== name
)
385 throw InvalidBuildFileException (
387 "module '%s' cannot link against itself",
389 const Module
* m
= project
.LocateModule ( aliasedModuleName
);
391 throw InvalidBuildFileException (
393 "module '%s' trying to alias non-existant module '%s'",
395 aliasedModuleName
.c_str() );
399 for ( i
= 0; i
< node
.subElements
.size(); i
++ )
400 ProcessXMLSubElement ( *node
.subElements
[i
], path
);
401 for ( i
= 0; i
< invocations
.size(); i
++ )
402 invocations
[i
]->ProcessXML ();
403 for ( i
= 0; i
< dependencies
.size(); i
++ )
404 dependencies
[i
]->ProcessXML ();
405 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
406 compilerFlags
[i
]->ProcessXML();
407 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
408 linkerFlags
[i
]->ProcessXML();
409 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
410 stubbedComponents
[i
]->ProcessXML();
411 non_if_data
.ProcessXML();
417 Module::ProcessXMLSubElement ( const XMLElement
& e
,
421 bool subs_invalid
= false;
422 string
subpath ( path
);
423 if ( e
.name
== "file" && e
.value
.size () > 0 )
426 const XMLAttribute
* att
= e
.GetAttribute ( "first", false );
429 if ( !stricmp ( att
->value
.c_str(), "true" ) )
431 else if ( stricmp ( att
->value
.c_str(), "false" ) )
432 throw InvalidBuildFileException (
434 "attribute 'first' of <file> element can only be 'true' or 'false'" );
436 string switches
= "";
437 att
= e
.GetAttribute ( "switches", false );
439 switches
= att
->value
;
442 // check for c++ file
443 string ext
= GetExtension ( e
.value
);
444 if ( !stricmp ( ext
.c_str(), ".cpp" ) )
446 else if ( !stricmp ( ext
.c_str(), ".cc" ) )
448 else if ( !stricmp ( ext
.c_str(), ".cxx" ) )
451 File
* pFile
= new File ( FixSeparator ( path
+ CSEP
+ e
.value
),
456 pIf
->data
.files
.push_back ( pFile
);
458 non_if_data
.files
.push_back ( pFile
);
461 else if ( e
.name
== "library" && e
.value
.size () )
463 Library
* pLibrary
= new Library ( e
, *this, e
.value
);
465 pIf
->data
.libraries
.push_back ( pLibrary
);
467 non_if_data
.libraries
.push_back ( pLibrary
);
470 else if ( e
.name
== "directory" )
472 const XMLAttribute
* att
= e
.GetAttribute ( "name", true );
474 subpath
= GetSubPath ( e
.location
, path
, att
->value
);
476 else if ( e
.name
== "include" )
478 Include
* include
= new Include ( project
, this, &e
);
480 pIf
->data
.includes
.push_back ( include
);
482 non_if_data
.includes
.push_back ( include
);
485 else if ( e
.name
== "define" )
487 Define
* pDefine
= new Define ( project
, this, e
);
489 pIf
->data
.defines
.push_back ( pDefine
);
491 non_if_data
.defines
.push_back ( pDefine
);
494 else if ( e
.name
== "invoke" )
497 throw InvalidBuildFileException (
499 "<invoke> is not a valid sub-element of <if>" );
500 invocations
.push_back ( new Invoke ( e
, *this ) );
501 subs_invalid
= false;
503 else if ( e
.name
== "dependency" )
506 throw InvalidBuildFileException (
508 "<dependency> is not a valid sub-element of <if>" );
509 dependencies
.push_back ( new Dependency ( e
, *this ) );
512 else if ( e
.name
== "importlibrary" )
515 throw InvalidBuildFileException (
517 "<importlibrary> is not a valid sub-element of <if>" );
519 throw InvalidBuildFileException (
521 "Only one <importlibrary> is valid per module" );
522 importLibrary
= new ImportLibrary ( e
, *this );
525 else if ( e
.name
== "if" )
528 pIf
= new If ( e
, project
, this );
530 pOldIf
->data
.ifs
.push_back ( pIf
);
532 non_if_data
.ifs
.push_back ( pIf
);
533 subs_invalid
= false;
535 else if ( e
.name
== "ifnot" )
538 pIf
= new If ( e
, project
, this, true );
540 pOldIf
->data
.ifs
.push_back ( pIf
);
542 non_if_data
.ifs
.push_back ( pIf
);
543 subs_invalid
= false;
545 else if ( e
.name
== "compilerflag" )
547 CompilerFlag
* pCompilerFlag
= new CompilerFlag ( project
, this, e
);
549 pIf
->data
.compilerFlags
.push_back ( pCompilerFlag
);
551 non_if_data
.compilerFlags
.push_back ( pCompilerFlag
);
554 else if ( e
.name
== "linkerflag" )
556 linkerFlags
.push_back ( new LinkerFlag ( project
, this, e
) );
559 else if ( e
.name
== "component" )
561 stubbedComponents
.push_back ( new StubbedComponent ( this, e
) );
562 subs_invalid
= false;
564 else if ( e
.name
== "property" )
566 throw InvalidBuildFileException (
568 "<property> is not a valid sub-element of <module>" );
570 else if ( e
.name
== "bootstrap" )
572 bootstrap
= new Bootstrap ( project
, this, e
);
575 else if ( e
.name
== "pch" )
578 throw InvalidBuildFileException (
580 "<pch> is not a valid sub-element of <if>" );
582 throw InvalidBuildFileException (
584 "Only one <pch> is valid per module" );
586 e
, *this, File ( FixSeparator ( path
+ CSEP
+ e
.value
), false, "", true ) );
589 if ( subs_invalid
&& e
.subElements
.size() > 0 )
590 throw InvalidBuildFileException (
592 "<%s> cannot have sub-elements",
594 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
595 ProcessXMLSubElement ( *e
.subElements
[i
], subpath
, pIf
);
599 Module::GetModuleType ( const string
& location
, const XMLAttribute
& attribute
)
601 if ( attribute
.value
== "buildtool" )
603 if ( attribute
.value
== "staticlibrary" )
604 return StaticLibrary
;
605 if ( attribute
.value
== "objectlibrary" )
606 return ObjectLibrary
;
607 if ( attribute
.value
== "kernel" )
609 if ( attribute
.value
== "kernelmodedll" )
610 return KernelModeDLL
;
611 if ( attribute
.value
== "kernelmodedriver" )
612 return KernelModeDriver
;
613 if ( attribute
.value
== "nativedll" )
615 if ( attribute
.value
== "nativecui" )
617 if ( attribute
.value
== "win32dll" )
619 if ( attribute
.value
== "win32cui" )
621 if ( attribute
.value
== "win32gui" )
623 if ( attribute
.value
== "bootloader" )
625 if ( attribute
.value
== "bootsector" )
627 if ( attribute
.value
== "iso" )
629 if ( attribute
.value
== "liveiso" )
631 if ( attribute
.value
== "test" )
633 if ( attribute
.value
== "rpcserver" )
635 if ( attribute
.value
== "rpcclient" )
637 if ( attribute
.value
== "alias" )
639 throw InvalidAttributeValueException ( location
,
645 Module::GetDefaultModuleExtension () const
664 case KernelModeDriver
:
681 throw InvalidOperationException ( __FILE__
,
686 Module::GetDefaultModuleEntrypoint () const
691 return "_NtProcessStartup";
693 return "_DriverEntry@8";
695 return "_DllMainCRTStartup@12";
697 return "_NtProcessStartup@4";
699 return "_DllMain@12";
703 return "_wmainCRTStartup";
705 return "_mainCRTStartup";
708 return "_wWinMainCRTStartup";
710 return "_WinMainCRTStartup";
711 case KernelModeDriver
:
712 return "_DriverEntry@8";
725 throw InvalidOperationException ( __FILE__
,
730 Module::GetDefaultModuleBaseaddress () const
746 case KernelModeDriver
:
760 throw InvalidOperationException ( __FILE__
,
765 Module::HasImportLibrary () const
767 return importLibrary
!= NULL
;
771 Module::IsDLL () const
779 case KernelModeDriver
:
797 throw InvalidOperationException ( __FILE__
,
802 Module::GenerateInOutputTree () const
810 case KernelModeDriver
:
828 throw InvalidOperationException ( __FILE__
,
833 Module::GetTargetName () const
835 return name
+ extension
;
839 Module::GetDependencyPath () const
841 if ( HasImportLibrary () )
842 return ReplaceExtension ( GetPathWithPrefix ( "lib" ), ".a" );
848 Module::GetBasePath () const
854 Module::GetPath () const
856 if ( path
.length() > 0 )
857 return path
+ CSEP
+ GetTargetName ();
859 return GetTargetName ();
863 Module::GetPathWithPrefix ( const string
& prefix
) const
865 return path
+ CSEP
+ prefix
+ GetTargetName ();
869 Module::GetInvocationTarget ( const int index
) const
871 return ssprintf ( "%s_invoke_%d",
877 Module::HasFileWithExtension (
878 const IfableData
& data
,
879 const std::string
& extension
) const
882 for ( i
= 0; i
< data
.files
.size (); i
++ )
884 File
& file
= *data
.files
[i
];
885 string file_ext
= GetExtension ( file
.name
);
886 if ( !stricmp ( file_ext
.c_str (), extension
.c_str () ) )
889 for ( i
= 0; i
< data
.ifs
.size (); i
++ )
891 if ( HasFileWithExtension ( data
.ifs
[i
]->data
, extension
) )
898 Module::InvokeModule () const
900 for ( size_t i
= 0; i
< invocations
.size (); i
++ )
902 Invoke
& invoke
= *invocations
[i
];
903 string command
= invoke
.invokeModule
->GetPath () + " " + invoke
.GetParameters ();
904 printf ( "Executing '%s'\n\n", command
.c_str () );
905 int exitcode
= system ( command
.c_str () );
907 throw InvocationFailedException ( command
,
913 File::File ( const string
& _name
, bool _first
,
914 std::string _switches
,
915 bool _isPreCompiledHeader
)
919 isPreCompiledHeader(_isPreCompiledHeader
)
929 File::IsGeneratedFile () const
931 string extension
= GetExtension ( name
);
932 return ( extension
== ".spec" || extension
== ".SPEC" );
936 Library::Library ( const XMLElement
& _node
,
937 const Module
& _module
,
938 const string
& _name
)
942 importedModule(_module
.project
.LocateModule(_name
))
944 if ( module
.name
== name
)
945 throw InvalidBuildFileException (
947 "module '%s' cannot link against itself",
949 if ( !importedModule
)
950 throw InvalidBuildFileException (
952 "module '%s' trying to import non-existant module '%s'",
958 Library::ProcessXML()
960 if ( !module
.project
.LocateModule ( name
) )
961 throw InvalidBuildFileException (
963 "module '%s' is trying to link against non-existant module '%s'",
969 Invoke::Invoke ( const XMLElement
& _node
,
970 const Module
& _module
)
979 const XMLAttribute
* att
= node
.GetAttribute ( "module", false );
981 invokeModule
= &module
;
984 invokeModule
= module
.project
.LocateModule ( att
->value
);
985 if ( invokeModule
== NULL
)
986 throw InvalidBuildFileException (
988 "module '%s' is trying to invoke non-existant module '%s'",
990 att
->value
.c_str() );
993 for ( size_t i
= 0; i
< node
.subElements
.size (); i
++ )
994 ProcessXMLSubElement ( *node
.subElements
[i
] );
998 Invoke::ProcessXMLSubElement ( const XMLElement
& e
)
1000 bool subs_invalid
= false;
1001 if ( e
.name
== "input" )
1003 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1004 ProcessXMLSubElementInput ( *e
.subElements
[i
] );
1006 else if ( e
.name
== "output" )
1008 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1009 ProcessXMLSubElementOutput ( *e
.subElements
[i
] );
1011 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1012 throw InvalidBuildFileException ( e
.location
,
1013 "<%s> cannot have sub-elements",
1018 Invoke::ProcessXMLSubElementInput ( const XMLElement
& e
)
1020 bool subs_invalid
= false;
1021 if ( e
.name
== "inputfile" && e
.value
.size () > 0 )
1023 input
.push_back ( new InvokeFile ( e
, FixSeparator ( module
.path
+ CSEP
+ e
.value
) ) );
1024 subs_invalid
= true;
1026 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1027 throw InvalidBuildFileException ( e
.location
,
1028 "<%s> cannot have sub-elements",
1033 Invoke::ProcessXMLSubElementOutput ( const XMLElement
& e
)
1035 bool subs_invalid
= false;
1036 if ( e
.name
== "outputfile" && e
.value
.size () > 0 )
1038 output
.push_back ( new InvokeFile ( e
, FixSeparator ( module
.path
+ CSEP
+ e
.value
) ) );
1039 subs_invalid
= true;
1041 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1042 throw InvalidBuildFileException (
1044 "<%s> cannot have sub-elements",
1049 Invoke::GetTargets ( string_list
& targets
) const
1051 for ( size_t i
= 0; i
< output
.size (); i
++ )
1053 InvokeFile
& file
= *output
[i
];
1054 targets
.push_back ( NormalizeFilename ( file
.name
) );
1059 Invoke::GetParameters () const
1061 string
parameters ( "" );
1063 for ( i
= 0; i
< output
.size (); i
++ )
1065 if ( parameters
.length () > 0)
1067 InvokeFile
& invokeFile
= *output
[i
];
1068 if ( invokeFile
.switches
.length () > 0 )
1070 parameters
+= invokeFile
.switches
+ " ";
1072 parameters
+= invokeFile
.name
;
1075 for ( i
= 0; i
< input
.size (); i
++ )
1077 if ( parameters
.length () > 0 )
1079 InvokeFile
& invokeFile
= *input
[i
];
1080 if ( invokeFile
.switches
.length () > 0 )
1082 parameters
+= invokeFile
.switches
;
1085 parameters
+= invokeFile
.name
;
1092 InvokeFile::InvokeFile ( const XMLElement
& _node
,
1093 const string
& _name
)
1097 const XMLAttribute
* att
= _node
.GetAttribute ( "switches", false );
1099 switches
= att
->value
;
1105 InvokeFile::ProcessXML()
1110 Dependency::Dependency ( const XMLElement
& _node
,
1111 const Module
& _module
)
1114 dependencyModule (NULL
)
1119 Dependency::ProcessXML()
1121 dependencyModule
= module
.project
.LocateModule ( node
.value
);
1122 if ( dependencyModule
== NULL
)
1123 throw InvalidBuildFileException ( node
.location
,
1124 "module '%s' depend on non-existant module '%s'",
1125 module
.name
.c_str(),
1126 node
.value
.c_str() );
1130 ImportLibrary::ImportLibrary ( const XMLElement
& _node
,
1131 const Module
& _module
)
1135 const XMLAttribute
* att
= _node
.GetAttribute ( "basename", false );
1137 basename
= att
->value
;
1139 basename
= module
.name
;
1141 att
= _node
.GetAttribute ( "definition", true );
1143 definition
= FixSeparator(att
->value
);
1147 If::If ( const XMLElement
& node_
,
1148 const Project
& project_
,
1149 const Module
* module_
,
1150 const bool negated_
)
1151 : node(node_
), project(project_
), module(module_
), negated(negated_
)
1153 const XMLAttribute
* att
;
1155 att
= node
.GetAttribute ( "property", true );
1157 property
= att
->value
;
1159 att
= node
.GetAttribute ( "value", true );
1174 Property::Property ( const XMLElement
& node_
,
1175 const Project
& project_
,
1176 const Module
* module_
)
1177 : node(node_
), project(project_
), module(module_
)
1179 const XMLAttribute
* att
;
1181 att
= node
.GetAttribute ( "name", true );
1185 att
= node
.GetAttribute ( "value", true );
1191 Property::ProcessXML()
1197 const XMLElement
& node_
,
1198 const Module
& module_
,
1200 : node(node_
), module(module_
), file(file_
)
1205 PchFile::ProcessXML()