diff options
Diffstat (limited to 'org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/checkers/CloseOpenedFilesChecker.java')
-rw-r--r-- | org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/checkers/CloseOpenedFilesChecker.java | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/checkers/CloseOpenedFilesChecker.java b/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/checkers/CloseOpenedFilesChecker.java new file mode 100644 index 0000000..354223f --- /dev/null +++ b/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/checkers/CloseOpenedFilesChecker.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2009 Elliott Baron + * 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: + * Elliott Baron - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.checkers; + +import java.text.MessageFormat; + +import org.eclipse.cdt.codan.core.model.AbstractIndexAstChecker; +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; +import org.eclipse.cdt.core.dom.ast.IASTIdExpression; +import org.eclipse.cdt.core.dom.ast.IASTInitializer; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IBinding; + +public class CloseOpenedFilesChecker extends AbstractIndexAstChecker { + private static final String ERR_ID = Activator.PLUGIN_ID + ".CloseOpenedFilesProblem"; + + public void processAst(IASTTranslationUnit ast) { + // traverse the AST using the visitor pattern + CloseOpenedFilesVisitor visitor = new CloseOpenedFilesVisitor(); + ast.accept(visitor); + + IASTName closeFD = visitor.getCloseFD(); + if (closeFD != null) { + IASTName openFD = visitor.getOpenFD(); + if (openFD == null || !matchingFileDescriptors(closeFD.getBinding(), openFD.getBinding())) { + String message = MessageFormat.format("File descriptor \"{0}\" has not been opened", closeFD.toString()); + reportProblem(ERR_ID, closeFD, message); + } + } + } + + private boolean matchingFileDescriptors(IBinding closeFD, IBinding openFD) { + // FIXME elaborate + return closeFD.equals(openFD); + } + + class CloseOpenedFilesVisitor extends ASTVisitor { + + public static final String OPEN = "open"; + public static final String CLOSE = "close"; + + private IASTName openFD; + private IASTName closeFD; + + public CloseOpenedFilesVisitor() { + shouldVisitExpressions = true; + } + + @Override + public int visit(IASTExpression expression) { + if (expression instanceof IASTFunctionCallExpression) { + IASTFunctionCallExpression callExpression = (IASTFunctionCallExpression) expression; + IASTExpression funcName = callExpression.getFunctionNameExpression(); + if (funcName instanceof IASTIdExpression) { + IASTName name = ((IASTIdExpression) funcName).getName(); + String simpleName = String.valueOf(name.getSimpleID()); + if (simpleName.equals(OPEN)) { + IASTNode parent = callExpression.getParent(); + if (parent instanceof IASTInitializer) { + parent = parent.getParent(); + if (parent instanceof IASTDeclarator) { + openFD = ((IASTDeclarator) parent).getName(); + } + } + } + else if (simpleName.equals(CLOSE)) { + IASTExpression paramExpression = callExpression.getParameterExpression(); + if (paramExpression instanceof IASTIdExpression) { + closeFD = ((IASTIdExpression) paramExpression).getName(); + } + } + } + + return PROCESS_SKIP; + } + else { + return PROCESS_CONTINUE; + } + } + + public IASTName getOpenFD() { + return openFD; + } + + public IASTName getCloseFD() { + return closeFD; + } + } + +} |