From d581ec1fce73716b9d422cf2e4a255871f0bcd9b Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Mon, 31 Aug 2009 23:06:28 -0400 Subject: Support multiple open/close calls; ensure open called before close. * org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/checkers/CloseOpenedFilesChecker.java: Report errors within visit method, store IASTNames for opened FDs in a list. --- .../codan/checkers/CloseOpenedFilesChecker.java | 68 ++++++++++++++-------- 1 file changed, 43 insertions(+), 25 deletions(-) (limited to 'org.eclipse.cdt.codan.checkers') 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 index 354223f..5563ad9 100644 --- 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 @@ -11,14 +11,17 @@ package org.eclipse.cdt.codan.checkers; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; import org.eclipse.cdt.codan.core.model.AbstractIndexAstChecker; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; 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.IASTInitializerExpression; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; @@ -31,31 +34,24 @@ public class CloseOpenedFilesChecker extends AbstractIndexAstChecker { // 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); + + private void reportProblem(IASTName closeFD) { + String message = MessageFormat.format("File descriptor \"{0}\" has not been opened", closeFD.toString()); + reportProblem(ERR_ID, closeFD, message); } + class CloseOpenedFilesVisitor extends ASTVisitor { public static final String OPEN = "open"; public static final String CLOSE = "close"; - private IASTName openFD; - private IASTName closeFD; + private List openedFDs; public CloseOpenedFilesVisitor() { + openedFDs = new ArrayList(); shouldVisitExpressions = true; } @@ -69,18 +65,40 @@ public class CloseOpenedFilesChecker extends AbstractIndexAstChecker { String simpleName = String.valueOf(name.getSimpleID()); if (simpleName.equals(OPEN)) { IASTNode parent = callExpression.getParent(); - if (parent instanceof IASTInitializer) { + // Handle initialization in declaration + if (parent instanceof IASTInitializerExpression) { parent = parent.getParent(); if (parent instanceof IASTDeclarator) { - openFD = ((IASTDeclarator) parent).getName(); + openedFDs.add(((IASTDeclarator) parent).getName()); + } + } + // Assignment after declaration + else if (parent instanceof IASTBinaryExpression) { + IASTExpression op2 = ((IASTBinaryExpression) parent).getOperand2(); + int operator = ((IASTBinaryExpression) parent).getOperator(); + if (callExpression.equals(op2) && operator == IASTBinaryExpression.op_assign) { + IASTExpression op1 = ((IASTBinaryExpression) parent).getOperand1(); + if (op1 instanceof IASTIdExpression) { + openedFDs.add(((IASTIdExpression) op1).getName()); + } } } } else if (simpleName.equals(CLOSE)) { IASTExpression paramExpression = callExpression.getParameterExpression(); if (paramExpression instanceof IASTIdExpression) { - closeFD = ((IASTIdExpression) paramExpression).getName(); - } + IASTName fd = ((IASTIdExpression) paramExpression).getName(); + // Add only if no matching opened FD + boolean match = false; + for (int i = 0; !match && i < openedFDs.size(); i++) { + IASTName opened = openedFDs.get(i); + match = matchingFileDescriptors(fd, opened); + } + + if (!match) { + reportProblem(fd); + } + } } } @@ -91,12 +109,12 @@ public class CloseOpenedFilesChecker extends AbstractIndexAstChecker { } } - public IASTName getOpenFD() { - return openFD; - } - - public IASTName getCloseFD() { - return closeFD; + private boolean matchingFileDescriptors(IASTName closeFD, IASTName openFD) { + // FIXME elaborate + IBinding closeBinding = closeFD.getBinding(); + IBinding openBinding = openFD.getBinding(); + + return openBinding != null && closeBinding != null && openBinding.equals(closeBinding); } } -- cgit