00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef NCL_NXSREADER_H
00021 #define NCL_NXSREADER_H
00022
00023 #include "ncl/nxsdefs.h"
00024 #include "ncl/nxsstring.h"
00025 #include "ncl/nxsexception.h"
00026 #include "ncl/nxstoken.h"
00027
00028 class NxsBlock;
00029 class NxsBlockFactory;
00030 class NxsTaxaBlockFactory;
00031 class NxsAssumptionsBlockAPI;
00032 class NxsCharactersBlockAPI;
00033 class NxsTaxaBlockAPI;
00034 class NxsTreesBlockAPI;
00035
00036 typedef std::list<NxsBlock *> BlockReaderList;
00037 typedef std::map<std::string, BlockReaderList> BlockTypeToBlockList;
00038
00039
00118 class NxsReader
00119 {
00120 static void installNCLSignalHandler();
00121 static void uninstallNCLSignalHandler();
00122 public:
00124 enum WarningHandlingMode
00125 {
00126 IGNORE_WARNINGS,
00127 WARNINGS_TO_STDERR,
00128 WARNINGS_TO_STDOUT,
00129 WARNINGS_ARE_ERRORS
00130 };
00132 enum NxsWarnLevel
00133 {
00134 UNCOMMON_SYNTAX_WARNING = 0,
00135 SKIPPING_CONTENT_WARNING = 1,
00136 OVERWRITING_CONTENT_WARNING = 2,
00137 DEPRECATED_WARNING = 3,
00138 AMBIGUOUS_CONTENT_WARNING = 4,
00139 ILLEGAL_CONTENT_WARNING = 5,
00140 PROBABLY_INCORRECT_CONTENT_WARNING = 6,
00141 FATAL_WARNING = 7,
00142 SUPPRESS_WARNINGS_LEVEL = 8
00143 };
00144
00149 static void setNCLCatchesSignals(bool);
00154 static bool getNCLCatchesSignals();
00159 static unsigned getNumSignalIntsCaught();
00163 static void setNumSignalsIntsCaught(unsigned);
00164
00165
00166 NxsReader();
00167 virtual ~NxsReader();
00168
00169
00170
00171 virtual void Add(NxsBlock *newBlock);
00172 void Detach(NxsBlock *newBlock);
00173 virtual void AddFactory(NxsBlockFactory *);
00174 void RemoveFactory(NxsBlockFactory *);
00175
00176
00177 virtual void Execute(NxsToken& token, bool notifyStartStop = true);
00178
00179
00180 void ReadFilepath(const char *filename);
00181 void ReadFilestream(std::istream & inf);
00182 void ReadStringAsNexusContent(const std::string & s);
00183
00184 virtual void DebugReportBlock(NxsBlock &nexusBlock);
00185
00186 const char *NCLNameAndVersion();
00187 const char *NCLCopyrightNotice();
00188 const char *NCLHomePageURL();
00189
00190
00191 virtual void ExecuteStarting();
00192 virtual void ExecuteStopping();
00193 virtual bool EnteringBlock(NxsString blockName);
00194 virtual void ExitingBlock(NxsString blockName);
00195 virtual void OutputComment(const NxsString &comment);
00196 virtual void SkippingDisabledBlock(NxsString blockName);
00197 virtual void SkippingBlock(NxsString blockName);
00198
00207 virtual void NexusWarn(const std::string &s, NxsWarnLevel warnLevel, file_pos pos, long line, long col)
00208 {
00209 if (warnLevel >= PROBABLY_INCORRECT_CONTENT_WARNING)
00210 {
00211 NxsString e(s.c_str());
00212 throw NxsException(e, pos, line, col);
00213 }
00214 }
00216 void NexusWarnToken(const std::string &m, NxsWarnLevel warnLevel, const ProcessedNxsToken &token)
00217 {
00218 NexusWarn(m , warnLevel, token.GetFilePosition(), token.GetLineNumber(), token.GetColumnNumber());
00219 }
00221 void NexusWarnToken(const std::string &m, NxsWarnLevel warnLevel, const NxsToken &token)
00222 {
00223 NexusWarn(m , warnLevel, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
00224 }
00225
00227 virtual void NexusError(NxsString msg, file_pos pos, long line, long col);
00228
00229
00230
00231 virtual void ClearUsedBlockList();
00232 NxsBlock *CreateBlockFromFactories(const std::string & currBlockName, NxsToken &token, NxsBlockFactory **sourceOfBlock = NULL);
00233 BlockReaderList GetUsedBlocksInOrder();
00234 BlockReaderList GetBlocksFromLastExecuteInOrder();
00235 BlockTypeToBlockList GetUsedBlocks();
00236 std::set<NxsBlock*> GetSetOfAllUsedBlocks();
00237
00238 NxsTaxaBlockAPI *GetLastStoredTaxaBlock();
00239 NxsCharactersBlockAPI *GetLastStoredCharactersBlock();
00240 NxsTreesBlockAPI *GetLastStoredTreesBlock();
00241
00242
00243 NxsTaxaBlockAPI *GetTaxaBlockByTitle(const char *title, unsigned *nMatches);
00244 NxsCharactersBlockAPI *GetCharBlockByTitle(const char *title, unsigned *nMatches);
00245 NxsTreesBlockAPI *GetTreesBlockByTitle(const char *title, unsigned *nMatches);
00246
00247 NxsTaxaBlockFactory *GetTaxaBlockFactory();
00248
00249
00250
00251 void SetTaxaBlockFactory(NxsTaxaBlockFactory *);
00252
00253
00254
00255 virtual void DeleteBlocksFromFactories();
00256 unsigned RemoveBlockFromUsedBlockList(NxsBlock *);
00257
00268 virtual void ClearContent();
00269
00281 virtual void AddReadBlock(const NxsString &blockID, NxsBlock *block)
00282 {
00283 this->BlockReadHook(blockID, block);
00284 }
00285
00294 void cullIdenticalTaxaBlocks(bool v=true)
00295 {
00296 this->destroyRepeatedTaxaBlocks = v;
00297 }
00298 std::vector<std::string> GetAllTitlesForBlock(const NxsBlock *b) const;
00299
00300
00304 void SetAlwaysReportStatusMessages(bool v) {
00305 this->alwaysReportStatusMessages = v;
00306 }
00320 void SetWarningOutputLevel(NxsWarnLevel lev) {
00321 currentWarningLevel = lev;
00322 }
00323 NxsWarnLevel GetWarningOutputLevel() const {
00324 return currentWarningLevel;
00325 }
00326
00331 virtual void statusMessage(const std::string & m) const;
00332
00338 bool BlockListEmpty();
00339 unsigned PositionInBlockList(NxsBlock *b);
00340
00341 void Reassign(NxsBlock *oldb, NxsBlock *newb);
00342
00360 void AssignBlockPriority(NxsBlock *b, int priorityLevel);
00362 int GetBlockPriority(NxsBlock *b) const;
00364 void DemoteBlocks(int priorityLevel=-1);
00365 protected:
00368 static BlockReaderList parseFileWithReader(NxsReader & reader, const char *filepath, bool parsePrivateBlocks=true, bool storeTokenInfo=true);
00369 static bool nclCatchesSignals;
00370 typedef void (*SignalHandlerFuncPtr) (int);
00371 static SignalHandlerFuncPtr prevSignalCatcher;
00372 static unsigned numSigIntsCaught;
00373 static bool prevSignalStored ;
00374
00375 void CoreExecutionTasks(NxsToken& token, bool notifyStartStop = true);
00376
00377
00378 void AddBlockToUsedBlockList(const std::string &, NxsBlock *, NxsToken *);
00379 bool BlockIsASingeltonReader(NxsBlock *) const ;
00380 void BlockReadHook(const NxsString &currBlockName, NxsBlock *currBlock, NxsToken *token = NULL );
00381 bool ExecuteBlock(NxsToken &token, const NxsString &currBlockName, NxsBlock *currBlock, NxsBlockFactory * sourceOfBlock);
00382 NxsBlock *FindBlockOfTypeByTitle(const std::string &btype, const char *title, unsigned *nMatches);
00383 NxsBlock *FindBlockByTitle(const BlockReaderList & chosenBlockList, const char *title, unsigned *nMatches);
00384 BlockReaderList FindAllBlocksByTitle(const BlockReaderList & chosenBlockList, const char *title);
00385 NxsBlock *GetLastStoredBlockByID(const std::string &key);
00386 NxsTaxaBlockAPI *GetOriginalTaxaBlock(const NxsTaxaBlockAPI *) const;
00387 bool IsRepeatedTaxaBlock(const NxsTaxaBlockAPI *) const;
00388 void NewBlockTitleCheckHook(const std::string &blockname, NxsBlock *p, NxsToken *token);
00389 bool ReadUntilEndblock(NxsToken &token, const std::string & currBlockName);
00390 void RegisterAltTitle(const NxsBlock * b, std::string t);
00391 std::set<NxsBlock *> RemoveBlocksFromFactoriesFromUsedBlockLists();
00392 virtual void PostBlockReadingHook(NxsBlock &);
00393
00394
00395 NxsBlock *blockList;
00396 NxsBlock *currBlock;
00397 typedef std::list<NxsBlockFactory *> BlockFactoryList;
00398 NxsTaxaBlockFactory *taxaBlockFactory;
00399 BlockFactoryList factories;
00400 bool destroyRepeatedTaxaBlocks;
00401 NxsWarnLevel currentWarningLevel;
00402 bool alwaysReportStatusMessages;
00403
00404 private:
00405
00406 BlockReaderList FindAllBlocksByTitleNoPrioritization(const BlockReaderList & chosenBlockList, const char *title);
00407
00408 BlockReaderList blocksInOrder;
00409 std::map<NxsBlock *, int> blockPriorities;
00410
00411 BlockReaderList lastExecuteBlocksInOrder;
00412 BlockTypeToBlockList blockTypeToBlockList;
00413 typedef std::pair<unsigned, std::list<std::string> > NxsBlockTitleHistory;
00414 typedef std::map<std::string, NxsBlockTitleHistory > NxsBlockTitleHistoryMap;
00415 NxsBlockTitleHistoryMap blockTitleHistoryMap;
00416 std::map<const NxsBlock *, std::list<std::string> > blockTitleAliases;
00417
00418
00419 };
00420
00421 typedef NxsBlock NexusBlock;
00422 typedef NxsReader Nexus;
00423
00430 class ExceptionRaisingNxsReader : public NxsReader
00431 {
00432 public:
00440 ExceptionRaisingNxsReader(NxsReader::WarningHandlingMode mode=NxsReader::WARNINGS_TO_STDERR)
00441 :warnMode(mode),
00442 warningToErrorThreshold(PROBABLY_INCORRECT_CONTENT_WARNING)
00443 {}
00445 void NexusError(NxsString msg, file_pos pos, long line, long col)
00446 {
00447 throw NxsException(msg, pos, line, col);
00448 }
00449 virtual void NexusWarn(const std::string & msg, NxsWarnLevel level, file_pos pos, long line, long col);
00450
00451 void SkippingBlock(NxsString blockName);
00452 void SkippingDisabledBlock(NxsString blockName);
00459 void SetWarningToErrorThreshold(int t)
00460 {
00461 warningToErrorThreshold = t;
00462 }
00463 virtual void ClearContent()
00464 {
00465 NxsReader::ClearContent();
00466 }
00467 private:
00468 NxsReader::WarningHandlingMode warnMode;
00469 int warningToErrorThreshold;
00470 };
00471
00479 class DefaultErrorReportNxsReader : public NxsReader
00480 {
00481 public:
00482 static BlockReaderList parseFile(const char *filepath, std::ostream * stdOutstream, std::ostream * errOutstream, bool parsePrivateBlocks=true, bool storeTokenInfo=true);
00484 DefaultErrorReportNxsReader(std::ostream * stdOutstream,
00485 std::ostream * errOutstream)
00486 :NxsReader(),
00487 stdOut(stdOutstream),
00488 errOut(errOutstream)
00489 {
00490 }
00491
00492 virtual ~DefaultErrorReportNxsReader() {}
00493
00495 virtual bool EnteringBlock(NxsString )
00496 {
00497 return true;
00498 }
00499
00501 void SkippingBlock(NxsString blockName)
00502 {
00503 if (stdOut != 0L)
00504 {
00505 *stdOut << "[!Skipping unknown block (" << blockName << ")...]\n";
00506 stdOut->flush();
00507 }
00508 }
00509
00511 void SkippingDisabledBlock(NxsString blockName)
00512 {
00513 if (stdOut != 0L)
00514 {
00515 *stdOut << "[!Skipping disabled block (" << blockName << ")...]\n";
00516 stdOut->flush();
00517 }
00518 }
00519
00524 void NexusWarn(const std::string & msg,
00525 NxsWarnLevel warnLevel,
00526 file_pos pos, long line, long col)
00527 {
00528 if (warnLevel < currentWarningLevel)
00529 return;
00530 if (warnLevel >= PROBABLY_INCORRECT_CONTENT_WARNING)
00531 {
00532 NxsString e(msg.c_str());
00533 throw NxsException(e, pos, line, col);
00534 }
00535 if (errOut != 0)
00536 {
00537 *errOut << "\nWarning: ";
00538 if (line > 0 || pos > 0)
00539 *errOut << "at line " << line << ", column " << col << " (file position " << pos << "):\n";
00540 *errOut << msg << std::endl;
00541 }
00542 else if (stdOut != 0L)
00543 {
00544 *stdOut << "\nWarning: ";
00545 if (line > 0 || pos > 0)
00546 *stdOut << "at line " << line << ", column " << col << " (file position " << pos << "):\n";
00547 *stdOut << msg << std::endl;
00548 }
00549 }
00550
00553 void NexusError(NxsString msg, file_pos pos, long line, long col)
00554 {
00555 NexusWarn(msg, NxsReader::FATAL_WARNING, pos, line, col);
00556 throw NxsException(msg, pos, line, col);
00557 }
00558
00559 std::ostream * stdOut;
00560 std::ostream * errOut;
00561 };
00562
00569 inline BlockTypeToBlockList NxsReader::GetUsedBlocks()
00570 {
00571 return blockTypeToBlockList;
00572 }
00573
00575 inline bool NxsReader::IsRepeatedTaxaBlock(const NxsTaxaBlockAPI * testB) const
00576 {
00577 return (GetOriginalTaxaBlock(testB) != NULL);
00578 }
00579
00580
00586 inline BlockReaderList NxsReader::GetUsedBlocksInOrder()
00587 {
00588 return blocksInOrder;
00589 }
00590
00598 inline BlockReaderList NxsReader::GetBlocksFromLastExecuteInOrder()
00599 {
00600 return lastExecuteBlocksInOrder;
00601 }
00602
00604 inline NxsTaxaBlockFactory * NxsReader::GetTaxaBlockFactory()
00605 {
00606 return this->taxaBlockFactory;
00607 }
00608
00609
00610
00611 #endif
00612