Reshuffling directories to separate include and sources, part one.
[fail.git] / include / core / awic / module.cpp
blob6c7f01c04eba7d5e013266eccf4c5f3432a1d52c
1 #include <sstream>
2 #include <fstream>
3 #include <vector>
4 #include "module.h"
5 #include "crc32.h"
7 using namespace awful;
8 using namespace awful::awic;
9 using namespace std;
11 namespace
13 void GenerateModuleHeaderName( std::ostream& Out_, const idlast::Namespace* pNamespace_ )
15 vector< string > NSNames;
16 const idlast::Namespace* pCurrentNS = pNamespace_;
17 while( pCurrentNS->getParent() )
19 NSNames.push_back( pCurrentNS->getName() );
20 pCurrentNS = pCurrentNS->getParent();
23 Out_ << "module_";
24 vector< string >::const_reverse_iterator it;
25 for( it = NSNames.rbegin(); it != NSNames.rend(); ++it )
27 Out_ << *it;
29 if( ( it - NSNames.rbegin() + vector< string >::size_type( 1 ) ) < NSNames.size() )
30 Out_ << '-';
33 Out_ << ".h";
37 void awful::awic::GenerateModuleFiles( const idlast::Namespace* pNamespace_ )
39 // Build an array of namespace names, from the root namespace to the one we're interested in.
41 std::stringstream filename;
42 GenerateModuleHeaderName( filename, pNamespace_ );
43 ofstream file( filename.str().c_str() );
45 vector< string > NSNames;
46 const idlast::Namespace* pCurrentNS = pNamespace_;
47 while( pCurrentNS->getParent() )
49 NSNames.push_back( pCurrentNS->getName() );
50 pCurrentNS = pCurrentNS->getParent();
53 stringstream defname;
54 vector< string >::const_reverse_iterator it;
55 for( it = NSNames.rbegin(); it != NSNames.rend(); ++it )
56 defname << '_' << *it;
58 file << "//\n"
59 "// Automatically generated by AWIC (AWful IDL Compiler).\n"
60 "//\n"
61 "#ifndef MODULE" << defname.str() << "_H_\n"
62 "#define MODULE" << defname.str() << "_H_\n\n"
63 "#include \"core/core.h\"\n";
65 const idlast::NamespaceDependencySet& deps = pNamespace_->getDependencies();
66 idlast::NamespaceDependencySet::const_iterator depit;
67 for( depit = deps.begin(); depit != deps.end(); ++depit )
69 file << "#include \"";
70 GenerateModuleHeaderName( file, *depit );
71 file << "\"\n";
74 file << '\n';
76 for( it = NSNames.rbegin(); it != NSNames.rend(); ++it )
78 file << "namespace " << *it;
80 if( ( it - NSNames.rbegin() + vector< string >::size_type( 1 ) ) < NSNames.size() )
81 file << " { ";
84 file << "\n"
85 "{\n"
86 "\tstruct awful_tag {};\n";
88 for( unsigned int i = 0; i < NSNames.size(); ++i )
89 file << '}';
91 file << "\n\n";
93 const idlast::Dictionary< idlast::Class >& Classes = pNamespace_->getClasses();
94 idlast::Dictionary< idlast::Class >::const_iterator clit;
96 for( clit = Classes.begin(); clit != Classes.end(); ++clit )
98 file << "#include \"" << clit->second->getName() << ".h\"\n";
99 file << "#include \"traits_" << clit->second->getName() << ".h\"\n";
102 const idlast::Dictionary< idlast::Class >& Structs = pNamespace_->getStructs();
103 idlast::Dictionary< idlast::Class >::const_iterator stit;
104 for( stit = Structs.begin(); stit != Structs.end(); ++stit )
106 file << "#include \"" << stit->second->getName() << ".h\"\n";
107 file << "#include \"traits_" << stit->second->getName() << ".h\"\n";
110 file << "\n"
111 "namespace awful\n"
112 "{\n"
113 "\ttemplate<> struct module_traits< ";
115 stringstream FullNSName;
116 for( it = NSNames.rbegin(); it != NSNames.rend(); ++it )
118 FullNSName << *it;
120 if( ( it - NSNames.rbegin() + vector< string >::size_type( 1 ) ) < NSNames.size() )
121 FullNSName << "::";
124 crc32 digest;
125 digest.write( FullNSName.str().c_str(), FullNSName.str().size() );
127 file << FullNSName.str() << "::awful_tag >\n"
128 "\t{\n"
129 "\t\tstatic uint32_t Digest() { return 0x" << std::hex << digest.result() << "; }\n"
130 "\t\tstatic const char* Name() { return \"" << NSNames[0] << "\"; }\n"
131 "\t\tstatic const char* FullName() { return \"" << FullNSName.str() << "\"; }\n\n"
132 "\t\ttemplate< class V > static void VisitQualifiedName( V& Visitor_ )\n"
133 "\t\t{\n";
135 for( it = NSNames.rbegin(); it != NSNames.rend(); ++it )
136 file << "\t\t\tVisitor_.QualifiedNameComponent( \"" << *it << "\" );\n";
138 file << "\t\t}\n"
139 "\n"
140 "\t\ttemplate< class V > static void VisitClasses( V& Visitor_ )\n"
141 "\t\t{\n";
143 for( clit = Classes.begin(); clit != Classes.end(); ++clit )
145 file << "\t\t\tVisitor_.template Class< "
146 << FullNSName.str() << "::" << clit->second->getName() << " >();\n";
149 for( stit = Structs.begin(); stit != Structs.end(); ++stit )
151 file << "\t\t\tVisitor_.template Struct< "
152 << FullNSName.str() << "::" << stit->second->getName() << " >();\n";
155 file << "\t\t}\n"
156 "\t};\n"
157 "}\n"
158 "\n"
159 "#endif\n";