|
NCBI C++ ToolKit
|
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 }
1.7.5.1
Modified on Wed May 23 13:21:15 2012 by modify_doxy.py rev. 337098