Exemplo n.º 1
0
/**
 * Called for the root of the list!
 */
bool GemTestCommand::operator == (GemTestCommand &other)
{
    if (count() != other.count()) return false;
    for (GemTestCommand *mine = next(), *yours = other.next();
        !mine->isRoot(); mine = mine->next(), yours = yours->next())
    {
        if (mine->_id != yours->_id) return false;
        if (mine->_arg != yours->_arg) return false;
        if (mine->_negate != yours->_negate) return false;
        if (mine->_text != yours->_text) return false;
    }
    return true;
}
Exemplo n.º 2
0
bool GemTest::test(Gem *gem)
{
    Gem *test = gem;       // The test pointer.
    Gem *tryStart;
    bool result, trying = false, passed;
    int i;
    
    for(GemTestCommand *cmd = _commands.next(); !cmd->isRoot(); cmd = cmd->next())
    {
        // We can skip commands if trying is passed.
        if(trying && ((passed && cmd->id() != CheckIfPassed) ||
                      (!test && cmd->id() != CheckIfPassed && cmd->id() != GoSelf)))
            continue;

        result = true;
        switch(cmd->id())
        {
        case GoSelf:
            test = gem;
            break;

        case GoParent:
            for(i = 0; test && i < cmd->intArg(); i++) test = test->parentGem();
            break;

        case GoNext:
            for(i = 0; test && i < cmd->intArg(); i++) test = test->nextGem();
            break;

        case GoPrev:
            for(i = 0; test && i < cmd->intArg(); i++) test = test->prevGem();
            break;

        case GoFirst:
            for(i = 0; test && i < cmd->intArg(); i++) test = test->firstGem();
            break;

        case GoLast:
            for(i = 0; test && i < cmd->intArg(); i++) test = test->lastGem();
            break;

        case GoFollowing:
            for(i = 0; test && i < cmd->intArg(); i++) test = test->followingGem();
            break;
            
        case GoPreceding:
            for(i = 0; test && i < cmd->intArg(); i++) test = test->precedingGem();
            break;

        case GoFinal:
            test = gem->finalGem();
            break;

        case BeginTry:
            trying = true;
            passed = false;
            tryStart = test;
            break;

        case CheckIfPassed:
            trying = false;
            result = passed;
            test = tryStart; // Return to where the test began.
            break;

        default:
            // Are we escalating this check?
            if(cmd->escalating())
            {
                result = false;
                for(Gem* it = test->parentGem(); it; it = it->parentGem())
                {
                    if(cmd->execute(gem, it))
                    {
                        result = true;
                        break;
                    }
                }
            }
            else
            {
                result = cmd->execute(gem, test);
            }
            break;
        }

        // You can't fail the BeginTry command.
        if(cmd->id() == BeginTry) continue;

        // A null test pointer is an automatic failure.
        if(!test)
        {
            if(!trying) return false;
            result = false;
        }

        // Did it fail?
        if(trying)
        {
            if(result != cmd->negated()) passed = true; // Passed!
        }
        else
        {
            if(result == cmd->negated()) return false; // Failed!
        }
    }

    if(trying)
    {
        qCritical("A 'try..pass' is missing 'pass'.");
        exit(1);
    }

    // All commands were successful.
    return true;
}