From 7b9d6a721570a1e3442e716b2916467424511be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 24 May 2007 13:08:18 +0000 Subject: [PATCH] CheckHeaders: Added files (Check for mistakes in headers or related to headers) --- CheckHeaders.cpp | 184 +++++++++++++++++++++++++++++++++++++++++++++++ CheckHeaders.h | 13 ++++ 2 files changed, 197 insertions(+) create mode 100644 CheckHeaders.cpp create mode 100644 CheckHeaders.h diff --git a/CheckHeaders.cpp b/CheckHeaders.cpp new file mode 100644 index 000000000..ff5e0cc95 --- /dev/null +++ b/CheckHeaders.cpp @@ -0,0 +1,184 @@ +//--------------------------------------------------------------------------- +#include "CheckHeaders.h" +#include "Tokenize.h" +#include "CommonCheck.h" +#include +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// HEADERS - No implementation in a header +//--------------------------------------------------------------------------- + +void WarningHeaderWithImplementation() +{ + for (TOKEN *tok = tokens; tok; tok = tok->next) + { + // Only interested in included file + if (tok->FileIndex == 0) + continue; + + if (match(tok, ") {")) + { + std::ostringstream ostr; + ostr << FileLine(tok) << ": Found implementation in header"; + ReportErr(ostr.str()); + } + } +} +//--------------------------------------------------------------------------- + + + + + + + + +//--------------------------------------------------------------------------- +// HEADERS - Unneeded include +//--------------------------------------------------------------------------- + +void WarningIncludeHeader() +{ + // Including.. + for (TOKEN *includetok = tokens; includetok; includetok = includetok->next) + { + if (strcmp(includetok->str, "#include") != 0) + continue; + + // Get fileindex of included file.. + unsigned int hfile = 0; + const char *includefile = includetok->next->str; + while (hfile < Files.size()) + { + if (stricmp(Files[hfile].c_str(), includefile) == 0) + break; + hfile++; + } + if (hfile == Files.size()) + continue; + + // This header is needed if: + // * It contains some needed class declaration + // * It contains some needed function declaration + // * It contains some needed constant value + // * It contains some needed variable + // * It contains some needed enum + bool Needed = false; + bool NeedDeclaration = false; + int indentlevel = 0; + for (TOKEN *tok1 = tokens; tok1; tok1 = tok1->next) + { + if (tok1->FileIndex != hfile) + continue; + + if (!tok1->next) + continue; + + if (!tok1->next->next) + continue; + + // I'm only interested in stuff that is declared at indentlevel 0 + if (tok1->str[0] == '{') + indentlevel++; + if (tok1->str[0] == '}') + indentlevel--; + if (indentlevel != 0) + continue; + + // Class or namespace declaration.. + if (match(tok1,"class var {") || + match(tok1,"class var :") || + match(tok1,"namespace var {")) + { + std::string classname = getstr(tok1, 1); + + // Try to find class usage in "parent" file.. + for (TOKEN *tok2 = tokens; tok2; tok2 = tok2->next) + { + if (tok2->FileIndex != includetok->FileIndex) + continue; + + // Inheritage.. + Needed |= match(tok2, "class var : " + classname); + Needed |= match(tok2, "class var : type " + classname); + + // Allocating.. + Needed |= match(tok2, "new " + classname); + + // Using class.. + Needed |= match(tok2, classname + " ::"); + Needed |= match(tok2, classname + " var"); + NeedDeclaration |= match(tok2, classname + " *"); + } + + if (Needed | NeedDeclaration) + break; + } + + // Variable.. + std::string varname = ""; + if (match(tok1, "type var ;") || match(tok1, "type var [")) + varname = getstr(tok1, 1); + if (match(tok1, "type * var ;") || match(tok1, "type * var [")) + varname = getstr(tok1, 2); + if (!varname.empty()) + { + for (TOKEN *tok2 = tokens; tok2; tok2 = tok2->next) + { + if (tok2->FileIndex != includetok->FileIndex) + continue; + + NeedDeclaration |= (tok2->str == varname); + Needed |= match(tok2, varname + " ."); + Needed |= match(tok2, varname + " ->"); + Needed |= match(tok2, varname + " ="); + } + + if (Needed | NeedDeclaration) + break; + } + + // enum + if (match(tok1,"enum var {")) + { + std::string enumname = getstr(tok1, 1); + + // Try to find enum usage in "parent" file.. + for (TOKEN *tok2 = tokens; tok2; tok2 = tok2->next) + { + if (tok2->FileIndex != includetok->FileIndex) + continue; + + Needed |= (enumname == tok2->str); + } + + if (Needed) + break; + } + + } + + + // Not a header file? + if (includetok->FileIndex == 0) + Needed |= NeedDeclaration; + + // Not needed! + if (!Needed) + { + std::ostringstream ostr; + ostr << FileLine(includetok) << ": The included header '" << includefile << "' is not needed"; + if (NeedDeclaration) + ostr << " (but a declaration in it is needed)"; + ReportErr(ostr.str()); + } + } +} +//--------------------------------------------------------------------------- + + + diff --git a/CheckHeaders.h b/CheckHeaders.h new file mode 100644 index 000000000..15f9613f1 --- /dev/null +++ b/CheckHeaders.h @@ -0,0 +1,13 @@ +//--------------------------------------------------------------------------- +#ifndef CheckHeadersH +#define CheckHeadersH +//--------------------------------------------------------------------------- + +void WarningHeaderWithImplementation(); + +void WarningIncludeHeader(); + + +//--------------------------------------------------------------------------- +#endif +