/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_codemaker.hxx" #include #include #include #include #include "idltype.hxx" #include "idloptions.hxx" using namespace rtl; //************************************************************************* // IdlType //************************************************************************* IdlType::IdlType(TypeReader& typeReader, const OString& typeName, const TypeManager& typeMgr, const TypeDependency& typeDependencies) : m_inheritedMemberCount(0) , m_indentLength(0) , m_typeName(typeName) , m_reader(typeReader) , m_typeMgr((TypeManager&)typeMgr) , m_dependencies(typeDependencies) { sal_Int32 i = typeName.lastIndexOf('/'); m_name = typeName.copy( i != -1 ? i+1 : 0 ); } IdlType::~IdlType() { } sal_Bool IdlType::dump(IdlOptions* pOptions) throw( CannotDumpException ) { sal_Bool ret = sal_False; OString outPath; if (pOptions->isValid("-O")) outPath = pOptions->getOption("-O"); OString tmpFileName; OString hFileName = createFileNameFromType(outPath, m_typeName, ".idl"); sal_Bool bFileExists = sal_False; sal_Bool bFileCheck = sal_False; if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) { bFileExists = fileExists( hFileName ); ret = sal_True; } if ( bFileExists && pOptions->isValid("-Gc") ) { tmpFileName = createFileNameFromType(outPath, m_typeName, ".tml"); bFileCheck = sal_True; } if ( !bFileExists || bFileCheck ) { FileStream hFile; if ( bFileCheck ) hFile.open(tmpFileName); else hFile.open(hFileName); if(!hFile.isValid()) { OString message("cannot open "); message += hFileName + " for writing"; throw CannotDumpException(message); } ret = dumpHFile(hFile); hFile.close(); if (ret && bFileCheck) { ret = checkFileContent(hFileName, tmpFileName); } } return ret; } sal_Bool IdlType::dumpDependedTypes(IdlOptions* pOptions) throw( CannotDumpException ) { sal_Bool ret = sal_True; TypeUsingSet usingSet(m_dependencies.getDependencies(m_typeName)); TypeUsingSet::const_iterator iter = usingSet.begin(); OString typeName; sal_uInt32 index = 0; while (iter != usingSet.end()) { typeName = (*iter).m_type; if ((index = typeName.lastIndexOf(']')) > 0) typeName = typeName.copy(index + 1); if ( getBaseType(typeName).isEmpty() ) { if (!produceType(typeName, m_typeMgr, m_dependencies, pOptions)) { fprintf(stderr, "%s ERROR: %s\n", pOptions->getProgramName().getStr(), OString("cannot dump Type '" + typeName + "'").getStr()); exit(99); } } ++iter; } return ret; } OString IdlType::dumpHeaderDefine(FileStream& o, sal_Char* prefix ) { if (m_typeName.equals("/")) { m_typeName = "global"; } sal_uInt32 length = 3 + m_typeName.getLength() + strlen(prefix); OStringBuffer tmpBuf(length); tmpBuf.append('_'); tmpBuf.append(m_typeName); tmpBuf.append('_'); tmpBuf.append(prefix); tmpBuf.append('_'); OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase()); o << "#ifndef " << tmp << "\n#define " << tmp << "\n"; return tmp; } void IdlType::dumpDefaultHIncludes(FileStream& o) { } void IdlType::dumpInclude(FileStream& o, const OString& genTypeName, const OString& typeName, sal_Char* prefix ) { sal_uInt32 length = 3+ m_typeName.getLength() + strlen(prefix); OStringBuffer tmpBuf(length); tmpBuf.append('_'); tmpBuf.append(typeName); tmpBuf.append('_'); tmpBuf.append(prefix); tmpBuf.append('_'); OString tmp(tmpBuf.makeStringAndClear().replace('/', '_').toAsciiUpperCase()); length = 1 + typeName.getLength() + strlen(prefix); tmpBuf.ensureCapacity(length); tmpBuf.append(typeName); tmpBuf.append('.'); tmpBuf.append(prefix); o << "#ifndef " << tmp << "\n#include <"; tmp = tmpBuf.makeStringAndClear(); sal_Int32 nIndex = 0; do { genTypeName.getToken(0, '/', nIndex); o << "../"; } while( nIndex != -1 ); // sal_Int32 nSlashes = genTypeName.getTokenCount( '/'); // for( sal_Int32 i = 1; i < nSlashes; i++ ) // o << "../"; o << tmp; o << ">\n#endif\n"; } void IdlType::dumpDepIncludes(FileStream& o, const OString& typeName, sal_Char* prefix) { TypeUsingSet usingSet(m_dependencies.getDependencies(typeName)); TypeUsingSet::const_iterator iter = usingSet.begin(); OString sPrefix(OString(prefix).toAsciiUpperCase()); sal_uInt32 index = 0; sal_uInt32 seqNum = 0; OString relType; while (iter != usingSet.end()) { index = (*iter).m_type.lastIndexOf(']'); seqNum = (index > 0 ? ((index+1) / 2) : 0); relType = (*iter).m_type; if (index > 0) relType = relType.copy(index+1); OString defPrefix("IDL"); if ( getBaseType(relType).isEmpty() && m_typeName != relType) { if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) { if (!((*iter).m_use & TYPEUSE_SUPER)) { o << "\n"; dumpNameSpace(o, sal_True, sal_False, relType); o << "\ninterface " << scopedName(m_typeName, relType, sal_True) << ";\n"; dumpNameSpace(o, sal_False, sal_False, relType); o << "\n\n"; } } dumpInclude(o, typeName, relType, prefix); } else if (relType == "type") { o << "module CORBA {\n" << "\tinterface TypeCode;\n" << "};\n\n"; } if( seqNum != 0 ) { // write typedef for sequences to support Rational Rose 2000 import OString aST = relType; OString aScope; dumpNameSpace( o, sal_True, sal_False, relType ); for( sal_uInt32 i = 0; i < seqNum; i++ ) { o << "typedef sequence< " << scopedName("", aST) << " > "; if( i == 0 ) { aST = aST.replace( '/', '_' ); aST = aST.replace( ' ', '_' ); } aST = aST + "_Sequence" ; o << aST << ";\n"; } dumpNameSpace( o, sal_False, sal_False, relType ); } ++iter; } } void IdlType::dumpNameSpace(FileStream& o, sal_Bool bOpen, sal_Bool bFull, const OString& type) { OString typeName(type); sal_Bool bOneLine = sal_True; if ( typeName.isEmpty() ) { typeName = m_typeName; bOneLine = sal_False; } if (typeName == "/") return; if (typeName.indexOf( '/' ) == -1 && !bFull) return; if (!bFull) typeName = typeName.copy( 0, typeName.lastIndexOf( '/' ) ); if (bOpen) { sal_Int32 nIndex = 0; do { o << "module " << typeName.getToken(0, '/', nIndex); if (bOneLine) o << " { "; else o << "\n{\n"; } while( nIndex != -1 ); } else { sal_Int32 nPos = 0; do { nPos = typeName.lastIndexOf( '/' ); o << "};"; if( bOneLine ) o << " "; else o << " /* " << typeName.copy( nPos+1 ) << " */\n"; if( nPos != -1 ) typeName = typeName.copy( 0, nPos ); } while( nPos != -1 ); } } sal_uInt32 IdlType::getMemberCount() { sal_uInt32 count = m_reader.getMethodCount(); sal_uInt32 fieldCount = m_reader.getFieldCount(); RTFieldAccess access = RT_ACCESS_INVALID; for (sal_uInt16 i=0; i < fieldCount; i++) { access = m_reader.getFieldAccess(i); if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) count++; } return count; } sal_uInt32 IdlType::checkInheritedMemberCount(const TypeReader* pReader) { sal_Bool bSelfCheck = sal_True; if (!pReader) { bSelfCheck = sal_False; pReader = &m_reader; } sal_uInt32 count = 0; OString superType(pReader->getSuperTypeName()); if ( !superType.isEmpty() ) { TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); if ( aSuperReader.isValid() ) { count = checkInheritedMemberCount(&aSuperReader); } } if (bSelfCheck) { count += pReader->getMethodCount(); sal_uInt32 fieldCount = pReader->getFieldCount(); RTFieldAccess access = RT_ACCESS_INVALID; for (sal_uInt16 i=0; i < fieldCount; i++) { access = pReader->getFieldAccess(i); if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) { count++; } } } return count; } sal_uInt32 IdlType::getInheritedMemberCount() { if (m_inheritedMemberCount == 0) { m_inheritedMemberCount = checkInheritedMemberCount(0); } return m_inheritedMemberCount; } void IdlType::dumpType(FileStream& o, const OString& type ) throw( CannotDumpException ) { OString sType(checkRealBaseType(type, sal_True)); sal_uInt32 index = sType.lastIndexOf(']'); sal_uInt32 seqNum = (index > 0 ? ((index+1) / 2) : 0); OString relType = (index > 0 ? (sType).copy(index+1) : type); RTTypeClass typeClass = m_typeMgr.getTypeClass(relType); sal_uInt32 i; /* for (i=0; i < seqNum; i++) { //o << "sequence< "; } */ switch (typeClass) { case RT_TYPE_INVALID: { OString tmp(getBaseType(relType)); if ( !tmp.isEmpty() ) { tmp = tmp.replace( ' ', '_' ); o << tmp; } else throw CannotDumpException("Unknown type '" + relType + "', incomplete type library."); } break; case RT_TYPE_INTERFACE: case RT_TYPE_STRUCT: case RT_TYPE_ENUM: case RT_TYPE_TYPEDEF: case RT_TYPE_EXCEPTION: if( seqNum ) { OString aST = relType.replace( '/', '_' ); aST = aST.replace( ' ', '_' ); o << aST; } else o << scopedName(m_typeName, relType); break; } for (i=0; i < seqNum; i++) { //o << " >"; // use typedef for sequences to support Rational Rose 2000 import o << "_Sequence"; } } OString IdlType::getBaseType(const OString& type) { if (type.equals("long")) return type; if (type.equals("short")) return type; if (type.equals("hyper")) return "long long"; if (type.equals("string")) return "string"; if (type.equals("boolean")) return type; if (type.equals("char")) return "char"; if (type.equals("byte")) return "byte"; if (type.equals("any")) return type; if (type.equals("type")) return "CORBA::TypeCode"; if (type.equals("float")) return type; if (type.equals("double")) return type; if (type.equals("octet")) return type; if (type.equals("void")) return type; if (type.equals("unsigned long")) return type; if (type.equals("unsigned short")) return type; if (type.equals("unsigned hyper")) return "unsigned long long"; return OString(); } void IdlType::dumpIdlGetType(FileStream& o, const OString& type, sal_Bool bDecl, IdlTypeDecl eDeclFlag) { OString sType( checkRealBaseType(type, sal_True) ); sal_uInt32 index = sType.lastIndexOf(']'); OString relType = (index > 0 ? (sType).copy(index+1) : type); if (eDeclFlag == CPPUTYPEDECL_ONLYINTERFACES) { if (m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) { o << indent() << "getIdlType( ("; dumpType(o, type); o << "*)0 )"; if (bDecl) o << ";\n"; } } else { if (isBaseType(type)) { return; } else { if (eDeclFlag == CPPUTYPEDECL_NOINTERFACES && m_typeMgr.getTypeClass(relType) == RT_TYPE_INTERFACE) return; // if (m_typeMgr.getTypeClass(type) == RT_TYPE_TYPEDEF) // { // o << indent() << "get_" << type.replace('/', '_') << "_Type()"; // } else // { o << indent() << "getIdlType( ("; dumpType(o, type); o << "*)0 )"; // } } if (bDecl) o << ";\n"; } } BASETYPE IdlType::isBaseType(const OString& type) { if (type.equals("long")) return BT_LONG; if (type.equals("short")) return BT_SHORT; if (type.equals("hyper")) return BT_HYPER; if (type.equals("string")) return BT_STRING; if (type.equals("boolean")) return BT_BOOLEAN; if (type.equals("char")) return BT_CHAR; if (type.equals("byte")) return BT_BYTE; if (type.equals("any")) return BT_ANY; if (type.equals("float")) return BT_FLOAT; if (type.equals("double")) return BT_DOUBLE; if (type.equals("void")) return BT_VOID; if (type.equals("unsigned long")) return BT_UNSIGNED_LONG; if (type.equals("unsigned short")) return BT_UNSIGNED_SHORT; if (type.equals("unsigned hyper")) return BT_UNSIGNED_HYPER; return BT_INVALID; } OString IdlType::checkSpecialIdlType(const OString& type) { OString baseType(type); RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader(); RegistryKey key; sal_uInt8* pBuffer=NULL; RTTypeClass typeClass; sal_Bool isTypeDef = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); TypeReader reader; while (isTypeDef) { reader = m_typeMgr.getTypeReader(baseType); if (reader.isValid()) { typeClass = reader.getTypeClass(); if (typeClass == RT_TYPE_TYPEDEF) baseType = reader.getSuperTypeName(); else isTypeDef = sal_False; } else { break; } } return baseType; } OString IdlType::checkRealBaseType(const OString& type, sal_Bool bResolveTypeOnly) { sal_uInt32 index = type.lastIndexOf(']'); OString baseType = (index > 0 ? ((OString)type).copy(index+1) : type); OString seqPrefix = (index > 0 ? ((OString)type).copy(0, index+1) : OString()); RegistryTypeReaderLoader & rReaderLoader = getRegistryTypeReaderLoader(); RegistryKey key; sal_uInt8* pBuffer=NULL; RTTypeClass typeClass; sal_Bool mustBeChecked = (m_typeMgr.getTypeClass(baseType) == RT_TYPE_TYPEDEF); TypeReader reader; while (mustBeChecked) { reader = m_typeMgr.getTypeReader(baseType); if (reader.isValid()) { typeClass = reader.getTypeClass(); if (typeClass == RT_TYPE_TYPEDEF) { baseType = reader.getSuperTypeName(); index = baseType.lastIndexOf(']'); if (index > 0) { seqPrefix += baseType.copy(0, index+1); baseType = baseType.copy(index+1); } } else mustBeChecked = sal_False; } else { break; } } if ( bResolveTypeOnly ) baseType = seqPrefix + baseType; return baseType; } void IdlType::dumpConstantValue(FileStream& o, sal_uInt16 index) { RTConstValue constValue = m_reader.getFieldConstValue(index); switch (constValue.m_type) { case RT_TYPE_BOOL: if (constValue.m_value.aBool) o << "true"; else o << "false"; break; case RT_TYPE_BYTE: { char tmp[16]; snprintf(tmp, sizeof(tmp), "0x%x", (sal_Int8)constValue.m_value.aByte); o << tmp; } break; case RT_TYPE_INT16: o << constValue.m_value.aShort; break; case RT_TYPE_UINT16: o << constValue.m_value.aUShort; break; case RT_TYPE_INT32: o << constValue.m_value.aLong; break; case RT_TYPE_UINT32: o << constValue.m_value.aULong; break; case RT_TYPE_INT64: { ::rtl::OString tmp( OString::valueOf(constValue.m_value.aHyper) ); o << tmp.getStr(); } break; case RT_TYPE_UINT64: { ::rtl::OString tmp( OString::valueOf((sal_Int64)constValue.m_value.aUHyper) ); o << tmp.getStr(); } break; case RT_TYPE_FLOAT: { ::rtl::OString tmp( OString::valueOf(constValue.m_value.aFloat) ); o << tmp.getStr(); } break; case RT_TYPE_DOUBLE: { ::rtl::OString tmp( OString::valueOf(constValue.m_value.aDouble) ); o << tmp.getStr(); } break; case RT_TYPE_STRING: { ::rtl::OUString aUStr(constValue.m_value.aString); ::rtl::OString aStr = ::rtl::OUStringToOString(aUStr, RTL_TEXTENCODING_ASCII_US); o << "\"" << aStr.getStr() << "\")"; } break; } } void IdlType::inc(sal_uInt32 num) { m_indentLength += num; } void IdlType::dec(sal_uInt32 num) { if (m_indentLength - num < 0) m_indentLength = 0; else m_indentLength -= num; } OString IdlType::indent() { OStringBuffer tmp(m_indentLength); for (sal_uInt32 i=0; i < m_indentLength; i++) { tmp.append(' '); } return tmp.makeStringAndClear(); } OString IdlType::indent(sal_uInt32 num) { OStringBuffer tmp(m_indentLength + num); for (sal_uInt32 i=0; i < m_indentLength + num; i++) { tmp.append(' '); } return tmp.makeStringAndClear(); } //************************************************************************* // InterfaceType //************************************************************************* InterfaceType::InterfaceType(TypeReader& typeReader, const OString& typeName, const TypeManager& typeMgr, const TypeDependency& typeDependencies) : IdlType(typeReader, typeName, typeMgr, typeDependencies) { m_inheritedMemberCount = 0; m_hasAttributes = sal_False; m_hasMethods = sal_False; } InterfaceType::~InterfaceType() { } sal_Bool InterfaceType::dumpHFile(FileStream& o) throw( CannotDumpException ) { OString headerDefine(dumpHeaderDefine(o, "IDL")); o << "\n"; dumpDefaultHIncludes(o); o << "\n"; dumpDepIncludes(o, m_typeName, "idl"); o << "\n"; dumpNameSpace(o); // write documentation OString aDoc = m_reader.getDoku(); if( !aDoc.isEmpty() ) o << "/**\n" << aDoc << "\n*/"; o << "\ninterface " << m_name; OString superType(m_reader.getSuperTypeName()); if ( !superType.isEmpty() ) o << " : " << scopedName(m_typeName, superType); o << "\n{\n"; inc(); dumpAttributes(o); dumpMethods(o); dec(); o << "};\n\n"; dumpNameSpace(o, sal_False); // o << "\nnamespace com { namespace sun { namespace star { namespace uno {\n" // << "class Type;\n} } } }\n\n"; o << "#endif /* "<< headerDefine << "*/" << "\n"; return sal_True; } void InterfaceType::dumpAttributes(FileStream& o) { sal_uInt32 fieldCount = m_reader.getFieldCount(); sal_Bool first=sal_True; RTFieldAccess access = RT_ACCESS_INVALID; OString fieldName; OString fieldType; for (sal_uInt16 i=0; i < fieldCount; i++) { access = m_reader.getFieldAccess(i); if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) continue; fieldName = m_reader.getFieldName(i); fieldType = m_reader.getFieldType(i); if (first) { first = sal_False; o << "\n"; } // write documentation OString aDoc = m_reader.getFieldDoku(i); if( !aDoc.isEmpty() ) o << "/**\n" << aDoc << "\n*/\n"; if (access == RT_ACCESS_READONLY) o << indent() << "readonly attribute "; else o << indent() << "attribute "; dumpType(o, fieldType); o << " " << fieldName << ";\n"; } } void InterfaceType::dumpMethods(FileStream& o) { sal_uInt32 methodCount = m_reader.getMethodCount(); OString methodName, returnType, paramType, paramName; sal_uInt32 paramCount = 0; sal_uInt32 excCount = 0; RTMethodMode methodMode = RT_MODE_INVALID; RTParamMode paramMode = RT_PARAM_INVALID; sal_Bool bRef = sal_False; sal_Bool bConst = sal_False; sal_Bool bWithRunTimeExcp = sal_True; for (sal_Int16 i=0; i < methodCount; i++) { methodName = m_reader.getMethodName(i); returnType = m_reader.getMethodReturnType(i); paramCount = m_reader.getMethodParamCount(i); excCount = m_reader.getMethodExcCount(i); methodMode = m_reader.getMethodMode(i); if ( methodName.equals("acquire") || methodName.equals("release") ) { bWithRunTimeExcp = sal_False; } // write documentation OString aDoc = m_reader.getMethodDoku(i); if( !aDoc.isEmpty() ) o << "/**\n" << aDoc << "\n*/\n"; o << indent(); dumpType(o, returnType); o << " " << methodName << "( "; sal_uInt16 j; for (j=0; j < paramCount; j++) { paramName = m_reader.getMethodParamName(i, j); paramType = m_reader.getMethodParamType(i, j); paramMode = m_reader.getMethodParamMode(i, j); switch (paramMode) { case RT_PARAM_IN: o << "in "; break; case RT_PARAM_OUT: o << "out "; break; case RT_PARAM_INOUT: o << "inout "; break; break; } dumpType(o, paramType); if( paramName == "Object" ) o << " _Object"; else o << " " << paramName; if (j+1 < paramCount) o << ", "; } o << " )"; if( excCount ) { o << " raises("; OString excpName; sal_Bool bWriteComma = sal_False; sal_Bool bRTExceptionWritten = sal_False; for (j=0; j < excCount; j++) { excpName = m_reader.getMethodExcType(i, j); if( bWriteComma ) o << ", "; o << scopedName(m_typeName, excpName); bWriteComma = sal_True; if(excpName == "com/sun/star/uno/RuntimeException") bRTExceptionWritten = sal_True; } if ( bWithRunTimeExcp && !bRTExceptionWritten ) { if( bWriteComma ) o << ", "; o << "::com::sun::star::uno::RuntimeException"; } o << ");\n"; } else if ( bWithRunTimeExcp ) { o << "raises( ::com::sun::star::uno::RuntimeException );\n"; } else { o << ";\n"; } } } sal_uInt32 InterfaceType::getMemberCount() { sal_uInt32 count = m_reader.getMethodCount(); if (count) m_hasMethods = sal_True; sal_uInt32 fieldCount = m_reader.getFieldCount(); RTFieldAccess access = RT_ACCESS_INVALID; for (sal_uInt16 i=0; i < fieldCount; i++) { access = m_reader.getFieldAccess(i); if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) { m_hasAttributes = sal_True; count++; } } return count; } sal_uInt32 InterfaceType::checkInheritedMemberCount(const TypeReader* pReader) { sal_uInt32 cout = 0; sal_Bool bSelfCheck = sal_True; if (!pReader) { bSelfCheck = sal_False; pReader = &m_reader; } sal_uInt32 count = 0; OString superType(pReader->getSuperTypeName()); if ( !superType.isEmpty() ) { TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); if (aSuperReader.isValid()) { count = checkInheritedMemberCount(&aSuperReader); } } if (bSelfCheck) { count += pReader->getMethodCount(); sal_uInt32 fieldCount = pReader->getFieldCount(); RTFieldAccess access = RT_ACCESS_INVALID; for (sal_uInt16 i=0; i < fieldCount; i++) { access = pReader->getFieldAccess(i); if (access != RT_ACCESS_CONST && access != RT_ACCESS_INVALID) { count++; } } } return count; } sal_uInt32 InterfaceType::getInheritedMemberCount() { if (m_inheritedMemberCount == 0) { m_inheritedMemberCount = checkInheritedMemberCount(0); } return m_inheritedMemberCount; } //************************************************************************* // ModuleType //************************************************************************* ModuleType::ModuleType(TypeReader& typeReader, const OString& typeName, const TypeManager& typeMgr, const TypeDependency& typeDependencies) : IdlType(typeReader, typeName, typeMgr, typeDependencies) { } ModuleType::~ModuleType() { } sal_Bool ModuleType::dump(IdlOptions* pOptions) throw( CannotDumpException ) { sal_Bool ret = sal_False; OString outPath; if (pOptions->isValid("-O")) outPath = pOptions->getOption("-O"); OString tmpName(m_typeName); if (tmpName.equals("/")) tmpName = "global"; else // tmpName += "/" + m_typeName.getToken(m_typeName.getTokenCount('/') - 1, '/'); tmpName += "/" + m_name; OString tmpFileName; OString hFileName = createFileNameFromType(outPath, tmpName, ".idl"); sal_Bool bFileExists = sal_False; sal_Bool bFileCheck = sal_False; if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) { bFileExists = fileExists( hFileName ); ret = sal_True; } if ( bFileExists && pOptions->isValid("-Gc") ) { tmpFileName = createFileNameFromType(outPath, m_typeName, ".tml"); bFileCheck = sal_True; } if ( !bFileExists || bFileCheck ) { FileStream hFile; if ( bFileCheck ) hFile.open(tmpFileName); else hFile.open(hFileName); if(!hFile.isValid()) { OString message("cannot open "); message += hFileName + " for writing"; throw CannotDumpException(message); } ret = dumpHFile(hFile); hFile.close(); if (ret && bFileCheck) { ret = checkFileContent(hFileName, tmpFileName); } } return ret; } sal_Bool ModuleType::dumpHFile(FileStream& o) throw( CannotDumpException ) { OString headerDefine(dumpHeaderDefine(o, "IDL")); o << "\n"; dumpDefaultHIncludes(o); o << "\n"; dumpDepIncludes(o, m_typeName, "idl"); o << "\n"; dumpNameSpace(o, sal_True, sal_True); o << "\n"; sal_uInt32 fieldCount = m_reader.getFieldCount(); RTFieldAccess access = RT_ACCESS_INVALID; OString fieldName; OString fieldType; for (sal_uInt16 i=0; i < fieldCount; i++) { access = m_reader.getFieldAccess(i); if (access == RT_ACCESS_CONST) { fieldName = m_reader.getFieldName(i); fieldType = m_reader.getFieldType(i); o << "const "; dumpType(o, fieldType); o << " " << fieldName << " = "; dumpConstantValue(o, i); o << ";\n"; } } o << "\n"; dumpNameSpace(o, sal_False, sal_True); o << "\n#endif /* "<< headerDefine << "*/" << "\n"; return sal_True; } sal_Bool ModuleType::hasConstants() { sal_uInt32 fieldCount = m_reader.getFieldCount(); RTFieldAccess access = RT_ACCESS_INVALID; for (sal_uInt16 i=0; i < fieldCount; i++) { access = m_reader.getFieldAccess(i); if (access == RT_ACCESS_CONST) return sal_True; } return sal_False; } //************************************************************************* // ConstantsType //************************************************************************* ConstantsType::ConstantsType(TypeReader& typeReader, const OString& typeName, const TypeManager& typeMgr, const TypeDependency& typeDependencies) : ModuleType(typeReader, typeName, typeMgr, typeDependencies) { } ConstantsType::~ConstantsType() { } sal_Bool ConstantsType::dump(IdlOptions* pOptions) throw( CannotDumpException ) { sal_Bool ret = sal_False; OString outPath; if (pOptions->isValid("-O")) outPath = pOptions->getOption("-O"); OString tmpFileName; OString hFileName = createFileNameFromType(outPath, m_typeName, ".idl"); sal_Bool bFileExists = sal_False; sal_Bool bFileCheck = sal_False; if ( pOptions->isValid("-G") || pOptions->isValid("-Gc") ) { bFileExists = fileExists( hFileName ); ret = sal_True; } if ( bFileExists && pOptions->isValid("-Gc") ) { tmpFileName = createFileNameFromType(outPath, m_typeName, ".tml"); bFileCheck = sal_True; } if ( !bFileExists || bFileCheck ) { FileStream hFile; if ( bFileCheck ) hFile.open(tmpFileName); else hFile.open(hFileName); if(!hFile.isValid()) { OString message("cannot open "); message += hFileName + " for writing"; throw CannotDumpException(message); } ret = dumpHFile(hFile); hFile.close(); if (ret && bFileCheck) { ret = checkFileContent(hFileName, tmpFileName); } } return ret; } //************************************************************************* // StructureType //************************************************************************* StructureType::StructureType(TypeReader& typeReader, const OString& typeName, const TypeManager& typeMgr, const TypeDependency& typeDependencies) : IdlType(typeReader, typeName, typeMgr, typeDependencies) { } StructureType::~StructureType() { } sal_Bool StructureType::dumpHFile(FileStream& o) throw( CannotDumpException ) { OString headerDefine(dumpHeaderDefine(o, "IDL")); o << "\n"; dumpDefaultHIncludes(o); o << "\n"; dumpDepIncludes(o, m_typeName, "idl"); o << "\n"; dumpNameSpace(o); // write documentation OString aDoc = m_reader.getDoku(); if( !aDoc.isEmpty() ) o << "/**\n" << aDoc << "\n*/"; o << "\nstruct " << m_name; o << "\n{\n"; inc(); OString superType(m_reader.getSuperTypeName()); if ( !superType.isEmpty() ) dumpSuperMember(o, superType); sal_uInt32 fieldCount = m_reader.getFieldCount(); RTFieldAccess access = RT_ACCESS_INVALID; OString fieldName; OString fieldType; sal_uInt16 i=0; for (i=0; i < fieldCount; i++) { access = m_reader.getFieldAccess(i); if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) continue; fieldName = m_reader.getFieldName(i); fieldType = m_reader.getFieldType(i); // write documentation OString aDoc = m_reader.getFieldDoku(i); if( !aDoc.isEmpty() ) o << "/**\n" << aDoc << "\n*/"; o << indent(); dumpType(o, fieldType); o << " " << fieldName << ";\n"; } dec(); o << "};\n\n"; dumpNameSpace(o, sal_False); o << "#endif /* "<< headerDefine << "*/" << "\n"; return sal_True; } void StructureType::dumpSuperMember(FileStream& o, const OString& superType) { if ( !superType.isEmpty() ) { TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); if (aSuperReader.isValid()) { dumpSuperMember(o, aSuperReader.getSuperTypeName()); sal_uInt32 fieldCount = aSuperReader.getFieldCount(); RTFieldAccess access = RT_ACCESS_INVALID; OString fieldName; OString fieldType; for (sal_uInt16 i=0; i < fieldCount; i++) { access = aSuperReader.getFieldAccess(i); if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) continue; fieldName = aSuperReader.getFieldName(i); fieldType = aSuperReader.getFieldType(i); // write documentation OString aDoc = aSuperReader.getFieldDoku(i); if( !aDoc.isEmpty() ) o << "/**\n" << aDoc << "\n*/"; o << indent(); dumpType(o, fieldType); o << " "; o << fieldName << ";\n"; } } } } //************************************************************************* // ExceptionType //************************************************************************* ExceptionType::ExceptionType(TypeReader& typeReader, const OString& typeName, const TypeManager& typeMgr, const TypeDependency& typeDependencies) : IdlType(typeReader, typeName, typeMgr, typeDependencies) { } ExceptionType::~ExceptionType() { } sal_Bool ExceptionType::dumpHFile(FileStream& o) throw( CannotDumpException ) { OString headerDefine(dumpHeaderDefine(o, "IDL")); o << "\n"; dumpDefaultHIncludes(o); o << "\n"; dumpDepIncludes(o, m_typeName, "idl"); o << "\n"; dumpNameSpace(o); // write documentation OString aDoc = m_reader.getDoku(); if( !aDoc.isEmpty() ) o << "/**\n" << aDoc << "\n*/"; o << "\nexception " << m_name; o << "\n{\n"; inc(); // Write extra member for derived exceptions o << indent() << "/*extra member to hold a derived exception */\n"; o << indent() << "any _derivedException;\n"; OString superType(m_reader.getSuperTypeName()); if ( !superType.isEmpty() ) dumpSuperMember(o, superType); sal_uInt32 fieldCount = m_reader.getFieldCount(); RTFieldAccess access = RT_ACCESS_INVALID; OString fieldName; OString fieldType; sal_uInt16 i = 0; for (i=0; i < fieldCount; i++) { access = m_reader.getFieldAccess(i); if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) continue; fieldName = m_reader.getFieldName(i); fieldType = m_reader.getFieldType(i); // write documentation OString aDoc = m_reader.getFieldDoku(i); if( !aDoc.isEmpty() ) o << "/**\n" << aDoc << "\n*/"; o << indent(); dumpType(o, fieldType); o << " " << fieldName << ";\n"; } dec(); o << "};\n\n"; dumpNameSpace(o, sal_False); o << "#endif /* "<< headerDefine << "*/" << "\n"; return sal_True; } void ExceptionType::dumpSuperMember(FileStream& o, const OString& superType) { if ( !superType.isEmpty() ) { TypeReader aSuperReader(m_typeMgr.getTypeReader(superType)); if (aSuperReader.isValid()) { dumpSuperMember(o, aSuperReader.getSuperTypeName()); sal_uInt32 fieldCount = aSuperReader.getFieldCount(); RTFieldAccess access = RT_ACCESS_INVALID; OString fieldName; OString fieldType; for (sal_uInt16 i=0; i < fieldCount; i++) { access = aSuperReader.getFieldAccess(i); if (access == RT_ACCESS_CONST || access == RT_ACCESS_INVALID) continue; fieldName = aSuperReader.getFieldName(i); fieldType = aSuperReader.getFieldType(i); // write documentation OString aDoc = aSuperReader.getFieldDoku(i); if( !aDoc.isEmpty() ) o << "/**\n" << aDoc << "\n*/"; o << indent(); dumpType(o, fieldType); o << " "; o << fieldName << ";\n"; } } } } //************************************************************************* // EnumType //************************************************************************* EnumType::EnumType(TypeReader& typeReader, const OString& typeName, const TypeManager& typeMgr, const TypeDependency& typeDependencies) : IdlType(typeReader, typeName, typeMgr, typeDependencies) { } EnumType::~EnumType() { } sal_Bool EnumType::dumpHFile(FileStream& o) throw( CannotDumpException ) { OString headerDefine(dumpHeaderDefine(o, "IDL")); o << "\n"; dumpDefaultHIncludes(o); o << "\n"; dumpNameSpace(o); // write documentation OString aDoc = m_reader.getDoku(); if( !aDoc.isEmpty() ) o << "/**\n" << aDoc << "\n*/"; o << "\nenum " << m_name << "\n{\n"; inc(); sal_uInt32 fieldCount = m_reader.getFieldCount(); RTFieldAccess access = RT_ACCESS_INVALID; RTConstValue constValue; OString fieldName; sal_uInt32 value=0; for (sal_uInt16 i=0; i < fieldCount; i++) { access = m_reader.getFieldAccess(i); if (access != RT_ACCESS_CONST) continue; fieldName = m_reader.getFieldName(i); constValue = m_reader.getFieldConstValue(i); if (constValue.m_type == RT_TYPE_INT32) value = constValue.m_value.aLong; else value++; /* doesn't work with rational rose 2000 // write documentation OString aDoc = m_reader.getFieldDoku(i); if( aDoc.getLength() ) */ // o << "/**\n" << aDoc << "\n*/\n"; o << indent() << fieldName; if( i +1 < fieldCount ) o << ",\n"; } dec(); o << "\n};\n\n"; dumpNameSpace(o, sal_False); o << "#endif /* "<< headerDefine << "*/" << "\n"; return sal_True; } //************************************************************************* // TypeDefType //************************************************************************* TypeDefType::TypeDefType(TypeReader& typeReader, const OString& typeName, const TypeManager& typeMgr, const TypeDependency& typeDependencies) : IdlType(typeReader, typeName, typeMgr, typeDependencies) { } TypeDefType::~TypeDefType() { } sal_Bool TypeDefType::dumpHFile(FileStream& o) throw( CannotDumpException ) { OString headerDefine(dumpHeaderDefine(o, "IDL")); o << "\n"; dumpDefaultHIncludes(o); o << "\n"; dumpDepIncludes(o, m_typeName, "idl"); o << "\n"; dumpNameSpace(o); o << "\ntypedef "; dumpType(o, m_reader.getSuperTypeName()); o << " " << m_name << ";\n\n"; dumpNameSpace(o, sal_False); o << "#endif /* "<< headerDefine << "*/" << "\n"; return sal_True; } //************************************************************************* // produceType //************************************************************************* sal_Bool produceType(const OString& typeName, TypeManager& typeMgr, TypeDependency& typeDependencies, IdlOptions* pOptions) throw( CannotDumpException ) { if (typeDependencies.isGenerated(typeName)) return sal_True; TypeReader reader(typeMgr.getTypeReader(typeName)); if (!reader.isValid()) { if (typeName.equals("/")) return sal_True; else return sal_False; } if( !checkTypeDependencies(typeMgr, typeDependencies, typeName)) return sal_False; RTTypeClass typeClass = reader.getTypeClass(); sal_Bool ret = sal_False; switch (typeClass) { case RT_TYPE_INTERFACE: { InterfaceType iType(reader, typeName, typeMgr, typeDependencies); ret = iType.dump(pOptions); if (ret) typeDependencies.setGenerated(typeName); ret = iType.dumpDependedTypes(pOptions); } break; case RT_TYPE_MODULE: { ModuleType mType(reader, typeName, typeMgr, typeDependencies); if (mType.hasConstants()) { ret = mType.dump(pOptions); if (ret) typeDependencies.setGenerated(typeName); // ret = mType.dumpDependedTypes(pOptions); } else { typeDependencies.setGenerated(typeName); ret = sal_True; } } break; case RT_TYPE_STRUCT: { StructureType sType(reader, typeName, typeMgr, typeDependencies); ret = sType.dump(pOptions); if (ret) typeDependencies.setGenerated(typeName); ret = sType.dumpDependedTypes(pOptions); } break; case RT_TYPE_ENUM: { EnumType enType(reader, typeName, typeMgr, typeDependencies); ret = enType.dump(pOptions); if (ret) typeDependencies.setGenerated(typeName); ret = enType.dumpDependedTypes(pOptions); } break; case RT_TYPE_EXCEPTION: { ExceptionType eType(reader, typeName, typeMgr, typeDependencies); ret = eType.dump(pOptions); if (ret) typeDependencies.setGenerated(typeName); ret = eType.dumpDependedTypes(pOptions); } break; case RT_TYPE_TYPEDEF: { TypeDefType tdType(reader, typeName, typeMgr, typeDependencies); ret = tdType.dump(pOptions); if (ret) typeDependencies.setGenerated(typeName); ret = tdType.dumpDependedTypes(pOptions); } break; case RT_TYPE_CONSTANTS: { ConstantsType cType(reader, typeName, typeMgr, typeDependencies); if (cType.hasConstants()) { ret = cType.dump(pOptions); if (ret) typeDependencies.setGenerated(typeName); // ret = cType.dumpDependedTypes(pOptions); } else { typeDependencies.setGenerated(typeName); ret = sal_True; } } break; case RT_TYPE_SERVICE: case RT_TYPE_OBJECT: ret = sal_True; break; } return ret; } //************************************************************************* // scopedName //************************************************************************* OString scopedName(const OString& scope, const OString& type, sal_Bool bNoNameSpace) { sal_Int32 nPos = type.lastIndexOf( '/' ); if (nPos == -1) return type; if (bNoNameSpace) return type.copy(nPos+1); OStringBuffer tmpBuf(type.getLength()*2); nPos = 0; do { tmpBuf.append("::"); tmpBuf.append(type.getToken(0, '/', nPos)); } while( nPos != -1 ); return tmpBuf.makeStringAndClear(); } //************************************************************************* // shortScopedName //************************************************************************* OString scope(const OString& scope, const OString& type ) { sal_Int32 nPos = type.lastIndexOf( '/' ); if( nPos == -1 ) return OString(); // scoped name only if the namespace is not equal if (scope.lastIndexOf('/') > 0) { OString tmpScp(scope.copy(0, scope.lastIndexOf('/'))); OString tmpScp2(type.copy(0, nPos)); if (tmpScp == tmpScp2) return OString(); } OString aScope( type.copy( 0, nPos ) ); OStringBuffer tmpBuf(aScope.getLength()*2); nPos = 0; do { tmpBuf.append("::"); tmpBuf.append(aScope.getToken(0, '/', nPos)); } while( nPos != -1 ); return tmpBuf.makeStringAndClear(); }