module.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:17k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: module.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:43:21  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.36
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: module.cpp,v 1000.1 2004/06/01 19:43:21 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author: Eugene Vasilchenko
  35. *
  36. * File Description:
  37. *   Data descriptions module: equivalent of ASN.1 module
  38. *
  39. * ---------------------------------------------------------------------------
  40. * $Log: module.cpp,v $
  41. * Revision 1000.1  2004/06/01 19:43:21  gouriano
  42. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.36
  43. *
  44. * Revision 1.36  2004/05/17 21:03:14  gorelenk
  45. * Added include of PCH ncbi_pch.hpp
  46. *
  47. * Revision 1.35  2003/06/16 14:41:05  gouriano
  48. * added possibility to convert DTD to XML schema
  49. *
  50. * Revision 1.34  2003/05/14 14:42:22  gouriano
  51. * added generation of XML schema
  52. *
  53. * Revision 1.33  2003/04/29 18:31:09  gouriano
  54. * object data member initialization verification
  55. *
  56. * Revision 1.32  2003/03/11 20:06:47  kuznets
  57. * iterate -> ITERATE
  58. *
  59. * Revision 1.31  2003/03/10 18:55:18  gouriano
  60. * use new structured exceptions (based on CException)
  61. *
  62. * Revision 1.30  2001/05/17 15:07:12  lavr
  63. * Typos corrected
  64. *
  65. * Revision 1.29  2000/11/29 17:42:44  vasilche
  66. * Added CComment class for storing/printing ASN.1/XML module comments.
  67. * Added srcutil.hpp file to reduce file dependency.
  68. *
  69. * Revision 1.28  2000/11/20 17:26:32  vasilche
  70. * Fixed warnings on 64 bit platforms.
  71. * Updated names of config variables.
  72. *
  73. * Revision 1.27  2000/11/15 20:34:55  vasilche
  74. * Added user comments to ENUMERATED types.
  75. * Added storing of user comments to ASN.1 module definition.
  76. *
  77. * Revision 1.26  2000/11/14 21:41:25  vasilche
  78. * Added preserving of ASN.1 definition comments.
  79. *
  80. * Revision 1.25  2000/11/08 17:02:51  vasilche
  81. * Added generation of modular DTD files.
  82. *
  83. * Revision 1.24  2000/09/26 17:38:26  vasilche
  84. * Fixed incomplete choiceptr implementation.
  85. * Removed temporary comments.
  86. *
  87. * Revision 1.23  2000/08/25 15:59:22  vasilche
  88. * Renamed directory tool -> datatool.
  89. *
  90. * Revision 1.22  2000/07/10 17:32:00  vasilche
  91. * Macro arguments made more clear.
  92. * All old ASN stuff moved to serialasn.hpp.
  93. * Changed prefix of enum info functions to GetTypeInfo_enum_.
  94. *
  95. * Revision 1.21  2000/06/16 20:01:30  vasilche
  96. * Avoid use of unexpected_exception() which is unimplemented on Mac.
  97. *
  98. * Revision 1.20  2000/05/24 20:09:29  vasilche
  99. * Implemented DTD generation.
  100. *
  101. * Revision 1.19  2000/04/07 19:26:29  vasilche
  102. * Added namespace support to datatool.
  103. * By default with argument -oR datatool will generate objects in namespace
  104. * NCBI_NS_NCBI::objects (aka ncbi::objects).
  105. * Datatool's classes also moved to NCBI namespace.
  106. *
  107. * Revision 1.18  2000/02/01 21:48:02  vasilche
  108. * Added CGeneratedChoiceTypeInfo for generated choice classes.
  109. * Removed CMemberInfo subclasses.
  110. * Added support for DEFAULT/OPTIONAL members.
  111. * Changed class generation.
  112. * Moved datatool headers to include/internal/serial/tool.
  113. *
  114. * Revision 1.17  1999/12/30 21:33:40  vasilche
  115. * Changed arguments - more structured.
  116. * Added intelligence in detection of source directories.
  117. *
  118. * Revision 1.16  1999/12/29 16:01:51  vasilche
  119. * Added explicit virtual destructors.
  120. * Resolved overloading of InternalResolve.
  121. *
  122. * Revision 1.15  1999/12/28 18:55:59  vasilche
  123. * Reduced size of compiled object files:
  124. * 1. avoid inline or implicit virtual methods (especially destructors).
  125. * 2. avoid std::string's methods usage in inline methods.
  126. * 3. avoid string literals ("xxx") in inline methods.
  127. *
  128. * Revision 1.14  1999/12/21 17:18:36  vasilche
  129. * Added CDelayedFostream class which rewrites file only if contents is changed.
  130. *
  131. * Revision 1.13  1999/12/20 21:00:19  vasilche
  132. * Added generation of sources in different directories.
  133. *
  134. * Revision 1.12  1999/11/22 21:04:49  vasilche
  135. * Cleaned main interface headers. Now generated files should include serial/serialimpl.hpp and user code should include serial/serial.hpp which became might lighter.
  136. *
  137. * Revision 1.11  1999/11/15 19:36:17  vasilche
  138. * Fixed warnings on GCC
  139. *
  140. * ===========================================================================
  141. */
  142. #include <ncbi_pch.hpp>
  143. #include <corelib/ncbistd.hpp>
  144. #include <corelib/ncbidiag.hpp>
  145. #include <corelib/ncbireg.hpp>
  146. #include <serial/datatool/module.hpp>
  147. #include <serial/datatool/exceptions.hpp>
  148. #include <serial/datatool/type.hpp>
  149. #include <serial/datatool/srcutil.hpp>
  150. #include <serial/datatool/fileutil.hpp>
  151. #include <typeinfo>
  152. BEGIN_NCBI_SCOPE
  153. CDataTypeModule::CDataTypeModule(const string& n)
  154.     : m_Errors(false), m_Name(n)
  155. {
  156. }
  157. CDataTypeModule::~CDataTypeModule()
  158. {
  159. }
  160. void CDataTypeModule::AddDefinition(const string& name,
  161.                                     const AutoPtr<CDataType>& type)
  162. {
  163.     CDataType*& oldType = m_LocalTypes[name];
  164.     if ( oldType ) {
  165.         type->Warning("redefinition, original: " +
  166.                       oldType->LocationString());
  167.         m_Errors = true;
  168.         return;
  169.     }
  170.     CDataType* dataType = type.get();
  171.     oldType = dataType;
  172.     m_Definitions.push_back(make_pair(name, type));
  173.     dataType->SetParent(this, name);
  174. }
  175. void CDataTypeModule::AddExports(const TExports& exports)
  176. {
  177.     m_Exports.insert(m_Exports.end(), exports.begin(), exports.end());
  178. }
  179. void CDataTypeModule::AddImports(const TImports& imports)
  180. {
  181.     m_Imports.insert(m_Imports.end(), imports.begin(), imports.end());
  182. }
  183. void CDataTypeModule::AddImports(const string& module, const list<string>& types)
  184. {
  185.     AutoPtr<Import> import(new Import());
  186.     import->moduleName = module;
  187.     import->types.insert(import->types.end(), types.begin(), types.end());
  188.     m_Imports.push_back(import);
  189. }
  190. void CDataTypeModule::PrintASN(CNcbiOstream& out) const
  191. {
  192.     m_Comments.PrintASN(out, 0, CComments::eMultiline);
  193.     out <<
  194.         GetName() << " DEFINITIONS ::=n"
  195.         "BEGINn"
  196.         "n";
  197.     if ( !m_Exports.empty() ) {
  198.         out << "EXPORTS ";
  199.         ITERATE ( TExports, i, m_Exports ) {
  200.             if ( i != m_Exports.begin() )
  201.                 out << ", ";
  202.             out << *i;
  203.         }
  204.         out <<
  205.             ";n"
  206.             "n";
  207.     }
  208.     if ( !m_Imports.empty() ) {
  209.         out << "IMPORTS ";
  210.         ITERATE ( TImports, m, m_Imports ) {
  211.             if ( m != m_Imports.begin() )
  212.                 out <<
  213.                     "n"
  214.                     "        ";
  215.             const Import& imp = **m;
  216.             ITERATE ( list<string>, i, imp.types ) {
  217.                 if ( i != imp.types.begin() )
  218.                     out << ", ";
  219.                 out << *i;
  220.             }
  221.             out << " FROM " << imp.moduleName;
  222.         }
  223.         out <<
  224.             ";n"
  225.             "n";
  226.     }
  227.     ITERATE ( TDefinitions, i, m_Definitions ) {
  228.         i->second->PrintASNTypeComments(out, 0);
  229.         out << i->first << " ::= ";
  230.         i->second->PrintASN(out, 0);
  231.         out <<
  232.             "n"
  233.             "n";
  234.     }
  235.     m_LastComments.PrintASN(out, 0, CComments::eMultiline);
  236.     out <<
  237.         "ENDn"
  238.         "n";
  239. }
  240. void CDataTypeModule::PrintDTD(CNcbiOstream& out) const
  241. {
  242.     out <<
  243.         "<!-- ============================================ -->n"
  244.         "<!-- This section is mapped from module "" << GetName() << ""n"
  245.         "================================================= -->n";
  246.     m_Comments.PrintDTD(out, CComments::eMultiline);
  247.     if ( !m_Exports.empty() ) {
  248.         out <<
  249.             "<!-- Elements used by other modules:n";
  250.         ITERATE ( TExports, i, m_Exports ) {
  251.             if ( i != m_Exports.begin() )
  252.                 out << ",n";
  253.             out << "          " << *i;
  254.         }
  255.         out << " -->nn";
  256.     }
  257.     if ( !m_Imports.empty() ) {
  258.         out <<
  259.             "<!-- Elements referenced from other modules:n";
  260.         ITERATE ( TImports, i, m_Imports ) {
  261.             if ( i != m_Imports.begin() )
  262.                 out << ",n";
  263.             const Import* imp = i->get();
  264.             ITERATE ( list<string>, t, imp->types ) {
  265.                 if ( t != imp->types.begin() )
  266.                     out << ",n";
  267.                 out <<
  268.                     "          " << *t;
  269.             }
  270.             out << " FROM "<< imp->moduleName;
  271.         }
  272.         out << " -->nn";
  273.     }
  274.     if ( !m_Exports.empty() || !m_Imports.empty() ) {
  275.         out <<
  276.             "<!-- ============================================ -->n";
  277.     }
  278.     out << "n";
  279.     ITERATE ( TDefinitions, i, m_Definitions ) {
  280.         out <<
  281.             "<!-- Definition of "<<i->first<<" -->n"
  282.             "n";
  283.         i->second->PrintDTD(out);
  284.         out <<
  285.             "n"
  286.             "n"
  287.             "n";
  288.     }
  289.     m_LastComments.PrintDTD(out, CComments::eMultiline);
  290.     out <<
  291.         "n"
  292.         "n"
  293.         "n"
  294.         "n";
  295. }
  296. // XML schema generator submitted by
  297. // Marc Dumontier, Blueprint initiative, dumontier@mshri.on.ca
  298. void CDataTypeModule::PrintXMLSchema(CNcbiOstream& out) const
  299. {
  300.     out <<
  301.         "<!-- ============================================ -->n"
  302.         "<!-- This section is mapped from module "" << GetName() << ""n"
  303.         "================================================= -->n";
  304.                                                                                                                                     
  305.     m_Comments.PrintDTD(out, CComments::eMultiline);
  306.     if ( !m_Exports.empty() ) {
  307.         out <<
  308.             "<!-- Elements used by other modules:n";
  309.         ITERATE ( TExports, i, m_Exports ) {
  310.             if ( i != m_Exports.begin() )
  311.                 out << ",n";
  312.             out << "          " << *i;
  313.         }
  314.         out << " -->nn";
  315.     }
  316.     if ( !m_Imports.empty() ) {
  317.         out <<
  318.             "<!-- Elements referenced from other modules:n";
  319.         ITERATE ( TImports, i, m_Imports ) {
  320.             if ( i != m_Imports.begin() )
  321.                 out << ",n";
  322.             const Import* imp = i->get();
  323.             ITERATE ( list<string>, t, imp->types ) {
  324.                 if ( t != imp->types.begin() )
  325.                     out << ",n";
  326.                 out <<
  327.                     "          " << *t;
  328.             }
  329.             out << " FROM "<< imp->moduleName;
  330.         }
  331.         out << " -->nn";
  332.     }
  333.     if ( !m_Exports.empty() || !m_Imports.empty() ) {
  334.         out <<
  335.             "<!-- ============================================ -->n";
  336.     }
  337.     out << "n";
  338.     ITERATE ( TDefinitions, i, m_Definitions ) {
  339.         i->second->PrintXMLSchema(out);
  340.     }
  341.     m_LastComments.PrintDTD(out, CComments::eMultiline);
  342. }
  343. static
  344. string DTDFileNameBase(const string& name)
  345. {
  346.     string res;
  347.     ITERATE ( string, i, name ) {
  348.         char c = *i;
  349.         if ( c == '-' )
  350.             res += '_';
  351.         else
  352.             res += c;
  353.     }
  354.     return res;
  355. }
  356. static
  357. string DTDPublicModuleName(const string& name)
  358. {
  359.     string res;
  360.     ITERATE ( string, i, name ) {
  361.         char c = *i;
  362.         if ( !isalnum(c) )
  363.             res += ' ';
  364.         else
  365.             res += c;
  366.     }
  367.     return res;
  368. }
  369. string CDataTypeModule::GetDTDPublicName(void) const
  370. {
  371.     return DTDPublicModuleName(GetName());
  372. }
  373. string CDataTypeModule::GetDTDFileNameBase(void) const
  374. {
  375.     return DTDFileNameBase(GetName());
  376. }
  377. static
  378. void PrintModularDTDModuleReference(CNcbiOstream& out, const string name)
  379. {
  380.     string fileName = DTDFileNameBase(name);
  381.     string pubName = DTDPublicModuleName(name);
  382.     out <<
  383.         "n"
  384.         "<!ENTITY % "<<fileName<<"_module PUBLIC "-//NCBI//"<<pubName<<" Module//EN" ""<<fileName<<".mod">n"
  385.         "%"<<fileName<<"_module;n";
  386. }
  387. void CDataTypeModule::PrintDTDModular(CNcbiOstream& out) const
  388. {
  389.     out <<
  390.         "<!-- "<<DTDFileNameBase(GetName())<<".dtdn"
  391.         "  This file is built from a series of basic modules.n"
  392.         "  The actual ELEMENT and ENTITY declarations are in the modules.n"
  393.         "  This file is used to put them together.n"
  394.         "-->n";
  395.     PrintModularDTDModuleReference(out, "NCBI-Entity");
  396.     PrintModularDTDModuleReference(out, GetName());
  397.     ITERATE ( TImports, i, m_Imports ) {
  398.         PrintModularDTDModuleReference(out, (*i)->moduleName);
  399.     }
  400. }
  401. bool CDataTypeModule::Check()
  402. {
  403.     bool ok = true;
  404.     ITERATE ( TDefinitions, d, m_Definitions ) {
  405.         if ( !d->second->Check() )
  406.             ok = false;
  407.     }
  408.     return ok;
  409. }
  410. bool CDataTypeModule::CheckNames()
  411. {
  412.     bool ok = true;
  413.     ITERATE ( TExports, e, m_Exports ) {
  414.         const string& name = *e;
  415.         TTypesByName::iterator it = m_LocalTypes.find(name);
  416.         if ( it == m_LocalTypes.end() ) {
  417.             ERR_POST(Warning << "undefined export type: " << name);
  418.             ok = false;
  419.         }
  420.         else {
  421.             m_ExportedTypes[name] = it->second;
  422.         }
  423.     }
  424.     ITERATE ( TImports, i, m_Imports ) {
  425.         const Import& imp = **i;
  426.         const string& module = imp.moduleName;
  427.         ITERATE ( list<string>, t, imp.types ) {
  428.             const string& name = *t;
  429.             if ( m_LocalTypes.find(name) != m_LocalTypes.end() ) {
  430.                 ERR_POST(Warning <<
  431.                          "import conflicts with local definition: " << name);
  432.                 ok = false;
  433.                 continue;
  434.             }
  435.             pair<TImportsByName::iterator, bool> ins =
  436.                 m_ImportedTypes.insert(TImportsByName::value_type(name, module));
  437.             if ( !ins.second ) {
  438.                 ERR_POST(Warning << "duplicated import: " << name);
  439.                 ok = false;
  440.                 continue;
  441.             }
  442.         }
  443.     }
  444.     return ok;
  445. }
  446. CDataType* CDataTypeModule::ExternalResolve(const string& typeName,
  447.                                             bool allowInternal) const
  448. {
  449.     const TTypesByName& types = allowInternal? m_LocalTypes: m_ExportedTypes;
  450.     TTypesByName::const_iterator t = types.find(typeName);
  451.     if ( t != types.end() )
  452.         return t->second;
  453.     if ( !allowInternal &&
  454.          m_LocalTypes.find(typeName) != m_LocalTypes.end() ) {
  455.         NCBI_THROW(CNotFoundException,eType, "not exported type: "+typeName);
  456.     }
  457.     NCBI_THROW(CNotFoundException,eType, "undefined type: "+typeName);
  458. }
  459. CDataType* CDataTypeModule::Resolve(const string& typeName) const
  460. {
  461.     TTypesByName::const_iterator t = m_LocalTypes.find(typeName);
  462.     if ( t != m_LocalTypes.end() )
  463.         return t->second;
  464.     TImportsByName::const_iterator i = m_ImportedTypes.find(typeName);
  465.     if ( i != m_ImportedTypes.end() )
  466.         return GetModuleContainer().InternalResolve(i->second, typeName);
  467.     NCBI_THROW(CNotFoundException,eType, "undefined type: "+typeName);
  468. }
  469. string CDataTypeModule::GetFileNamePrefix(void) const
  470. {
  471.     _TRACE("module " << m_Name << ": " << GetModuleContainer().GetFileNamePrefixSource());
  472.     if ( MakeFileNamePrefixFromModuleName() ) {
  473.         if ( m_PrefixFromName.empty() )
  474.             m_PrefixFromName = Identifier(m_Name);
  475.         _TRACE("module " << m_Name << ": "" << m_PrefixFromName << """);
  476.         if ( UseAllFileNamePrefixes() ) {
  477.             return Path(GetModuleContainer().GetFileNamePrefix(),
  478.                         m_PrefixFromName);
  479.         }
  480.         else {
  481.             return m_PrefixFromName;
  482.         }
  483.     }
  484.     return GetModuleContainer().GetFileNamePrefix();
  485. }
  486. const string CDataTypeModule::GetVar(const string& typeName,
  487.                                       const string& varName) const
  488. {
  489.     _ASSERT(!typeName.empty());
  490.     _ASSERT(!varName.empty());
  491.     const CNcbiRegistry& registry = GetConfig();
  492.     {
  493.         const string& s = registry.Get(GetName() + '.' + typeName, varName);
  494.         if ( !s.empty() )
  495.             return s;
  496.     }
  497.     {
  498.         const string& s = registry.Get(typeName, varName);
  499.         if ( !s.empty() )
  500.             return s;
  501.     }
  502.     {
  503.         const string& s = registry.Get(GetName(), varName);
  504.         if ( !s.empty() )
  505.             return s;
  506.     }
  507.     // default section
  508.     return registry.Get("-", varName);
  509. }
  510. END_NCBI_SCOPE