All Downloads are FREE. Search and download functionalities are using the official Maven repository.

soot.PhaseOptions Maven / Gradle / Ivy

There is a newer version: 1.12.0
Show newest version
/* Soot - a J*va Optimization Framework
 * Copyright (C) 2003 Ondrej Lhotak
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

package soot;
import java.util.*;

/** Manages the phase options of the various soot phases. */
public class PhaseOptions {
    /** Needed for preventing infinite recursion in constructor. 
     * Termination is assured: each constructor is called exactly once.
     * Here is a case analysis.
     *   a. PackManager used first.  Then its constructor needs PhaseOptions,
            which also needs a PackManager; OK because we store the 
            PackManager being initialized in a field.
         b. PhaseOptions used first.  Then getPM() calls PackManager.v(),
            which calls the constr, which sets the .pm field here, uses
            PhaseOptions (which uses PackManager), and returns.  OK. */
    private PackManager pm;
    public void setPackManager(PackManager m) { this.pm = m; }
    PackManager getPM()
    {
        if (pm == null)
            PackManager.v();
        return pm;
    }

    public PhaseOptions( Singletons.Global g ) { }
    public static PhaseOptions v() { return G.v().soot_PhaseOptions(); }

    private final Map phaseToOptionMap = new HashMap();

    public Map getPhaseOptions(String phaseName) {
        return getPhaseOptions(getPM().getPhase(phaseName));
    }

    public Map getPhaseOptions(HasPhaseOptions phase) {
        Map ret = phaseToOptionMap.get(phase);
        if( ret == null ) ret = new HashMap();
        else ret = new HashMap( ret );
        StringTokenizer st = new StringTokenizer( phase.getDefaultOptions() );
        while( st.hasMoreTokens() ) {
            String opt = st.nextToken();
            String key = getKey( opt );
            String value = getValue( opt );
            if( !ret.containsKey( key ) ) ret.put( key, value );
        }
        return Collections.unmodifiableMap(ret);
    }

    public boolean processPhaseOptions(String phaseName, String option) {
        StringTokenizer st = new StringTokenizer(option, ",");
        while (st.hasMoreTokens()) {
            if( !setPhaseOption( phaseName, st.nextToken() ) ) {
                return false;
            }
        }
        return true;
    }

    /** This method returns true iff key "name" is in options 
        and maps to "true". */
    public static boolean getBoolean(Map options, String name)
    {
        return options.containsKey(name) &&
            options.get(name).equals("true");
    }



    /** This method returns the value of "name" in options 
        or "" if "name" is not found. */
    public static String getString(Map options, String name)
    {
        return options.containsKey(name) ?
            (String)options.get(name) : "";
    }



    /** This method returns the float value of "name" in options 
        or 1.0 if "name" is not found. */
    public static float getFloat(Map options, String name)
    {
        return options.containsKey(name) ?
            new Float((String)options.get(name)).floatValue() : 1.0f;
    }



    /** This method returns the integer value of "name" in options 
        or 0 if "name" is not found. */
    public static int getInt(Map options, String name)
    {
        return options.containsKey(name) ?
            new Integer((String)options.get(name)).intValue() : 0;
    }


    private Map mapForPhase( String phaseName ) {
        HasPhaseOptions phase = getPM().getPhase( phaseName );
        if( phase == null ) return null;
        return mapForPhase( phase );
    }

    private Map mapForPhase( HasPhaseOptions phase ) {
        Map optionMap = phaseToOptionMap.get( phase );
        if( optionMap == null ) {
            phaseToOptionMap.put( phase, optionMap = new HashMap() );
        }
        return optionMap;
    }

    private String getKey( String option ) {
        int delimLoc = option.indexOf(":");
        if (delimLoc < 0) {
            if( option.equals("on") || option.equals("off") ) return "enabled";
            return option;
        } else {
            return option.substring(0, delimLoc);
        }
    }
    private String getValue( String option ) {
        int delimLoc = option.indexOf(":");
        if (delimLoc < 0) {
            if( option.equals("off") ) return "false";
            return "true";
        } else {
            return option.substring(delimLoc+1);
        }
    }
    private void resetRadioPack( String phaseName ) {
        for (Pack p : getPM().allPacks()) {
            if( !(p instanceof RadioScenePack) ) continue;
            if( p.get(phaseName) == null ) continue;
            for( Iterator tIt = p.iterator(); tIt.hasNext(); ) {
                final Transform t = (Transform) tIt.next();
                setPhaseOption( t.getPhaseName(), "enabled:false" );
            }
        }
    }
    private boolean checkParentEnabled( String phaseName ) {
        if( true ) return true;
        for (Pack p : getPM().allPacks()) {
            if( getBoolean( getPhaseOptions( p ), "enabled" ) ) continue;
            for( Iterator tIt = p.iterator(); tIt.hasNext(); ) {
                final Transform t = (Transform) tIt.next();
                if( t.getPhaseName().equals( phaseName ) ) {
                    G.v().out.println( "Attempt to set option for phase "+phaseName+" of disabled pack "+p.getPhaseName() );
                    return false;

                }
            }
        }
        return true;
    }
    public boolean setPhaseOption( String phaseName, String option ) {
        HasPhaseOptions phase = getPM().getPhase( phaseName );
        if( phase == null ) {
            G.v().out.println( "Option "+option+" given for nonexistent"
                    +" phase "+phaseName );
            return false;
        }
        return setPhaseOption( phase, option );
    }
    public boolean setPhaseOption( HasPhaseOptions phase, String option ) {
        Map optionMap = mapForPhase( phase );
        if( !checkParentEnabled( phase.getPhaseName() ) ) return false;
        if( optionMap == null ) {
            G.v().out.println( "Option "+option+" given for nonexistent"
                    +" phase "+phase.getPhaseName() );
            return false;
        }
        String key = getKey( option );
        if( key.equals( "enabled" ) && getValue( option ).equals( "true" ) ) {
            resetRadioPack( phase.getPhaseName() );
        }
        if( declaresOption( phase, key ) ) {
            optionMap.put( key, getValue( option ) );
            return true;
        }
        G.v().out.println( "Invalid option "+option+" for phase "+phase.getPhaseName() );
        return false;
    }

    private boolean declaresOption( String phaseName, String option ) {
        HasPhaseOptions phase = getPM().getPhase( phaseName );
        return declaresOption( phase, option );
    }
    private boolean declaresOption( HasPhaseOptions phase, String option ) {
        String declareds = phase.getDeclaredOptions();
        for( StringTokenizer st = new StringTokenizer( declareds );
                st.hasMoreTokens(); ) {
            if( st.nextToken().equals( option ) ) {
                return true;
            }
        }
        return false;
    }

    public void setPhaseOptionIfUnset( String phaseName, String option ) {
        Map optionMap = mapForPhase( phaseName );
        if( optionMap == null )
            throw new RuntimeException( "No such phase "+phaseName );
        if( optionMap.containsKey( getKey( option ) ) ) return;
        if( !declaresOption( phaseName, getKey( option ) ) )
            throw new RuntimeException( "No option "+option+" for phase "+phaseName );
        optionMap.put( getKey( option ), getValue( option ) );
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy