001/*-------------------------------------------------------------------------+
002|                                                                          |
003| Copyright 2005-2011 the ConQAT Project                                   |
004|                                                                          |
005| Licensed under the Apache License, Version 2.0 (the "License");          |
006| you may not use this file except in compliance with the License.         |
007| You may obtain a copy of the License at                                  |
008|                                                                          |
009|    http://www.apache.org/licenses/LICENSE-2.0                            |
010|                                                                          |
011| Unless required by applicable law or agreed to in writing, software      |
012| distributed under the License is distributed on an "AS IS" BASIS,        |
013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
014| See the License for the specific language governing permissions and      |
015| limitations under the License.                                           |
016+-------------------------------------------------------------------------*/
017package eu.cqse.check.framework.preprocessor.c;
018
019import java.util.HashMap;
020import java.util.HashSet;
021import java.util.Map;
022import java.util.Set;
023
024import org.conqat.lib.commons.assertion.CCSMAssert;
025
026/**
027 * A macro provider that encapsulates another macro provider and allows
028 * temporary addition and removal of macros.
029 */
030public class OverlayMacroProvider implements IMacroProvider {
031
032        /** The encapsulated provider. */
033        private final IMacroProvider innerProvider;
034
035        /** The definitions (without leading '#' and 'define') of known macros. */
036        private final Map<String, String> macros = new HashMap<>();
037
038        /** Macros that have been explicitly undefined. */
039        private final Set<String> undefinedMacros = new HashSet<>();
040
041        /** Constructor. */
042        public OverlayMacroProvider(IMacroProvider innerProvider) {
043                CCSMAssert.isNotNull(innerProvider);
044                this.innerProvider = innerProvider;
045        }
046
047        /** {@inheritDoc} */
048        @Override
049        public boolean isDefined(String name) {
050                if (undefinedMacros.contains(name)) {
051                        return false;
052                }
053
054                if (macros.containsKey(name)) {
055                        return true;
056                }
057
058                return innerProvider.isDefined(name);
059        }
060
061        /** {@inheritDoc} */
062        @Override
063        public String getDefinition(String name) {
064                String definition = macros.get(name);
065                if (definition != null) {
066                        return definition;
067                }
068                return innerProvider.getDefinition(name);
069        }
070
071        /**
072         * Defines a macro.
073         * 
074         * @param definition
075         *            the macro definition without leading '#' and 'define'.
076         */
077        public void define(String name, String definition) {
078                macros.put(name, definition);
079                undefinedMacros.remove(name);
080        }
081
082        /** Undefines a macro. */
083        public void undefine(String name) {
084                undefinedMacros.add(name);
085                macros.remove(name);
086        }
087}