NCBI C++ ToolKit
datatool.cpp
Go to the documentation of this file.
00001 /*  $Id: datatool.cpp 54522 2012-05-18 12:18:50Z gouriano $
00002 * ===========================================================================
00003 *
00004 *                            PUBLIC DOMAIN NOTICE
00005 *               National Center for Biotechnology Information
00006 *
00007 *  This software/database is a "United States Government Work" under the
00008 *  terms of the United States Copyright Act.  It was written as part of
00009 *  the author's official duties as a United States Government employee and
00010 *  thus cannot be copyrighted.  This software/database is freely available
00011 *  to the public for use. The National Library of Medicine and the U.S.
00012 *  Government have not placed any restriction on its use or reproduction.
00013 *
00014 *  Although all reasonable efforts have been taken to ensure the accuracy
00015 *  and reliability of the software and data, the NLM and the U.S.
00016 *  Government do not and cannot warrant the performance or results that
00017 *  may be obtained by using this software or data. The NLM and the U.S.
00018 *  Government disclaim all warranties, express or implied, including
00019 *  warranties of performance, merchantability or fitness for any particular
00020 *  purpose.
00021 *
00022 *  Please cite the author in any work or product based on this material.
00023 *
00024 * ===========================================================================
00025 *
00026 * Author: Eugene Vasilchenko
00027 *
00028 * File Description:
00029 *   main datatool file: argument processing and task manager
00030 */
00031 
00032 #include <ncbi_pch.hpp>
00033 #include <corelib/ncbistd.hpp>
00034 #include <corelib/ncbiargs.hpp>
00035 
00036 #include <serial/objistr.hpp>
00037 #include <serial/objistrasnb.hpp>
00038 #include <serial/objostr.hpp>
00039 #include <serial/objcopy.hpp>
00040 
00041 #include <memory>
00042 
00043 #include "exceptions.hpp"
00044 #include "code.hpp"
00045 #include "lexer.hpp"
00046 #include "dtdlexer.hpp"
00047 #include "parser.hpp"
00048 #include "dtdparser.hpp"
00049 #include "xsdlexer.hpp"
00050 #include "xsdparser.hpp"
00051 #include "wsdllexer.hpp"
00052 #include "wsdlparser.hpp"
00053 #include "moduleset.hpp"
00054 #include "module.hpp"
00055 #include "type.hpp"
00056 #include "generate.hpp"
00057 #include "datatool.hpp"
00058 #include "filecode.hpp"
00059 #include "traversal_code_generator.hpp"
00060 #include <serial/objistrxml.hpp>
00061 #include <serial/objostrxml.hpp>
00062 #include <serial/error_codes.hpp>
00063 
00064 
00065 #define NCBI_USE_ERRCODE_X   Serial_DataTool
00066 
00067 
00068 BEGIN_NCBI_SCOPE
00069 
00070 int CDataTool::Run(void)
00071 {
00072     if ( !ProcessModules() )
00073         return 1;
00074     if ( !ProcessData() )
00075         return 1;
00076     if ( !GenerateCode() )
00077         return 1;
00078 
00079     return 0;
00080 }
00081 
00082 CDataTool::CDataTool(void)
00083 {
00084     SetVersion( CVersionInfo(2,5,0) );
00085 }
00086 
00087 void CDataTool::Init(void)
00088 {
00089     SetDiagPostLevel(eDiag_Warning);
00090 
00091     auto_ptr<CArgDescriptions> d(new CArgDescriptions);
00092 
00093     d->SetUsageContext("datatool", "work with ASN.1/XML data");
00094 
00095     // module arguments
00096     d->AddKey("m", "moduleFile",
00097               "module file(s)",
00098               CArgDescriptions::eString,
00099               CArgDescriptions::fAllowMultiple);
00100     d->AddDefaultKey("M", "externalModuleFile",
00101                      "external module file(s)",
00102                      CArgDescriptions::eString, NcbiEmptyString,
00103                      CArgDescriptions::fAllowMultiple);
00104     d->AddFlag("i",
00105                "ignore unresolved symbols");
00106     d->AddOptionalKey("f", "moduleFile",
00107                       "write ASN.1 module file",
00108                       CArgDescriptions::eOutputFile);
00109     d->AddOptionalKey("fx", "dtdFile",
00110                       "write DTD file (\"-fx m\" writes modular DTD file)",
00111                       CArgDescriptions::eOutputFile);
00112     d->AddOptionalKey("fxs", "XMLSchemaFile",
00113                       "write XML Schema file (\"-fxs m\" writes modular Schema file)",
00114                       CArgDescriptions::eOutputFile);
00115     d->AddOptionalKey("fd", "SpecificationDump",
00116                       "write specification dump file (datatool internal format)",
00117                       CArgDescriptions::eOutputFile);
00118     d->AddOptionalKey("ms", "moduleSuffix",
00119                       "suffix of modular DTD or Schema file name",
00120                       CArgDescriptions::eString);
00121 
00122     // data arguments
00123     d->AddOptionalKey("v", "valueFile",
00124                       "read value in ASN.1 text format",
00125                       CArgDescriptions::eInputFile);
00126     d->AddOptionalKey("vx", "valueFile",
00127                       "read value in XML format",
00128                       CArgDescriptions::eInputFile);
00129     d->AddOptionalKey("d", "valueFile",
00130                       "read value in ASN.1 binary format (-t is required)",
00131                       CArgDescriptions::eInputFile);
00132     d->AddOptionalKey("tvs", "traversalSpecFile",
00133                       "read traversal specification file",
00134                       CArgDescriptions::eInputFile);
00135     d->AddOptionalKey("t", "type",
00136                       "binary value type (see \"-d\" argument)",
00137                       CArgDescriptions::eString);
00138     d->AddOptionalKey("dn", "filename",
00139                       "DTD module name in XML header (no extension). "
00140                       "If empty, omit DOCTYPE line.",
00141                       CArgDescriptions::eString);
00142     d->AddFlag("F",
00143                "read value completely into memory");
00144     d->AddOptionalKey("p", "valueFile",
00145                       "write value in ASN.1 text format",
00146                       CArgDescriptions::eOutputFile);
00147     d->AddOptionalKey("px", "valueFile",
00148                       "write value in XML format",
00149                       CArgDescriptions::eOutputFile);
00150     d->AddOptionalKey("pj", "valueFile",
00151                       "write value in JSON format",
00152                       CArgDescriptions::eOutputFile);
00153     d->AddOptionalKey("xmlns", "namespaceName",
00154                       "XML namespace name",
00155                       CArgDescriptions::eString);
00156     d->AddOptionalKey("e", "valueFile",
00157                       "write value in ASN.1 binary format",
00158                       CArgDescriptions::eOutputFile);
00159     d->AddFlag("sxo",
00160                "no scope prefixes in XML output");
00161     d->AddFlag("sxi",
00162                "no scope prefixes in XML input");
00163 
00164     // code generation arguments
00165     d->AddOptionalKey("oex", "exportSpec",
00166                       "class export specifier for MSVC",
00167                       CArgDescriptions::eString);
00168     d->AddOptionalKey("od", "defFile",
00169                       "code definition file",
00170                       CArgDescriptions::eInputFile);
00171     d->AddFlag("odi",
00172                "silently ignore absent code definition file");
00173     d->AddFlag("odw",
00174                "issue a warning about absent code definition file");
00175     d->AddFlag("ods",
00176                "generate sample definition file");
00177     d->AddOptionalKey("of", "listFile",
00178                       "write list of generated C++ files",
00179                       CArgDescriptions::eOutputFile);
00180     d->AddOptionalKey("oc", "basename",
00181                       "write combining C++ files",
00182                       CArgDescriptions::eString);
00183     d->AddFlag("oA",
00184                "generate C++ files for all types");
00185     d->AddOptionalKey("ot", "types",
00186                       "generate C++ files for listed types",
00187                       CArgDescriptions::eString);
00188     d->AddOptionalKey("ox", "types",
00189                       "exclude listed types from generation",
00190                       CArgDescriptions::eString);
00191     d->AddFlag("oX",
00192                "turn off recursive type generation");
00193 
00194     d->AddOptionalKey("on", "namespace",
00195                       "default namespace", 
00196                       CArgDescriptions::eString);
00197 
00198     d->AddOptionalKey("opm", "directory",
00199                       "directory for searching source modules",
00200                       CArgDescriptions::eString);
00201     d->AddOptionalKey("oph", "directory",
00202                       "directory for generated *.hpp files",
00203                       CArgDescriptions::eString);
00204     d->AddOptionalKey("opc", "directory",
00205                       "directory for generated *.cpp files",
00206                       CArgDescriptions::eString);
00207 
00208     d->AddOptionalKey("or", "prefix",
00209                       "add prefix to generated file names",
00210                       CArgDescriptions::eString);
00211     d->AddFlag("orq",
00212                "use quoted syntax form for generated include files");
00213     d->AddFlag("ors",
00214                "add source file dir to generated file names");
00215     d->AddFlag("orm",
00216                "add module name to generated file names");
00217     d->AddFlag("orA",
00218                "combine all -or* prefixes");
00219     d->AddFlag("ocvs",
00220                "create \".cvsignore\" files");
00221     d->AddOptionalKey("oR", "rootDirectory",
00222                       "set \"-o*\" arguments for NCBI directory tree",
00223                       CArgDescriptions::eString);
00224 
00225     d->AddFlag("oDc",
00226                "turn on generation of DOXYGEN-style comments");
00227     d->AddOptionalKey("odx", "URL",
00228                       "URL of documentation root folder (for DOXYGEN)",
00229                       CArgDescriptions::eString);
00230     d->AddFlag("lax_syntax",
00231                "allow non-standard ASN.1 syntax accepted by asntool");
00232     d->AddOptionalKey("pch", "file",
00233                       "name of the precompiled header to include in all *.cpp files",
00234                       CArgDescriptions::eString);
00235 
00236     SetupArgDescriptions(d.release());
00237 }
00238 
00239 bool CDataTool::ProcessModules(void)
00240 {
00241     const CArgs& args = GetArgs();
00242 
00243     // load generator config
00244     if ( const CArgValue& od = args["od"] )
00245         generator.LoadConfig(od.AsString(), args["odi"], args["odw"]);
00246 
00247     list<string> modulesPath;
00248     string opt;
00249 
00250     if ( generator.GetOpt("oR", &opt) ) {
00251         // NCBI directory tree
00252         const string& rootDir = opt;
00253         generator.SetRootDir(rootDir);
00254         generator.SetHPPDir(Path(rootDir, "include"));
00255         string srcDir = Path(rootDir, "src");
00256         generator.SetCPPDir(srcDir);
00257         modulesPath.push_back(srcDir);
00258         generator.SetFileNamePrefixSource(eFileName_FromSourceFileName);
00259         generator.SetDefaultNamespace("NCBI_NS_NCBI::objects");
00260     }
00261     
00262     if ( generator.GetOpt("opm", &opt) ) {
00263 //        modulesPath.clear();
00264         NStr::Split(opt, ",", modulesPath);
00265     }
00266     
00267     SourceFile::EType srctype =
00268         LoadDefinitions(generator.GetMainModules(),
00269                         modulesPath, args["m"].GetStringList(), false);
00270     
00271     if (srctype == SourceFile::eASN) {
00272         LoadDefinitions(generator.GetImportModules(),
00273                         modulesPath, args["M"].GetStringList(), true, srctype);
00274     }
00275 
00276     if ( args["sxo"] ) {
00277         CDataType::SetEnforcedStdXml(true);
00278     }
00279 
00280     if ( const CArgValue& f = args["f"] ) {
00281         generator.GetMainModules().PrintASN(f.AsOutputFile());
00282         f.CloseFile();
00283     }
00284     if ( const CArgValue& f = args["fd"] ) {
00285         generator.GetMainModules().PrintSpecDump(f.AsOutputFile());
00286         f.CloseFile();
00287     }
00288 
00289     if ( const CArgValue& fx = args["fx"] ) {
00290         if (srctype == SourceFile::eDTD ||
00291             srctype == SourceFile::eXSD ||
00292             srctype == SourceFile::eWSDL) {
00293             CDataType::SetEnforcedStdXml(true);
00294         }
00295         if ( fx.AsString() == "m" ) {
00296             if ( const CArgValue& ms = args["ms"] ) {
00297                 CDataTypeModule::SetModuleFileSuffix(ms.AsString());
00298             }
00299             generator.ResolveImportRefs();
00300             CDataType::EnableDTDEntities(true);
00301             generator.GetMainModules().PrintDTDModular();
00302         } else {
00303             generator.GetMainModules().PrintDTD(fx.AsOutputFile());
00304             fx.CloseFile();
00305         }
00306     }
00307 
00308     if ( const CArgValue& ax = args["fxs"] ) {
00309         if (srctype == SourceFile::eDTD ||
00310             srctype == SourceFile::eXSD ||
00311             srctype == SourceFile::eWSDL) {
00312             CDataType::SetEnforcedStdXml(true);
00313         }
00314         if ( ax.AsString() == "m" ) {
00315             if ( const CArgValue& ms = args["ms"] ) {
00316                 CDataTypeModule::SetModuleFileSuffix(ms.AsString());
00317             }
00318             generator.ResolveImportRefs();
00319             generator.GetMainModules().PrintXMLSchemaModular();
00320         } else {
00321             generator.GetMainModules().PrintXMLSchema(ax.AsOutputFile());
00322             ax.CloseFile();
00323         }
00324     }
00325 
00326     if ( !generator.Check() ) {
00327         if ( !args["i"] ) { // ignored
00328             ERR_POST_X(1, "some types are unknown");
00329             return false;
00330         }
00331         else {
00332             ERR_POST_X(2, Warning << "some types are unknown: ignoring");
00333         }
00334     }
00335     return true;
00336 }
00337 
00338 bool CDataTool::ProcessData(void)
00339 {    
00340     const CArgs& args = GetArgs();
00341     bool stdXmlIn = false;
00342     if ( args["sxi"] ) {
00343         stdXmlIn = true;
00344     }
00345     bool stdXmlOut = false;
00346     if ( args["sxo"] ) {
00347         stdXmlOut = true;
00348     }
00349 
00350     // convert data
00351     ESerialDataFormat inFormat;
00352     string inFileName;
00353     const CArgValue& t = args["t"];
00354     
00355     if ( const CArgValue& v = args["v"] ) {
00356         inFormat = eSerial_AsnText;
00357         inFileName = v.AsString();
00358     }
00359     else if ( const CArgValue& vx = args["vx"] ) {
00360         inFormat = eSerial_Xml;
00361         inFileName = vx.AsString();
00362     }
00363     else if ( const CArgValue& d = args["d"] ) {
00364         if ( !t ) {
00365             ERR_POST_X(3, "ASN.1 value type must be specified (-t)");
00366             return false;
00367         }
00368         inFormat = eSerial_AsnBinary;
00369         inFileName = d.AsString();
00370     }
00371     else // no input data
00372         return true;
00373 
00374     auto_ptr<CObjectIStream>
00375         in(CObjectIStream::Open(inFormat, inFileName, eSerial_StdWhenAny));
00376     if (inFormat == eSerial_Xml) {
00377         CObjectIStreamXml *is = dynamic_cast<CObjectIStreamXml*>(in.get());
00378         if (stdXmlIn) {
00379             is->SetEnforcedStdXml(true);
00380         }
00381         is->SetDefaultStringEncoding(eEncoding_Unknown);
00382     }
00383 
00384     TTypeInfo typeInfo;
00385     string typeName;
00386     if ( t ) {
00387         typeName = t.AsString();
00388         if (typeName != "?") {
00389             in->ReadFileHeader();
00390         }
00391     }
00392     else {
00393         typeName = in->ReadFileHeader();
00394     }
00395 
00396     bool type_guessed = false;
00397     if (typeName != "?") {
00398         typeInfo =
00399             generator.GetMainModules().ResolveInAnyModule(typeName, true)->
00400             GetTypeInfo().Get();
00401     } else {
00402         type_guessed = true;
00403         set<TTypeInfo> known_types;
00404         generator.GetMainModules().CollectAllTypeinfo(known_types);
00405         set<TTypeInfo> matching_types = in->GuessDataType(known_types, 16);
00406         if (matching_types.size() == 0) {
00407             NCBI_THROW(CNotFoundException,eType,"No typeinfo matches");
00408         } else if (matching_types.size() == 1) {
00409             typeInfo = *matching_types.begin();
00410         } else {
00411             string msg("Multiple typeinfo matches:");
00412             ITERATE(set<TTypeInfo>, ti, matching_types) {
00413                 msg += " " + (*ti)->GetName();
00414             }
00415             NCBI_THROW(CNotFoundException,eType,msg);
00416         }
00417         in->ReadFileHeader();
00418     }
00419     
00420     // determine output data file
00421     ESerialDataFormat outFormat;
00422     string outFileName;
00423     bool use_nsName = false;
00424     string nsName;
00425     
00426     if ( const CArgValue& p = args["p"] ) {
00427         outFormat = eSerial_AsnText;
00428         outFileName = p.AsString();
00429     }
00430     else if ( const CArgValue& px = args["px"] ) {
00431         outFormat = eSerial_Xml;
00432         outFileName = px.AsString();
00433         if ( const CArgValue& px_ns = args["xmlns"] ) {
00434             use_nsName = true;
00435             nsName = px_ns.AsString();
00436         }
00437     }
00438     else if ( const CArgValue& pj = args["pj"] ) {
00439         outFormat = eSerial_Json;
00440         outFileName = pj.AsString();
00441     }
00442     else if ( const CArgValue& e = args["e"] ) {
00443         outFormat = eSerial_AsnBinary;
00444         outFileName = e.AsString();
00445     }
00446     else {
00447         if (typeName == "?") {
00448             ERR_POST_X(4, "Data type: " << typeInfo->GetName());
00449         }
00450         // no input data
00451         outFormat = eSerial_None;
00452     }
00453 
00454     if ( args["F"] ) {
00455         // read fully in memory
00456         AnyType value;
00457         in->Read(&value, typeInfo, CObjectIStream::eNoFileHeader);
00458         if ( outFormat != eSerial_None ) {
00459             // store data
00460             auto_ptr<CObjectOStream>
00461                 out(CObjectOStream::Open(outFormat, outFileName,
00462                                          eSerial_StdWhenAny));
00463             if ( outFormat == eSerial_Xml ) {
00464                 CObjectOStreamXml *os = dynamic_cast<CObjectOStreamXml*>(out.get());
00465                 if (stdXmlOut) {
00466                     os->SetEnforcedStdXml(true);
00467                 }
00468                 os->SetDefaultStringEncoding(eEncoding_Unknown);
00469                 if (use_nsName) {
00470                     os->SetReferenceSchema(true);
00471                     if (!nsName.empty()) {
00472                         os->SetDefaultSchemaNamespace(nsName);
00473                     }
00474                 }
00475                 // Set DTD file name (default prefix is added in any case)
00476                 if( const CArgValue& dn = args["dn"] ) {
00477                     const string& name = dn.AsString();
00478                     if ( name.empty() ) {
00479                         os->SetReferenceDTD(false);
00480                     }
00481                     else {
00482                         os->SetReferenceDTD(true);
00483                         os->SetDTDFileName(name);
00484                     }
00485                 }
00486             }
00487             out->Write(&value, typeInfo);
00488         }
00489     }
00490     else {
00491         if ( outFormat != eSerial_None ) {
00492             // copy
00493             auto_ptr<CObjectOStream>
00494                 out(CObjectOStream::Open(outFormat, outFileName,
00495                                          eSerial_StdWhenAny));
00496             if ( outFormat == eSerial_Xml ) {
00497                 CObjectOStreamXml *os = dynamic_cast<CObjectOStreamXml*>(out.get());
00498                 if (stdXmlOut) {
00499                     os->SetEnforcedStdXml(true);
00500                 }
00501                 os->SetDefaultStringEncoding(eEncoding_Unknown);
00502                 if (use_nsName) {
00503                     os->SetReferenceSchema(true);
00504                     if (!nsName.empty()) {
00505                         os->SetDefaultSchemaNamespace(nsName);
00506                     }
00507                 }
00508                 // Set DTD file name (default prefix is added in any case)
00509                 if( const CArgValue& dn = args["dn"] ) {
00510                     const string& name = dn.AsString();
00511                     if ( name.empty() ) {
00512                         os->SetReferenceDTD(false);
00513                     }
00514                     else {
00515                         os->SetReferenceDTD(true);
00516                         os->SetDTDFileName(name);
00517                     }
00518                 }
00519             }
00520             CObjectStreamCopier copier(*in, *out);
00521             copier.Copy(typeInfo, CObjectStreamCopier::eNoFileHeader);
00522             // In case the input stream has more than one object of this type,
00523             // keep converting them
00524             {
00525                 set<TTypeInfo> known;
00526                 known.insert(typeInfo);
00527                 for (bool go=true; go; ) {
00528                     try {
00529                         set<TTypeInfo> matching = in->GuessDataType(known,2);
00530                         go = !matching.empty() &&
00531                              *matching.begin() == *known.begin();
00532                         if (go) {
00533                             copier.Copy(typeInfo);
00534                         }
00535                     } catch (CEofException&) {
00536                         go = false;
00537                     }
00538                 }
00539             }
00540         }
00541         else {
00542             // skip
00543             if (!type_guessed) {
00544                 in->Skip(typeInfo, CObjectIStream::eNoFileHeader);
00545             }
00546         }
00547     }
00548     return true;
00549 }
00550 
00551 bool CDataTool::GenerateCode(void)
00552 {
00553     string opt;
00554     //if ( const CArgValue& oD = args["oD"] )
00555     //    generator.AddConfigLine(oD.AsString());
00556 
00557     // set list of types for generation
00558     if ( generator.GetOpt("oX") )
00559         generator.ExcludeRecursion();
00560     if ( generator.GetOpt("oA") )
00561         generator.IncludeAllMainTypes();
00562     if ( generator.GetOpt("ot", &opt) )
00563         generator.IncludeTypes(opt);
00564     if ( generator.GetOpt("ox", &opt) )
00565         generator.ExcludeTypes(opt);
00566 
00567     if ( !generator.HaveGenerateTypes() )
00568         return true;
00569 
00570     // set the export specifier, if provided
00571     if ( generator.GetOpt("oex", &opt) ) {
00572         string ex;
00573         ex = generator.GetConfig().Get("-","_export");
00574         if (ex.empty()) {
00575             ex = opt;
00576         }
00577         CClassCode::SetExportSpecifier(ex);
00578     }
00579     // define the Doxygen group
00580     {
00581         if ( generator.GetOpt("oDc") ) {
00582             CClassCode::SetDoxygenComments(true);
00583             if ( generator.GetOpt("odx", &opt) ) {
00584                 string root = opt;
00585                 if (root.empty()) {
00586                     // default
00587                     root = "http://www.ncbi.nlm.nih.gov/IEB/ToolBox/CPP_DOC/lxr/source";
00588                 }
00589                 CClassCode::SetDocRootURL(root);
00590             }
00591             string group = generator.GetConfig().Get("-","_addtogroup_name");
00592             CClassCode::SetDoxygenGroup(group);
00593             group = generator.GetConfig().Get("-","_ingroup_name");
00594             generator.SetDoxygenIngroup(group);
00595             group = generator.GetConfig().Get("-","_addtogroup_description");
00596             generator.SetDoxygenGroupDescription(group);
00597         } else {
00598             CClassCode::SetDoxygenComments(false);
00599         }
00600     }
00601 
00602     // prepare generator
00603     
00604     // set namespace
00605     opt = "";
00606     if ( generator.GetOpt("on", &opt) ) {
00607         generator.SetDefaultNamespace(opt);
00608     } else if (opt == "-") {
00609         generator.ResetDefaultNamespace();
00610     }
00611     
00612     // set output files
00613     if ( generator.GetOpt("oc", &opt) ) {
00614         const string& fileName = opt;
00615         generator.SetCombiningFileName(fileName);
00616         generator.SetFileListFileName(fileName+".files");
00617     }
00618     if ( generator.GetOpt("of", &opt) )
00619         generator.SetFileListFileName(opt);
00620     
00621     // set directories
00622     if ( generator.GetOpt("oph", &opt) )
00623         generator.SetHPPDir(opt);
00624     if ( generator.GetOpt("opc", &opt) )
00625         generator.SetCPPDir(opt);
00626     
00627     // set file names prefixes
00628     if ( generator.GetOpt("or", &opt) )
00629         generator.SetFileNamePrefix(opt);
00630     if ( generator.GetOpt("orq") )
00631         generator.UseQuotedForm(true);
00632     if ( generator.GetOpt("ocvs") )
00633         generator.CreateCvsignore(true);
00634     if ( generator.GetOpt("ors") )
00635         generator.SetFileNamePrefixSource(eFileName_FromSourceFileName);
00636     if ( generator.GetOpt("orm") )
00637         generator.SetFileNamePrefixSource(eFileName_FromModuleName);
00638     if ( generator.GetOpt("orA") )
00639         generator.SetFileNamePrefixSource(eFileName_UseAllPrefixes);
00640 
00641     // precompiled header
00642     if ( generator.GetOpt("pch", &opt) )
00643         CFileCode::SetPchHeader(opt);
00644     
00645     cout << GetFullVersion().Print(GetProgramDisplayName(), CVersion::fVersionInfo);
00646     // generate code
00647     generator.GenerateCode();
00648 
00649     if ( GetArgs()["ods"] ) {
00650         generator.GetMainModules().PrintSampleDEF(generator.GetCPPDir());
00651     }
00652 
00653     // also generate traversal code if requested
00654     const CArgValue& tvs = GetArgs()["tvs"];
00655     if( tvs ) {
00656         CNcbiIstream& traversal_spec_file = tvs.AsInputFile();
00657 
00658         try {
00659             CStopWatch total_code_generation_stop_watch(CStopWatch::eStart);
00660             CTraversalCodeGenerator traversal_code_generator( 
00661                 generator.GetMainModules(),
00662                 traversal_spec_file );
00663             ERR_POST_X(2, Info << "Total seconds to generate traversal code: " << total_code_generation_stop_watch.Restart() );
00664         } catch( exception &ex ) {
00665             cerr << "Exception: " << ex.what() << endl;
00666         }
00667     }
00668 
00669     return true;
00670 }
00671 
00672 SourceFile::EType CDataTool::LoadDefinitions(
00673     CFileSet& fileSet, const list<string>& modulesPath,
00674     const CArgValue::TStringArray& nameList,
00675     bool split_names, SourceFile::EType srctype)
00676 {
00677     SourceFile::EType moduleType;
00678     list<string> names;
00679 
00680     ITERATE (CArgValue::TStringArray, n, nameList) {
00681         if (split_names) {
00682             list<string> t;
00683             NStr::Split(*n, " ", t);
00684             names.insert(names.end(), t.begin(), t.end());
00685         } else {
00686             names.push_back(*n);
00687         }
00688     }
00689 
00690     ITERATE ( list<string>, fi, names ) {
00691         string name = *fi;
00692         if ( !name.empty() ) {
00693             SourceFile fName(name, modulesPath);
00694             moduleType = fName.GetType();
00695 
00696 // if first module has unknown type - assume ASN
00697             if (srctype == SourceFile::eUnknown) {
00698                 if (moduleType == SourceFile::eUnknown) {
00699                     moduleType = SourceFile::eASN;
00700                 }
00701                 srctype = moduleType;
00702             }
00703 // if second module has unknown type - assume same as the previous one
00704             else {
00705                 if (moduleType == SourceFile::eUnknown) {
00706                     moduleType = srctype;
00707                 }
00708 // if modules have different types - exception
00709                 else if (moduleType != srctype) {
00710                     NCBI_THROW(CDatatoolException,eWrongInput,
00711                                "Unable to process modules of different types"
00712                                " simultaneously: "+name);
00713                 }
00714             }
00715 
00716             switch (moduleType) {
00717             default:
00718                 NCBI_THROW(CDatatoolException,eWrongInput,"Unknown file type: "+name);
00719 
00720             case SourceFile::eASN:
00721                 {
00722                     ASNLexer lexer(fName,name);
00723                     lexer.AllowIDsEndingWithMinus(generator.GetOpt("lax_syntax"));
00724                     ASNParser parser(lexer);
00725                     fileSet.AddFile(parser.Modules(name));
00726                 }
00727                 break;
00728             case SourceFile::eDTD:
00729                 {
00730                     DTDLexer lexer(fName,name);
00731                     DTDParser parser(lexer);
00732                     fileSet.AddFile(parser.Modules(name));
00733                     CDataType::SetXmlSourceSpec(true);
00734                 }
00735                 break;
00736             case SourceFile::eXSD:
00737                 {
00738                     name = fName.GetFileName();
00739             XSDLexer lexer(fName,name);
00740                     XSDParser parser(lexer);
00741                     fileSet.AddFile(parser.Modules(name));
00742                     CDataType::SetXmlSourceSpec(true);
00743                 }
00744                 break;
00745             case SourceFile::eWSDL:
00746                 {
00747                     name = fName.GetFileName();
00748                     WSDLLexer lexer(fName,name);
00749                     WSDLParser parser(lexer);
00750                     fileSet.AddFile(parser.Modules(name));
00751                     CDataType::SetXmlSourceSpec(true);
00752                 }
00753                 break;
00754             }
00755         }
00756     }
00757     return srctype;
00758 }
00759 
00760 END_NCBI_SCOPE
00761 
00762 int NcbiSys_main(int argc, ncbi::TXChar* argv[])
00763 {
00764     USING_NCBI_SCOPE;
00765     CException::EnableBackgroundReporting(false);
00766     return CDataTool().AppMain(argc, argv, 0, eDS_Default, 0, _T_XSTRING("datatool"));
00767 }
Modified on Wed May 23 13:21:15 2012 by modify_doxy.py rev. 337098