void NxsTaxaBlockSurrogate::AssureTaxaBlock(bool allocBlock, NxsToken &token, const char *cmd) { if (!allocBlock) { if (taxa != NULL) return; if (!nxsReader) { NxsString errormsg = "API Error: No nxsReader during parse in NxsTaxaBlockSurrogate::AssureTaxaBlock"; throw NxsNCLAPIException(errormsg, token); } unsigned nTb; NxsTaxaBlockAPI * cb = nxsReader->GetTaxaBlockByTitle(NULL, &nTb); if (cb == NULL) { NxsString errormsg = "TAXA Block has been not been read, but a "; if (cmd) errormsg += cmd; errormsg += " command (which requires a TAXA block) has been encountered. Either add a TAXA block or (for blocks other than the TREES block) you may use a \"DIMENSIONS NEWTAXA NTAX= ...\" command to introduces taxa."; throw NxsException(errormsg, token); } if (nTb > 1) { NxsString errormsg = "Multiple TAXA Blocks have been read (or implied using NEWTAXA in other blocks) and a"; if (cmd) errormsg += cmd; errormsg += " command (which requires a TAXA block) has been encountered.\nA \"LINK TAXA=<title here>;\" command must be used to specify which TAXA block is needed."; cb->WarnDangerousContent(errormsg, token); } taxa = cb; return; } if (nxsReader != NULL) { NxsTaxaBlockFactory * tbf = nxsReader->GetTaxaBlockFactory(); if (tbf) { std::string s("TAXA"); taxa = tbf->GetBlockReaderForID(s, nxsReader, &token); ownsTaxaBlock = true; passedRefOfOwnedBlock = false; taxaLinkStatus = NxsBlock::BLOCK_LINK_TO_IMPLIED_BLOCK; } } if (taxa == NULL) { taxa = new NxsTaxaBlock(); ownsTaxaBlock = true; passedRefOfOwnedBlock = false; taxaLinkStatus = NxsBlock::BLOCK_LINK_TO_IMPLIED_BLOCK; } }
/* This function is called by derived classes right before they start to parse a command that requires a Taxa block. If a taxa block has not been set at this point, and one cannot be created then a NxsException will be generated. This enables lazy initialization of the taxa field. */ void NxsTaxaBlockSurrogate::AssureTaxaBlock(bool allocBlock, NxsToken &token, const char *cmd) { if (!allocBlock) { if (taxa != NULL) return; if (!nxsReader) { NxsString errormsg = "API Error: No nxsReader during parse in NxsTaxaBlockSurrogate::AssureTaxaBlock"; throw NxsNCLAPIException(errormsg, token); } unsigned nTb; NxsTaxaBlockAPI * cb = nxsReader->GetTaxaBlockByTitle(NULL, &nTb); if (cb == NULL) { NxsString errormsg = "TAXA Block has been not been read, but a "; if (cmd) errormsg += cmd; errormsg += " command (which requires a TAXA block) has been encountered. Either add a TAXA block or (for blocks other than the TREES block) you may use a \"DIMENSIONS NEWTAXA NTAX= ...\" command to introduces taxa."; throw NxsException(errormsg, token); } if (nTb > 1) { NxsString errormsg = "Multiple TAXA Blocks have been read (or implied using NEWTAXA in other blocks) and a "; if (cmd) errormsg += cmd; errormsg += " command (which requires a TAXA block) has been encountered"; std::string bn = token.GetBlockName(); if (!bn.empty()) { errormsg += " in a "; errormsg += bn; errormsg += " block."; } errormsg += ".\nThis can be caused by reading multiple files. It is possible that\neach file is readable separately, but cannot be read unambiguously when read in sequence.\n"; errormsg += "One way to correct this is to use the\n TITLE some-unique-name-here ;\ncommand in the TAXA block and an accompanying\n LINK TAXA=the-unique-title-goes here;\n"; errormsg += "command to specify which TAXA block is needed."; cb->WarnDangerousContent(errormsg, token); } taxa = cb; return; } if (nxsReader != NULL) { NxsTaxaBlockFactory * tbf = nxsReader->GetTaxaBlockFactory(); if (tbf) { std::string s("TAXA"); taxa = tbf->GetBlockReaderForID(s, nxsReader, &token); ownsTaxaBlock = true; passedRefOfOwnedBlock = false; taxaLinkStatus = NxsBlock::BLOCK_LINK_TO_IMPLIED_BLOCK; } } if (taxa == NULL) { taxa = new NxsTaxaBlock(); ownsTaxaBlock = true; passedRefOfOwnedBlock = false; taxaLinkStatus = NxsBlock::BLOCK_LINK_TO_IMPLIED_BLOCK; } }