1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_codemaker.hxx" 26 27 #include "includes.hxx" 28 29 #include "dumputils.hxx" 30 31 #include "codemaker/dependencies.hxx" 32 #include "codemaker/global.hxx" 33 #include "codemaker/typemanager.hxx" 34 #include "codemaker/unotype.hxx" 35 36 #include "osl/diagnose.h" 37 #include "rtl/string.hxx" 38 #include "rtl/ustring.hxx" 39 #include "sal/types.h" 40 41 #include <vector> 42 43 using codemaker::cppumaker::Includes; 44 45 Includes::Includes( 46 TypeManager const & manager, codemaker::Dependencies const & dependencies, 47 bool hpp): 48 m_manager(manager), m_map(dependencies.getMap()), m_hpp(hpp), 49 m_includeAny(dependencies.hasAnyDependency()), m_includeReference(false), 50 m_includeSequence(dependencies.hasSequenceDependency()), 51 m_includeType(dependencies.hasTypeDependency()), 52 m_includeCppuMacrosHxx(false), m_includeCppuUnotypeHxx(false), 53 m_includeOslDoublecheckedlockingH(false), m_includeOslMutexHxx(false), 54 m_includeRtlStrbufHxx(false), m_includeRtlStringH(false), 55 m_includeRtlTextencH(false), m_includeRtlUstrbufHxx(false), 56 m_includeRtlUstringH(false), 57 m_includeRtlUstringHxx(dependencies.hasStringDependency()), 58 m_includeSalTypesH( 59 dependencies.hasBooleanDependency() || dependencies.hasByteDependency() 60 || dependencies.hasShortDependency() 61 || dependencies.hasUnsignedShortDependency() 62 || dependencies.hasLongDependency() 63 || dependencies.hasUnsignedShortDependency() 64 || dependencies.hasHyperDependency() 65 || dependencies.hasUnsignedHyperDependency() 66 || dependencies.hasCharDependency()), 67 m_includeTypelibTypeclassH(false), 68 m_includeTypelibTypedescriptionH(false) 69 {} 70 71 Includes::~Includes() 72 {} 73 74 void Includes::add(rtl::OString const & registryType) { 75 sal_Int32 rank; 76 std::vector< rtl::OString > args; 77 rtl::OString type( 78 codemaker::UnoType::decompose(registryType, &rank, &args)); 79 if (rank > 0) { 80 m_includeSequence = true; 81 } 82 switch (codemaker::UnoType::getSort(type)) { 83 case codemaker::UnoType::SORT_VOID: 84 OSL_ASSERT(args.empty()); 85 OSL_ASSERT(false); 86 break; 87 88 case codemaker::UnoType::SORT_BOOLEAN: 89 case codemaker::UnoType::SORT_BYTE: 90 case codemaker::UnoType::SORT_SHORT: 91 case codemaker::UnoType::SORT_UNSIGNED_SHORT: 92 case codemaker::UnoType::SORT_LONG: 93 case codemaker::UnoType::SORT_UNSIGNED_LONG: 94 case codemaker::UnoType::SORT_HYPER: 95 case codemaker::UnoType::SORT_UNSIGNED_HYPER: 96 case codemaker::UnoType::SORT_CHAR: 97 OSL_ASSERT(args.empty()); 98 m_includeSalTypesH = true; 99 break; 100 101 case codemaker::UnoType::SORT_FLOAT: 102 case codemaker::UnoType::SORT_DOUBLE: 103 OSL_ASSERT(args.empty()); 104 break; 105 106 case codemaker::UnoType::SORT_STRING: 107 OSL_ASSERT(args.empty()); 108 m_includeRtlUstringHxx = true; 109 break; 110 111 case codemaker::UnoType::SORT_TYPE: 112 OSL_ASSERT(args.empty()); 113 m_includeType = true; 114 break; 115 116 case codemaker::UnoType::SORT_ANY: 117 OSL_ASSERT(args.empty()); 118 m_includeAny = true; 119 break; 120 121 case codemaker::UnoType::SORT_COMPLEX: 122 m_map.insert( 123 codemaker::Dependencies::Map::value_type( 124 type, codemaker::Dependencies::KIND_NO_BASE)); 125 {for (std::vector< rtl::OString >::iterator i(args.begin()); 126 i != args.end(); ++i) 127 { 128 add(*i); 129 }} 130 break; 131 132 default: 133 OSL_ASSERT(false); 134 break; 135 } 136 } 137 138 namespace { 139 140 void dumpEmptyLineBeforeFirst(FileStream & out, bool * first) { 141 OSL_ASSERT(first != 0); 142 if (*first) { 143 out << "\n"; 144 *first = false; 145 } 146 } 147 148 } 149 150 void Includes::dump(FileStream & out, rtl::OString const * companionHdl) { 151 OSL_ASSERT(companionHdl == 0 || m_hpp); 152 if (!m_includeReference) { 153 for (codemaker::Dependencies::Map::iterator i(m_map.begin()); 154 i != m_map.end(); ++i) 155 { 156 if (isInterfaceType(i->first)) { 157 m_includeReference = true; 158 break; 159 } 160 } 161 } 162 out << "#include \"sal/config.h\"\n"; 163 if (companionHdl) { 164 out << "\n"; 165 dumpInclude(out, *companionHdl, false); 166 } 167 bool first = true; 168 for (codemaker::Dependencies::Map::iterator i(m_map.begin()); 169 i != m_map.end(); ++i) 170 { 171 dumpEmptyLineBeforeFirst(out, &first); 172 if (m_hpp || i->second == codemaker::Dependencies::KIND_BASE 173 || !isInterfaceType(i->first)) 174 { 175 dumpInclude(out, i->first, m_hpp); 176 } else { 177 bool ns = dumpNamespaceOpen(out, i->first, false); 178 if (ns) { 179 out << " "; 180 } 181 out << "class "; 182 dumpTypeIdentifier(out, i->first); 183 out << ";"; 184 if (ns) { 185 out << " "; 186 } 187 dumpNamespaceClose(out, i->first, false); 188 out << "\n"; 189 } 190 } 191 static char const * hxxExtension[2] = { "h", "hxx" }; 192 if (m_includeAny) { 193 dumpEmptyLineBeforeFirst(out, &first); 194 out << "#include \"com/sun/star/uno/Any." << hxxExtension[m_hpp] << "\"\n"; 195 } 196 if (m_includeReference) { 197 dumpEmptyLineBeforeFirst(out, &first); 198 out << "#include \"com/sun/star/uno/Reference." << hxxExtension[m_hpp] << "\"\n"; 199 } 200 if (m_includeSequence) { 201 dumpEmptyLineBeforeFirst(out, &first); 202 out << "#include \"com/sun/star/uno/Sequence." << hxxExtension[m_hpp] << "\"\n"; 203 } 204 if (m_includeType) { 205 dumpEmptyLineBeforeFirst(out, &first); 206 out << "#include \"com/sun/star/uno/Type." << hxxExtension[m_hpp] << "\"\n"; 207 } 208 if (m_includeCppuMacrosHxx) { 209 dumpEmptyLineBeforeFirst(out, &first); 210 out << ("#include \"cppu/macros.hxx\"\n"); 211 } 212 if (m_includeCppuUnotypeHxx) { 213 dumpEmptyLineBeforeFirst(out, &first); 214 out << ("#include \"cppu/unotype.hxx\"\n"); 215 } 216 if (m_includeOslDoublecheckedlockingH) { 217 dumpEmptyLineBeforeFirst(out, &first); 218 out << ("#include \"osl/doublecheckedlocking.h\"\n"); 219 } 220 if (m_includeOslMutexHxx) { 221 dumpEmptyLineBeforeFirst(out, &first); 222 out << "#include \"osl/mutex.hxx\"\n"; 223 } 224 if (m_includeRtlStrbufHxx) { 225 dumpEmptyLineBeforeFirst(out, &first); 226 out << ("#include \"rtl/strbuf.hxx\"\n"); 227 } 228 if (m_includeRtlStringH) { 229 dumpEmptyLineBeforeFirst(out, &first); 230 out << "#include \"rtl/string.h\"\n"; 231 } 232 if (m_includeRtlTextencH) { 233 dumpEmptyLineBeforeFirst(out, &first); 234 out << "#include \"rtl/textenc.h\"\n"; 235 } 236 if (m_includeRtlUstrbufHxx) { 237 dumpEmptyLineBeforeFirst(out, &first); 238 out << ("#include \"rtl/ustrbuf.hxx\"\n"); 239 } 240 if (m_includeRtlUstringH) { 241 dumpEmptyLineBeforeFirst(out, &first); 242 out << "#include \"rtl/ustring.h\"\n"; 243 } 244 if (m_includeRtlUstringHxx) { 245 dumpEmptyLineBeforeFirst(out, &first); 246 out << ("#include \"rtl/ustring.hxx\"\n"); 247 } 248 if (m_includeSalTypesH) { 249 dumpEmptyLineBeforeFirst(out, &first); 250 out << "#include \"sal/types.h\"\n"; 251 } 252 if (m_includeTypelibTypeclassH) { 253 dumpEmptyLineBeforeFirst(out, &first); 254 out << ("#include \"typelib/typeclass.h\"\n"); 255 } 256 if (m_includeTypelibTypedescriptionH) { 257 dumpEmptyLineBeforeFirst(out, &first); 258 out << ("#include \"typelib/typedescription.h\"\n"); 259 } 260 } 261 262 void Includes::dumpInclude( 263 FileStream & out, rtl::OString const & registryType, bool hpp, 264 rtl::OString const & suffix) 265 { 266 static char const * extension[2] = { "hdl", "hpp" }; 267 out << "#include \"" << registryType; 268 if ( !suffix.isEmpty() ) { 269 out << "/" << suffix; 270 } 271 out << "." << extension[hpp] << "\"\n"; 272 } 273 274 bool Includes::isInterfaceType(rtl::OString const & registryType) const { 275 return m_manager.getTypeClass(registryType) == RT_TYPE_INTERFACE; 276 } 277