org.sosy_lab.cpachecker.cpa.callstack.CallstackState.java Source code

Java tutorial

Introduction

Here is the source code for org.sosy_lab.cpachecker.cpa.callstack.CallstackState.java

Source

/*
 *  CPAchecker is a tool for configurable software verification.
 *  This file is part of CPAchecker.
 *
 *  Copyright (C) 2007-2014  Dirk Beyer
 *  All rights reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *
 *  CPAchecker web page:
 *    http://cpachecker.sosy-lab.org
 */
package org.sosy_lab.cpachecker.cpa.callstack;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Nonnull;

import com.google.common.collect.Lists;
import org.sosy_lab.cpachecker.cfa.model.CFANode;
import org.sosy_lab.cpachecker.core.interfaces.AbstractQueryableState;
import org.sosy_lab.cpachecker.core.interfaces.AbstractState;
import org.sosy_lab.cpachecker.core.interfaces.Partitionable;
import org.sosy_lab.cpachecker.exceptions.InvalidQueryException;
import org.sosy_lab.cpachecker.util.globalinfo.GlobalInfo;

public final class CallstackState implements AbstractState, Partitionable, AbstractQueryableState, Serializable {

    private static final long serialVersionUID = 3629687385150064994L;
    private final CallstackState previousState;
    private final String currentFunction;
    private transient CFANode callerNode;
    private final int depth;

    CallstackState(CallstackState previousElement, @Nonnull String function, @Nonnull CFANode callerNode) {
        this.previousState = previousElement;
        this.currentFunction = checkNotNull(function);
        this.callerNode = checkNotNull(callerNode);
        if (previousElement == null) {
            depth = 1;
        } else {
            depth = previousElement.getDepth() + 1;
        }
    }

    public CallstackState getPreviousState() {
        return previousState;
    }

    public String getCurrentFunction() {
        return currentFunction;
    }

    public CFANode getCallNode() {
        return callerNode;
    }

    public int getDepth() {
        return depth;
    }

    /** for logging and debugging */
    private List<String> getStack() {
        final List<String> stack = new ArrayList<>();
        CallstackState state = this;
        while (state != null) {
            stack.add(state.getCurrentFunction());
            state = state.getPreviousState();
        }
        return Lists.reverse(stack);
    }

    @Override
    public Object getPartitionKey() {
        return this;
    }

    @Override
    public String toString() {
        return "Function " + getCurrentFunction() + " called from node " + getCallNode() + ", stack depth "
                + getDepth() + " [" + Integer.toHexString(super.hashCode()) + "], stack " + getStack();
    }

    public boolean sameStateInProofChecking(CallstackState pOther) {
        if (pOther.callerNode == callerNode && pOther.depth == depth
                && pOther.currentFunction.equals(currentFunction)
                && (pOther.previousState == previousState || (previousState != null && pOther.previousState != null
                        && previousState.sameStateInProofChecking(pOther.previousState)))) {
            return true;
        }
        return false;
    }

    @Override
    public String getCPAName() {
        return "Callstack";
    }

    @Override
    public boolean checkProperty(String pProperty) throws InvalidQueryException {
        return false;
    }

    @Override
    public Object evaluateProperty(String pProperty) throws InvalidQueryException {
        if (pProperty.compareToIgnoreCase("caller") == 0) {
            if (callerNode != null) {
                return this.callerNode.getFunctionName();
            } else {
                return "";
            }
        }

        throw new InvalidQueryException(
                String.format("Evaluating %s not supported by %s", pProperty, this.getClass().getCanonicalName()));
    }

    @Override
    public void modifyProperty(String pModification) throws InvalidQueryException {
        throw new InvalidQueryException("modifyProperty not implemented by " + this.getClass().getCanonicalName());
    }

    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeInt(callerNode.getNodeNumber());
    }

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        int nodeNumber = in.readInt();
        callerNode = GlobalInfo.getInstance().getCFAInfo().get().getNodeByNodeNumber(nodeNumber);
    }
}