/******************************************************************************* * Copyright (c) Gil Barash - chookapp@yahoo.com * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Gil Barash - initial API and implementation *******************************************************************************/ package com.chookapp.org.bracketeer.cdt; import java.util.Stack; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElifStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElseStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorEndifStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfdefStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfndefStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.jface.text.BadLocationException; import com.chookapp.org.bracketeer.common.Hint; import com.chookapp.org.bracketeer.common.IBracketeerProcessingContainer; import com.chookapp.org.bracketeer.common.IHintConfiguration; import com.chookapp.org.bracketeer.common.MutableBool; public class PreprocessorVisitor { MutableBool _cancelProcessing; IBracketeerProcessingContainer _container; IHintConfiguration _hintConf; class CondInfo { public String _cond; public IASTFileLocation _fileLoc; public CondInfo(String str, IASTFileLocation fileLocation) { _cond = str; _fileLoc = fileLocation; } } Stack<CondInfo> _stack; public PreprocessorVisitor(IBracketeerProcessingContainer container, MutableBool cancelProcessing, IHintConfiguration hintConf) { _cancelProcessing = cancelProcessing; _container = container; _hintConf = hintConf; _stack = new Stack<CondInfo>(); } private String stripEolBackslash(char[] ch) { String str = new String(ch); return stripEolBackslash(str); } private String stripEolBackslash(String str) { return str.replaceAll("\\\\(\\s*[\r|\n])", "$1"); //$NON-NLS-1$ //$NON-NLS-2$ } public void visit(IASTPreprocessorStatement[] stmts) throws BadLocationException { for (IASTPreprocessorStatement stmt : stmts) { if(_cancelProcessing.get()) break; if( stmt instanceof IASTPreprocessorIfStatement) { StringBuffer str = new StringBuffer(); str.append("if( "); //$NON-NLS-1$ str.append(stripEolBackslash(((IASTPreprocessorIfStatement)stmt).getCondition())); str.append(" )"); //$NON-NLS-1$ _stack.push(new CondInfo(str.toString(), stmt.getFileLocation())); } else if( stmt instanceof IASTPreprocessorIfdefStatement) { StringBuffer str = new StringBuffer(); str.append("if_defined( "); //$NON-NLS-1$ str.append(stripEolBackslash(((IASTPreprocessorIfdefStatement)stmt).getCondition())); str.append(" )"); //$NON-NLS-1$ _stack.push(new CondInfo(str.toString(), stmt.getFileLocation())); } else if( stmt instanceof IASTPreprocessorIfndefStatement) { StringBuffer str = new StringBuffer(); str.append("if_not_defined( "); //$NON-NLS-1$ str.append(stripEolBackslash(((IASTPreprocessorIfndefStatement)stmt).getCondition())); str.append(" )"); //$NON-NLS-1$ _stack.push(new CondInfo(str.toString(), stmt.getFileLocation())); } else if( stmt instanceof IASTPreprocessorElifStatement) { CondInfo cond = null; if(!_stack.empty()) { cond = _stack.pop(); } if( cond != null ) { IASTFileLocation location = stmt.getFileLocation(); int endLoc = location.getNodeOffset()+location.getNodeLength()-1; int startLoc = cond._fileLoc.getNodeOffset(); _container.add(new Hint("preprocess", startLoc, endLoc, cond._cond)); //$NON-NLS-1$ } StringBuffer str = new StringBuffer(); str.append("if( "); //$NON-NLS-1$ str.append(stripEolBackslash(((IASTPreprocessorElifStatement)stmt).getCondition())); str.append(" )"); //$NON-NLS-1$ _stack.push(new CondInfo(str.toString(), stmt.getFileLocation())); } else if (stmt instanceof IASTPreprocessorElseStatement) { CondInfo cond = null; if(!_stack.empty()) { cond = _stack.pop(); } StringBuffer str = new StringBuffer(); str.append("else_of_"); //$NON-NLS-1$ if( cond != null ) { IASTFileLocation location = stmt.getFileLocation(); int endLoc = location.getNodeOffset()+location.getNodeLength()-1; int startLoc = cond._fileLoc.getNodeOffset(); _container.add(new Hint("preprocess", startLoc, endLoc, cond._cond)); //$NON-NLS-1$ str.append(cond._cond); } _stack.push(new CondInfo(str.toString(), stmt.getFileLocation())); } else if( stmt instanceof IASTPreprocessorEndifStatement) { if(_stack.empty()) continue; CondInfo cond = _stack.pop(); IASTFileLocation location = stmt.getFileLocation(); int endLoc = location.getNodeOffset()+location.getNodeLength()-1; int startLoc = cond._fileLoc.getNodeOffset(); _container.add(new Hint("preprocess", startLoc, endLoc, cond._cond)); //$NON-NLS-1$ } } } }