kwsCheckVariablePerLine.cxx 4.91 KB
Newer Older
1 2 3
/*=========================================================================

  Program:   KWStyle - Kitware Style Checker
4
  Module:    kwsCheckVariablePerLine.cxx
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

  Copyright (c) Kitware, Inc.  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "kwsParser.h"

namespace kws {


/** Check the number of statements per line */
bool Parser::CheckVariablePerLine(unsigned long max)
{
  m_TestsDone[VARIABLEPERLINE] = true;
  char* val = new char[255];
  sprintf(val,"Variables per line = %ld max",max);
  m_TestsDescription[VARIABLEPERLINE] = val;
  delete [] val;

  // For the moment only standard types are defined.
  // We might be able to do more with finding typedefs
  #define ntypes 12
  const char* types[ntypes] = {"int","unsigned int",
   "char","unsigned char",
   "short","unsigned short",
   "long","unsigned long",
   "float","double","void","long int"};

  bool hasError = false;
  for(unsigned int i = 0;i<ntypes;i++)
    {
    std::string typeToFind = types[i];
    typeToFind += " ";
    size_t posType = m_BufferNoComment.find(typeToFind,0);
    while(posType != std::string::npos)
      {
      // Check that this is the first word
      bool firstWord = false;
47
      long int pos=static_cast<long int>(posType);
48 49 50 51 52 53 54 55 56 57 58 59 60
      pos--;
      while((pos>0) && (m_BufferNoComment[pos]==' '))
        {
        pos--;
        }
      if((pos<=0) || (m_BufferNoComment[pos]=='\n'))
        {
        firstWord = true;
        }

      if(firstWord)
        {
        std::string line = this->GetLine(this->GetLineNumber(posType,true)-1);
61

62
        // Check if we have any comments
63 64
        int poscom = static_cast<int>(line.find("//",0));
        if(poscom != -1)
65 66 67
          {
          line = line.substr(0,poscom);
          }
68 69
        poscom = static_cast<int>(line.find("/*",0));
        while(poscom != -1)
70
          {
71
          int poscomend = static_cast<int>(line.find("*/",0));
72 73 74 75 76
          if(poscomend == -1)
            {
            line = line.substr(0,poscom);
            break;
            }
77

78 79
          std::string line_temp = line.substr(0,poscom);
          line = line_temp+line.substr(poscomend+2,line.size()-poscomend-2);
80
          poscom = static_cast<int>(line.find("/*",poscom+1));
81 82 83 84 85 86 87
          }

        // If we have any '(' in the line we stop
        if(line.find('(') == std::string::npos)
          {
          // This is a very simple check we count the number of comas
          unsigned int vars = 1;
88
          pos = static_cast<long int>(line.find(',',0));
89 90 91
          while(pos!=-1)
            {
            // Check that we are not initializing an array
92
            bool betweenBraces = false;
93 94 95 96 97 98
            long int openCurly = pos-1;
            while(openCurly>0)
              {
              // Ok we have the opening
              if(line[openCurly] == '{')
                {
99
                long int posClosing = static_cast<long int>(this->FindClosingChar('{','}',openCurly,false,line));
100 101 102 103 104 105 106 107 108
                if(posClosing == -1
                  || pos<posClosing)
                  {
                  betweenBraces = true;
                  }
                break;
                }
              openCurly--;
              }
109

110 111
            // Check if we are not at the end of the line
            bool endofline = true;
112 113
            int eof = pos+1;
            while(eof < (int)line.size())
114
              {
115
              if(line[eof] != ' ' && line[eof] != '\n'
116 117 118 119 120 121 122 123 124 125 126 127
                 && line[eof] != '\r' && line[eof] != '\t')
                {
                endofline = false;
                break;
                }
              eof++;
              }

            if(!betweenBraces && !endofline)
              {
              vars++;
              }
128
            pos = static_cast<long int>(line.find(',',pos+1));
129
            }
130

131 132 133 134 135 136 137
          if(vars > max)
            {
            Error error;
            error.line = this->GetLineNumber(posType,true);
            error.line2 = error.line;
            error.number = VARIABLEPERLINE;
            error.description = "Number of variable per line exceed: ";
138 139 140
            char* localval = new char[10];
            sprintf(localval,"%d",vars);
            error.description += localval;
141
            error.description += " (max=";
142 143 144 145
            delete [] localval;
            localval = new char[10];
            sprintf(localval,"%ld",max);
            error.description += localval;
146
            error.description += ")";
147
            delete [] localval;
148 149 150 151 152 153 154 155 156 157 158 159 160
            m_ErrorList.push_back(error);
            hasError = true;
            }
          }
        }// end firstWord
      posType = m_BufferNoComment.find(typeToFind,posType+1);
      }
    }

  return !hasError;
}

} // end namespace kws