Пример #1
0
/*! Called internally when the NxsReader has found the correct NxsBlock to read
    a block in a file.

    `token` will be at the block ID.
    `currBlockName` will be the block ID as a string.
    `currentBlock` will be the block reader to be used
    `sourceOfBlock` is the factory  that created the block (or 0L). If sourceOfBlock
        is not NULL then it will be alerted if the block is skipped (BlockSkipped() method)
        or there was an error in the read (BlockError() method). The factory is expected
        to delete the block instances in these cases (NxsReader will not refer to those
        instances again).



    The following steps occur:
        - the EnteringBlock hook is called (if it returns false, the block will be skipped by calling
            NxsReader::SkippingBlock
        - NxsBlock::Reset() is called on the reader block
        - NxsBlock::Read() method of the reader block is called
        - If an exception is generated, the NexusError is called.
        - If no exception is generated by Read then the block is processed:
            - if NxsReader::cullIdenticalTaxaBlocks(true) has been called before Execute and this
                is a repeated TAXA block, the block will be deleted.
            - the BlockReadHook() will store all of the implied blocks
                (by calling NxsBlock::GetImpliedBlocks()) and the block itself.
            - if one of the implied blocks is a repeated TAXA block and
                NxsReader::cullIdenticalTaxaBlocks(true) has been called, then
                the blocks NxsBlock::SwapEquivalentTaxaBlock() method will determine
                whether or not the duplicate taxa block can be deleted.
            - each stored block will generate a call to NxsReader::AddBlockToUsedBlockList()
        - ExitingBlock() is called
        - PostBlockReadingHook() is called
 */
bool NxsReader::ExecuteBlock(NxsToken &token, const NxsString &currBlockName, NxsBlock *currentBlock, NxsBlockFactory * sourceOfBlock)
{
    if (!EnteringBlock(currBlockName))
    {
        SkippingBlock(currBlockName);
        if (sourceOfBlock)
        {
            sourceOfBlock->BlockSkipped(currentBlock);
        }
        if (!ReadUntilEndblock(token, currBlockName))
        {
            token.SetBlockName(0L);
            token.SetEOFAllowed(true);
            return false;
        }
        return true;
    }
    this->RemoveBlockFromUsedBlockList(currentBlock);
    currentBlock->Reset();
    // We need to back up currentBlock, because the Read statement might trigger
    // a recursive call to Execute (if the block contains instructions to execute
    // another file, then the same NxsReader object may be used and any member fields (e.g. currentBlock)
    //	could be trashed.
    //
    bool eofFound = false;
    try
    {
        try
        {
            currentBlock->Read(token);
        }
        catch (NxsX_UnexpectedEOF &eofx)
        {
            if (!currentBlock->TolerateEOFInBlock())
            {
                throw eofx;
            }
            NxsString m;
            m << "Unexpected End of file in " << currBlockName << "block";
            currentBlock->WarnDangerousContent(m, token);
            eofFound = true;
        }
        if (destroyRepeatedTaxaBlocks && currBlockName.EqualsCaseInsensitive("TAXA"))
        {
            NxsTaxaBlockAPI * oldTB = this->GetOriginalTaxaBlock((NxsTaxaBlockAPI *) currentBlock);
            if (oldTB)
            {
                const std::string altTitle = currentBlock->GetTitle();
                this->RegisterAltTitle(oldTB, altTitle);
                if (sourceOfBlock)
                {
                    sourceOfBlock->BlockError(currentBlock);
                }
                return true;
            }
        }
        BlockReadHook(currBlockName, currentBlock, &token);
    }
    catch (NxsException &x)
    {
        NxsString m;
        if (currentBlock->errormsg.length() > 0)
        {
            m = currentBlock->errormsg;
        }
        else
        {
            m = x.msg;
        }
        currentBlock->Reset();
        if (sourceOfBlock != 0)
        {

            sourceOfBlock->BlockError(currentBlock);
        }
        else
        {

            token.SetBlockName(0L);
        }
        token.SetEOFAllowed(true);
        currentBlock = NULL;
        NexusError(m, x.pos, x.line, x.col);
        return false;
    }       // catch (NxsException x)
    ExitingBlock(currBlockName);
    PostBlockReadingHook(*currentBlock);
    return !eofFound;
}
Пример #2
0
/*! used internally to  do most of the work of Execute() */
void NxsReader::CoreExecutionTasks(
    NxsToken  &token,           /* the token object used to grab NxsReader tokens */
    bool notifyStartStop)       /* if true, ExecuteStarting and ExecuteStopping will be called */
{
    unsigned numSigInts = NxsReader::getNumSignalIntsCaught();
    const bool checkingSignals = NxsReader::getNCLCatchesSignals();

    lastExecuteBlocksInOrder.clear();
    currBlock = NULL;

    NxsString errormsg;
    token.SetEOFAllowed(true);

    try
    {
        token.SetLabileFlagBit(NxsToken::saveCommandComments);
        token.GetNextToken();
    }
    catch (NxsException x)
    {
        NexusError(token.errormsg, 0, 0, 0);
        return;
    }

    if (token.Equals("#NEXUS"))
    {
        token.SetLabileFlagBit(NxsToken::saveCommandComments);
        token.GetNextToken();
    }
    else
    {
        errormsg = "Expecting #NEXUS to be the first token in the file, but found ";
        errormsg += token.GetToken();
        errormsg += " instead";
        /*mth changed this to a warning instead of an error	 because of the large number
            of files that violate this requirement.
         */
        NexusWarn(errormsg,  NxsReader::AMBIGUOUS_CONTENT_WARNING, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn());
    }

    if (notifyStartStop)
    {
        ExecuteStarting();
    }
    bool keepReading = true;
    for (; keepReading && !token.AtEOF(); )
    {
        if (checkingSignals && NxsReader::getNumSignalIntsCaught() != numSigInts)
        {
            throw NxsSignalCanceledParseException("Reading NEXUS content");
        }
        if (token.Equals("BEGIN"))
        {
            token.SetEOFAllowed(false); /*must exit the block before and EOF*/
            token.GetNextToken();
            token.SetBlockName(token.GetTokenReference().c_str());
            for (currBlock = blockList; currBlock != NULL; currBlock = currBlock->next)
            {
                if (currBlock->CanReadBlockType(token))
                {
                    break;
                }
            }
            NxsString currBlockName = token.GetToken();
            currBlockName.ToUpper();
            NxsBlockFactory * sourceOfBlock = NULL;
            if (currBlock == NULL)
            {
                try
                {
                    currBlock = CreateBlockFromFactories(currBlockName, token, &sourceOfBlock);
                }
                catch (NxsException x)
                {
                    NexusError(x.msg, x.pos, x.line, x.col);
                    token.SetBlockName(0L);
                    token.SetEOFAllowed(true);
                    return;
                }
            }
            if (currBlock == NULL)
            {
                SkippingBlock(currBlockName);
                if (!ReadUntilEndblock(token, currBlockName))
                {
                    token.SetBlockName(0L);
                    token.SetEOFAllowed(true);
                    return;
                }
            }
            else if (currBlock->IsEnabled())
            {
                keepReading = ExecuteBlock(token, currBlockName, currBlock, sourceOfBlock);
            }
            else
            {
                SkippingDisabledBlock(token.GetToken());
                if (sourceOfBlock)
                {
                    sourceOfBlock->BlockSkipped(currBlock);
                }
                if (!ReadUntilEndblock(token, currBlockName))
                {
                    token.SetBlockName(0L);
                    token.SetEOFAllowed(true);
                    return;
                }
            }
            currBlock = NULL;
            token.SetEOFAllowed(true);
            token.SetBlockName(0L);
        }       // if (token.Equals("BEGIN"))
        else if (token.Equals("&SHOWALL"))
        {
            for (NxsBlock*  showBlock = blockList; showBlock != NULL; showBlock = showBlock->next) {
                DebugReportBlock(*showBlock);
            }
        }
        else if (token.Equals("&LEAVE"))
        {
            break;
        }
        if (keepReading)
        {
            token.SetLabileFlagBit(NxsToken::saveCommandComments);
            token.GetNextToken();
        }
    }
    if (notifyStartStop)
    {
        ExecuteStopping();
    }

    currBlock = NULL;
}