Logo Search packages:      
Sourcecode: codeblocks version File versions  Download package

string astyle::ASBeautifier::beautify ( const string &  originalLine ) [virtual, inherited]

beautify a line of source code. every line of source code in a source code file should be sent one after the other to the beautify method.

Returns:
the indented line.
Parameters:
originalLinethe original unindented line.

Definition at line 649 of file ASBeautifier.cpp.

References astyle::ASBeautifier::ASBeautifier(), astyle::ASBeautifier::beautify(), astyle::ASBeautifier::convertTabToSpaces(), astyle::ASBeautifier::getNextProgramCharDistance(), astyle::ASBeautifier::indexOf(), astyle::ASBeautifier::registerInStatementIndent(), and astyle::ASBeautifier::trim().

Referenced by astyle::ASBeautifier::beautify(), nextLine(), and astyle::ASBeautifier::nextLine().

{
      string line;
      bool isInLineComment = false;
      bool lineStartsInComment = false;
      bool isInClass = false;
      bool isInSwitch = false;
      bool isInOperator = false;
      bool isSpecialChar = false;
      bool haveCaseIndent = false;
      bool lineBeginsWithBracket = false;
      bool closingBracketReached = false;
      bool shouldIndentBrackettedLine = true;
      bool previousLineProbation = (probationHeader != NULL);
      bool isInQuoteContinuation = isInVerbatimQuote | haveLineContinuationChar;
      char ch = ' ';
      char prevCh;
      char tempCh;
      int tabCount = 0;
      int spaceTabCount = 0;
      int lineOpeningBlocksNum = 0;
      int lineClosingBlocksNum = 0;
      int tabIncrementIn = 0;
      int i;
      int iPrelim;
      string outBuffer; // the newly idented line is buffered here
      const string *lastLineHeader = NULL;

      currentHeader = NULL;
      lineStartsInComment = isInComment;
      blockCommentNoBeautify = blockCommentNoIndent;
      lineOpensComment = false;
      previousLineProbationTab = false;
      haveLineContinuationChar = false;

      // handle and remove white spaces around the line:
      // If not in comment, first find out size of white space before line,
      // so that possible comments starting in the line continue in
      // relation to the preliminary white-space.
      if (isInQuoteContinuation)
      {
            // trim a single space added by ASFormatter, otherwise leave it alone
            if (!(originalLine.length() == 1 && originalLine[0] == ' '))
                  line = originalLine;
      }
      else if (!isInComment)
      {
            line = trim(originalLine);
            if (line.length() > 0 && line[0] == '{')
                  lineBeginsWithBracket = true;

            size_t j = line.find_first_not_of(" \t{");
            if (j != string::npos && line.compare(j, 2, "/*") == 0)
                  lineOpensComment = true;
      }
      else
      {
            // trim the end of comment lines
            line = originalLine;
            size_t trimEnd = line.find_last_not_of(" \t");
            if (trimEnd == string::npos)
                  trimEnd = 0;
            else
                  trimEnd++;
            if (trimEnd < line.length())
                  line.erase(trimEnd);
      }

      if (line.length() == 0)
      {
            if (backslashEndsPrevLine)  // must continue to clear variables
                  line = ' ';
            else if (emptyLineFill && !isInQuoteContinuation && headerStack->size() > 0)
                  return preLineWS(prevFinalLineSpaceTabCount, prevFinalLineTabCount);
            else
                  return line;
      }

      // handle preprocessor commands
      // except C# region and endregion

      if (!isInComment
              && (line[0] == '#' || backslashEndsPrevLine)
              && line.compare(0, 7, "#region") != 0
              && line.compare(0, 10, "#endregion") != 0)
      {
            if (line[0] == '#')
            {
                  string preproc = trim(string(line.c_str() + 1));

                  // When finding a multi-lined #define statement, the original beautifier
                  // 1. sets its isInDefineDefinition flag
                  // 2. clones a new beautifier that will be used for the actual indentation
                  //    of the #define. This clone is put into the activeBeautifierStack in order
                  //    to be called for the actual indentation.
                  // The original beautifier will have isInDefineDefinition = true, isInDefine = false
                  // The cloned beautifier will have   isInDefineDefinition = true, isInDefine = true
                  if (preprocessorIndent && preproc.compare(0, 6, "define") == 0 && line[line.length() - 1] == '\\')
                  {
                        if (!isInDefineDefinition)
                        {
                              ASBeautifier *defineBeautifier;

                              // this is the original beautifier
                              isInDefineDefinition = true;

                              // push a new beautifier into the active stack
                              // this beautifier will be used for the indentation of this define
                              defineBeautifier = new ASBeautifier(*this);
                              activeBeautifierStack->push_back(defineBeautifier);
                        }
                        else
                        {
                              // the is the cloned beautifier that is in charge of indenting the #define.
                              isInDefine = true;
                        }
                  }
                  else if (preproc.compare(0, 2, "if") == 0)
                  {
                        // push a new beautifier into the stack
                        waitingBeautifierStackLengthStack->push_back(waitingBeautifierStack->size());
                        activeBeautifierStackLengthStack->push_back(activeBeautifierStack->size());
                        waitingBeautifierStack->push_back(new ASBeautifier(*this));
                  }
                  else if (preproc.compare(0, 4/*2*/, "else") == 0)
                  {
                        if (waitingBeautifierStack && !waitingBeautifierStack->empty())
                        {
                              // MOVE current waiting beautifier to active stack.
                              activeBeautifierStack->push_back(waitingBeautifierStack->back());
                              waitingBeautifierStack->pop_back();
                        }
                  }
                  else if (preproc.compare(0, 4, "elif") == 0)
                  {
                        if (waitingBeautifierStack && !waitingBeautifierStack->empty())
                        {
                              // append a COPY current waiting beautifier to active stack, WITHOUT deleting the original.
                              activeBeautifierStack->push_back(new ASBeautifier(*(waitingBeautifierStack->back())));
                        }
                  }
                  else if (preproc.compare(0, 5, "endif") == 0)
                  {
                        int stackLength;
                        ASBeautifier *beautifier;

                        if (waitingBeautifierStackLengthStack && !waitingBeautifierStackLengthStack->empty())
                        {
                              stackLength = waitingBeautifierStackLengthStack->back();
                              waitingBeautifierStackLengthStack->pop_back();
                              while ((int) waitingBeautifierStack->size() > stackLength)
                              {
                                    beautifier = waitingBeautifierStack->back();
                                    waitingBeautifierStack->pop_back();
                                    delete beautifier;
                              }
                        }

                        if (!activeBeautifierStackLengthStack->empty())
                        {
                              stackLength = activeBeautifierStackLengthStack->back();
                              activeBeautifierStackLengthStack->pop_back();
                              while ((int) activeBeautifierStack->size() > stackLength)
                              {
                                    beautifier = activeBeautifierStack->back();
                                    activeBeautifierStack->pop_back();
                                    delete beautifier;
                              }
                        }
                  }
            }

            // check if the last char is a backslash
            if (line.length() > 0)
                  backslashEndsPrevLine = (line[line.length() - 1] == '\\');
            else
                  backslashEndsPrevLine = false;

            // check if this line ends a multi-line #define
            // if so, use the #define's cloned beautifier for the line's indentation
            // and then remove it from the active beautifier stack and delete it.
            if (!backslashEndsPrevLine && isInDefineDefinition && !isInDefine)
            {
                  string beautifiedLine;
                  ASBeautifier *defineBeautifier;

                  isInDefineDefinition = false;
                  defineBeautifier = activeBeautifierStack->back();
                  activeBeautifierStack->pop_back();

                  beautifiedLine = defineBeautifier->beautify(line);
                  delete defineBeautifier;
                  return beautifiedLine;
            }

            // unless this is a multi-line #define, return this precompiler line as is.
            if (!isInDefine && !isInDefineDefinition)
                  return originalLine;
      }

      // if there exists any worker beautifier in the activeBeautifierStack,
      // then use it instead of me to indent the current line.
      // variables set by ASFormatter must be updated.
      if (!isInDefine && activeBeautifierStack != NULL && !activeBeautifierStack->empty())
      {
            activeBeautifierStack->back()->inLineNumber = inLineNumber;
            activeBeautifierStack->back()->horstmannIndentInStatement = horstmannIndentInStatement;
            activeBeautifierStack->back()->nonInStatementBracket = nonInStatementBracket;
            activeBeautifierStack->back()->lineCommentNoBeautify = lineCommentNoBeautify;
            activeBeautifierStack->back()->isNonInStatementArray = isNonInStatementArray;
            activeBeautifierStack->back()->isSharpAccessor = isSharpAccessor;
            activeBeautifierStack->back()->isSharpDelegate = isSharpDelegate;
            // must return originalLine not the trimmed line
            return activeBeautifierStack->back()->beautify(originalLine);
      }

      // calculate preliminary indentation based on data from past lines
      if (!inStatementIndentStack->empty())
            spaceTabCount = inStatementIndentStack->back();

      for (i = 0; i < (int) headerStack->size(); i++)
      {
            isInClass = false;

            if (blockIndent)
            {
                  // do NOT indent opening block for these headers
                  if (!((*headerStack)[i] == &AS_NAMESPACE
                          || (*headerStack)[i] == &AS_CLASS
                          || (*headerStack)[i] == &AS_STRUCT
                          || (*headerStack)[i] == &AS_UNION
                          || (*headerStack)[i] == &AS_CONST
                          || (*headerStack)[i] == &AS_INTERFACE
                          || (*headerStack)[i] == &AS_THROWS
                          || (*headerStack)[i] == &AS_STATIC))
                        ++tabCount;
            }
            else if (!(i > 0 && (*headerStack)[i-1] != &AS_OPEN_BRACKET
                       && (*headerStack)[i] == &AS_OPEN_BRACKET))
                  ++tabCount;

            if (!isJavaStyle() && !namespaceIndent && i >= 1
                    && (*headerStack)[i-1] == &AS_NAMESPACE
                    && (*headerStack)[i] == &AS_OPEN_BRACKET)
                  --tabCount;

            if (isCStyle() && i >= 1
                    && (*headerStack)[i-1] == &AS_CLASS
                    && (*headerStack)[i] == &AS_OPEN_BRACKET)
            {
                  if (classIndent)
                        ++tabCount;
                  isInClass = true;
            }

            // is the switchIndent option is on, indent switch statements an additional indent.
            else if (switchIndent && i > 1
                     && (*headerStack)[i-1] == &AS_SWITCH
                     && (*headerStack)[i] == &AS_OPEN_BRACKET)
            {
                  ++tabCount;
                  isInSwitch = true;
            }

      }

      iPrelim = i;

      if (!lineStartsInComment
              && isCStyle()
              && isInClass
              && classIndent
              && headerStack->size() >= 2
              && (*headerStack)[headerStack->size()-2] == &AS_CLASS
              && (*headerStack)[headerStack->size()-1] == &AS_OPEN_BRACKET
              && line[0] == '}'
              && bracketBlockStateStack->back() == true)
            --tabCount;

      else if (!lineStartsInComment
               && isInSwitch
               && switchIndent
               && headerStack->size() >= 2
               && (*headerStack)[headerStack->size()-2] == &AS_SWITCH
               && (*headerStack)[headerStack->size()-1] == &AS_OPEN_BRACKET
               && line[0] == '}')
            --tabCount;

      if (isInClassHeader)
      {
            if (lineStartsInComment || lineOpensComment)
            {
                  if (!lineBeginsWithBracket)
                        tabCount--;
            }
            else if (isCStyle() && !isClassAccessModifier(line))
            {
                  isInClassHeaderTab = true;
                  tabCount += classInitializerTabs;
            }
            else if (blockIndent)
            {
                  if (!lineBeginsWithBracket)
                        tabCount++;
            }
      }

      if (isInConditional)
      {
            --tabCount;
      }


      // parse characters in the current line.

      for (i = 0; i < (int) line.length(); i++)
      {
            outBuffer.append(1, line[i]);

            tempCh = line[i];
            prevCh = ch;
            ch = tempCh;

            if (isWhiteSpace(ch))
            {
                  if (ch == '\t')
                        tabIncrementIn += convertTabToSpaces(i, tabIncrementIn);
                  continue;
            }

            // handle special characters (i.e. backslash+character such as \n, \t, ...)

            if (isInQuote && !isInVerbatimQuote)
            {
                  if (isSpecialChar)
                  {
                        isSpecialChar = false;
                        continue;
                  }
                  if (line.compare(i, 2, "\\\\") == 0)
                  {
                        outBuffer.append(1, '\\');
                        i++;
                        continue;
                  }
                  if (ch == '\\')
                  {
                        if (peekNextChar(line, i) == ' ')   // is this '\' at end of line
                              haveLineContinuationChar = true;
                        else
                              isSpecialChar = true;
                        continue;
                  }
            }
            else if (isInDefine && ch == '\\')
                  continue;

            // handle quotes (such as 'x' and "Hello Dolly")
            if (!(isInComment || isInLineComment) && (ch == '"' || ch == '\''))
            {
                  if (!isInQuote)
                  {
                        quoteChar = ch;
                        isInQuote = true;
                        if (isSharpStyle() && prevCh == '@')
                              isInVerbatimQuote = true;
                  }
                  else if (isInVerbatimQuote && ch == '"')
                  {
                        if (peekNextChar(line, i) == '"')           // check consecutive quotes
                        {
                              outBuffer.append(1, '"');
                              i++;
                        }
                        else
                        {
                              isInQuote = false;
                              isInVerbatimQuote = false;
                        }
                  }
                  else if (quoteChar == ch)
                  {
                        isInQuote = false;
                        isInStatement = true;
                        continue;
                  }
            }
            if (isInQuote)
                  continue;

            // handle comments

            if (!(isInComment || isInLineComment) && line.compare(i, 2, "//") == 0)
            {
                  isInLineComment = true;
                  outBuffer.append(1, '/');
                  i++;
                  continue;
            }
            else if (!(isInComment || isInLineComment) && line.compare(i, 2, "/*") == 0)
            {
                  isInComment = true;
                  outBuffer.append(1, '*');
                  i++;
                  if (!lineOpensComment)                          // does line start with comment?
                        blockCommentNoIndent = true;        // if no, cannot indent continuation lines
                  continue;
            }
            else if ((isInComment || isInLineComment) && line.compare(i, 2, "*/") == 0)
            {
                  isInComment = false;
                  outBuffer.append(1, '/');
                  i++;
                  blockCommentNoIndent = false;           // ok to indent next comment
                  continue;
            }
            // treat C# '#region' and '#endregion' statements as a line comment
            else if (isSharpStyle() &&
                     (line.compare(i, 7, "#region") == 0 || line.compare(i, 10, "#endregion") == 0))
            {
                  isInLineComment = true;
//                continue;
            }

            if (isInComment || isInLineComment)
            {
                  // append rest of the comment up to the comment end
                  while (i+1 < (int) line.length()
                          && line.compare(i+1, 2, "*/") != 0)
                        outBuffer.append(1, line[++i]);
                  continue;
            }

            // if we have reached this far then we are NOT in a comment or string of special character...

            if (probationHeader != NULL)
            {
                  if (((probationHeader == &AS_STATIC || probationHeader == &AS_CONST) && ch == '{')
                          || (probationHeader == &AS_SYNCHRONIZED && ch == '('))
                  {
                        // insert the probation header as a new header
                        isInHeader = true;
                        headerStack->push_back(probationHeader);

                        // handle the specific probation header
                        isInConditional = (probationHeader == &AS_SYNCHRONIZED);

                        isInStatement = false;
                        // if the probation comes from the previous line, then indent by 1 tab count.
                        if (previousLineProbation
                                && ch == '{'
                                && !(blockIndent
                                     && (probationHeader == &AS_CONST || probationHeader == &AS_STATIC)))
                        {
                              tabCount++;
                              previousLineProbationTab = true;
                        }
                        previousLineProbation = false;
                  }

                  // dismiss the probation header
                  probationHeader = NULL;
            }

            prevNonSpaceCh = currentNonSpaceCh;
            currentNonSpaceCh = ch;
            if (!isLegalNameChar(ch) && ch != ',' && ch != ';')
            {
                  prevNonLegalCh = currentNonLegalCh;
                  currentNonLegalCh = ch;
            }

            if (isInHeader)
            {
                  isInHeader = false;
                  currentHeader = headerStack->back();
            }
            else
                  currentHeader = NULL;

            if (isCStyle() && isInTemplate
                    && (ch == '<' || ch == '>')
                    &&  findOperator(line, i, nonAssignmentOperators) == NULL)
            {
                  if (ch == '<')
                  {
                        ++templateDepth;
                  }
                  else if (ch == '>')
                  {
                        if (--templateDepth <= 0)
                        {
                              if (isInTemplate)
                                    ch = ';';
                              else
                                    ch = 't';
                              isInTemplate = false;
                              templateDepth = 0;
                        }
                  }
            }

            // handle parenthesies
            if (ch == '(' || ch == '[' || ch == ')' || ch == ']')
            {
                  if (ch == '(' || ch == '[')
                  {
                        isInOperator = false;
                        // if have a struct header, this is a declaration not a definition
                        if (ch == '('
                                && (isInClassHeader || isInClassHeaderTab)
                                && headerStack->size() > 0
                                && headerStack->back() == &AS_STRUCT)
                        {
                              headerStack->pop_back();
                              isInClassHeader = false;
                              // -1 for isInClassHeader, -2 for isInClassHeaderTab
                              if (isInClassHeaderTab)
                              {
                                    tabCount -= (1 + classInitializerTabs);
                                    isInClassHeaderTab = false;
                              }
                              if (tabCount < 0)
                                    tabCount = 0;
                        }

                        if (parenDepth == 0)
                        {
                              parenStatementStack->push_back(isInStatement);
                              isInStatement = true;
                        }
                        parenDepth++;

                        inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());

                        if (currentHeader != NULL)
                              registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, minConditionalIndent/*indentLength*2*/, true);
                        else
                              registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, true);
                  }
                  else if (ch == ')' || ch == ']')
                  {
                        parenDepth--;
                        if (parenDepth == 0)
                        {
                              if (!parenStatementStack->empty())      // in case of unmatched closing parens
                              {
                                    isInStatement = parenStatementStack->back();
                                    parenStatementStack->pop_back();
                              }
                              ch = ' ';
                              isInConditional = false;
                        }

                        if (!inStatementIndentStackSizeStack->empty())
                        {
                              int previousIndentStackSize = inStatementIndentStackSizeStack->back();
                              inStatementIndentStackSizeStack->pop_back();
                              while (previousIndentStackSize < (int) inStatementIndentStack->size())
                                    inStatementIndentStack->pop_back();

                              if (!parenIndentStack->empty())
                              {
                                    int poppedIndent = parenIndentStack->back();
                                    parenIndentStack->pop_back();

                                    if (i == 0)
                                          spaceTabCount = poppedIndent;
                              }
                        }
                  }

                  continue;
            }


            if (ch == '{')
            {
                  // first, check if '{' is a block-opener or an static-array opener
                  bool isBlockOpener = ((prevNonSpaceCh == '{' && bracketBlockStateStack->back())
                                        || prevNonSpaceCh == '}'
                                        || prevNonSpaceCh == ')'
                                        || prevNonSpaceCh == ';'
                                        || peekNextChar(line, i) == '{'
                                        || isInClassHeader
                                        || isNonInStatementArray
                                        || isSharpAccessor
                                        || isSharpDelegate
                                        || isInExtern
                                        || (isInDefine &&
                                            (prevNonSpaceCh == '('
                                             || isLegalNameChar(prevNonSpaceCh))));

                  //if (isNonInStatementArray
                  //        && prevNonSpaceCh != ')'
                  //        && prevNonSpaceCh != '='
                  //        && !isInEnum
                  //        && i == nonInStatementBracket)
                  //    isBlockOpener = false;

                  isInClassHeader = false;

                  if (!isBlockOpener && currentHeader != NULL)
                  {
                        for (size_t n = 0; n < nonParenHeaders.size(); n++)
                              if (currentHeader == nonParenHeaders[n])
                              {
                                    isBlockOpener = true;
                                    break;
                              }
                  }

                  // TODO: TEMPORARY??? fix to give C# }) statements a full indent
                  // check for anonymous method
                  //if (isBlockOpener && isSharpStyle() && !parenIndentStack->empty())
                  //    isBlockOpener = false;

                  bracketBlockStateStack->push_back(isBlockOpener);

                  if (!isBlockOpener)
                  {
                        inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
                        registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, true);
                        parenDepth++;
                        if (i == 0)
                              shouldIndentBrackettedLine = false;

                        continue;
                  }

                  // this bracket is a block opener...

                  ++lineOpeningBlocksNum;

                  if (isInClassHeaderTab)
                  {
                        isInClassHeaderTab = false;
                        // decrease tab count if bracket is broken
                        size_t firstChar = line.find_first_not_of(" \t");
                        if (firstChar != string::npos
                                && line[firstChar] == '{'
                                && (int) firstChar == i)
                        {
                              tabCount -= classInitializerTabs;
                              // decrease one more if an empty class
                              if (headerStack->size() > 0
                                      && (*headerStack).back() == &AS_CLASS)
                              {
                                    int nextChar = getNextProgramCharDistance(line, i);
                                    if (line[nextChar] == '}')
                                          tabCount--;
                              }
                        }
                  }

                  if (bracketIndent && !namespaceIndent && headerStack->size() > 0
                          && (*headerStack).back() == &AS_NAMESPACE)
                  {
                        shouldIndentBrackettedLine = false;
                        tabCount--;
                  }

                  // do not allow inStatementIndent - should occur for Java files only
                  //if (inStatementIndentStack->size() > 0)
                  //{
                  //    spaceTabCount = 0;
                  //    inStatementIndentStack->back() = 0;
                  //}

                  blockParenDepthStack->push_back(parenDepth);
                  blockStatementStack->push_back(isInStatement);

                  inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
                  if (inStatementIndentStack->size() > 0)
                  {
                        spaceTabCount = 0;
                        inStatementIndentStack->back() = 0;
                  }

                  blockTabCount += isInStatement ? 1 : 0;
                  parenDepth = 0;
                  isInStatement = false;

                  tempStacks->push_back(new vector<const string*>);
                  headerStack->push_back(&AS_OPEN_BRACKET);
                  lastLineHeader = &AS_OPEN_BRACKET;

                  continue;
            }

            //check if a header has been reached
            bool isPotentialHeader = isCharPotentialHeader(line, i);

            if (isPotentialHeader)
            {
                  const string *newHeader = findHeader(line, i, headers);

                  if (newHeader != NULL)
                  {
                        char peekChar = peekNextChar(line, i + newHeader->length() - 1);

                        // is not a header if part of a definition
                        if (peekChar == ',' || peekChar == ')')
                              newHeader = NULL;
                        // the following accessor definitions are NOT headers
                        // goto default; is NOT a header
                        // default(int) keyword in C# is NOT a header
                        else if ((newHeader == &AS_GET || newHeader == &AS_SET || newHeader == &AS_DEFAULT)
                                 && (peekChar == ';' ||  peekChar == '('))
                        {
                              newHeader = NULL;
                        }
                  }

                  if (newHeader != NULL)
                  {
                        // if we reached here, then this is a header...
                        bool isIndentableHeader = true;

                        isInHeader = true;

                        vector<const string*> *lastTempStack;
                        if (tempStacks->empty())
                              lastTempStack = NULL;
                        else
                              lastTempStack = tempStacks->back();

                        // if a new block is opened, push a new stack into tempStacks to hold the
                        // future list of headers in the new block.

                        // take care of the special case: 'else if (...)'
                        if (newHeader == &AS_IF && lastLineHeader == &AS_ELSE)
                        {
                              headerStack->pop_back();
                        }

                        // take care of 'else'
                        else if (newHeader == &AS_ELSE)
                        {
                              if (lastTempStack != NULL)
                              {
                                    int indexOfIf = indexOf(*lastTempStack, &AS_IF);
                                    if (indexOfIf != -1)
                                    {
                                          // recreate the header list in headerStack up to the previous 'if'
                                          // from the temporary snapshot stored in lastTempStack.
                                          int restackSize = lastTempStack->size() - indexOfIf - 1;
                                          for (int r = 0; r < restackSize; r++)
                                          {
                                                headerStack->push_back(lastTempStack->back());
                                                lastTempStack->pop_back();
                                          }
                                          if (!closingBracketReached)
                                                tabCount += restackSize;
                                    }
                                    /*
                                     * If the above if is not true, i.e. no 'if' before the 'else',
                                     * then nothing beautiful will come out of this...
                                     * I should think about inserting an Exception here to notify the caller of this...
                                     */
                              }
                        }

                        // check if 'while' closes a previous 'do'
                        else if (newHeader == &AS_WHILE)
                        {
                              if (lastTempStack != NULL)
                              {
                                    int indexOfDo = indexOf(*lastTempStack, &AS_DO);
                                    if (indexOfDo != -1)
                                    {
                                          // recreate the header list in headerStack up to the previous 'do'
                                          // from the temporary snapshot stored in lastTempStack.
                                          int restackSize = lastTempStack->size() - indexOfDo - 1;
                                          for (int r = 0; r < restackSize; r++)
                                          {
                                                headerStack->push_back(lastTempStack->back());
                                                lastTempStack->pop_back();
                                          }
                                          if (!closingBracketReached)
                                                tabCount += restackSize;
                                    }
                              }
                        }
                        // check if 'catch' closes a previous 'try' or 'catch'
                        else if (newHeader == &AS_CATCH || newHeader == &AS_FINALLY)
                        {
                              if (lastTempStack != NULL)
                              {
                                    int indexOfTry = indexOf(*lastTempStack, &AS_TRY);
                                    if (indexOfTry == -1)
                                          indexOfTry = indexOf(*lastTempStack, &AS_CATCH);
                                    if (indexOfTry != -1)
                                    {
                                          // recreate the header list in headerStack up to the previous 'try'
                                          // from the temporary snapshot stored in lastTempStack.
                                          int restackSize = lastTempStack->size() - indexOfTry - 1;
                                          for (int r = 0; r < restackSize; r++)
                                          {
                                                headerStack->push_back(lastTempStack->back());
                                                lastTempStack->pop_back();
                                          }

                                          if (!closingBracketReached)
                                                tabCount += restackSize;
                                    }
                              }
                        }
                        else if (newHeader == &AS_CASE)
                        {
                              isInCase = true;
                              if (!haveCaseIndent)
                              {
                                    haveCaseIndent = true;
                                    if (!lineBeginsWithBracket)
                                          --tabCount;
                              }
                        }
                        else if (newHeader == &AS_DEFAULT)
                        {
                              isInCase = true;
                              --tabCount;
                        }
                        else if (newHeader == &AS_STATIC
                                 || newHeader == &AS_SYNCHRONIZED
                                 || (newHeader == &AS_CONST && isCStyle()))
                        {
                              if (!headerStack->empty() &&
                                      (headerStack->back() == &AS_STATIC
                                       || headerStack->back() == &AS_SYNCHRONIZED
                                       || headerStack->back() == &AS_CONST))
                              {
                                    isIndentableHeader = false;
                              }
                              else
                              {
                                    isIndentableHeader = false;
                                    probationHeader = newHeader;
                              }
                        }
                        else if (newHeader == &AS_CONST)
                        {
                              isIndentableHeader = false;
                        }
                        else if (newHeader == &AS_TEMPLATE)
                        {
                              if (isCStyle())
                                    isInTemplate = true;
                              isIndentableHeader = false;
                        }

                        if (isIndentableHeader)
                        {
                              headerStack->push_back(newHeader);
                              isInStatement = false;
                              if (indexOf(nonParenHeaders, newHeader) == -1)
                              {
                                    isInConditional = true;
                              }
                              lastLineHeader = newHeader;
                        }
                        else
                              isInHeader = false;

                        outBuffer.append(newHeader->substr(1));
                        i += newHeader->length() - 1;

                        continue;
                  }  // newHeader != NULL
            }   // isPotentialHeader

            if (ch == '?')
                  isInQuestion = true;

            // special handling of 'case' statements
            if (ch == ':')
            {
                  if ((int) line.length() > i + 1 && line[i+1] == ':') // look for ::
                  {
                        ++i;
                        outBuffer.append(1, ':');
                        ch = ' ';
                        continue;
                  }

                  else if (isInQuestion)
                  {
                        isInQuestion = false;
                  }

                  else if (isCStyle() && isInClassHeader)
                  {
                        // found a 'class A : public B' definition
                        // so do nothing special
                  }

                  else if (isCStyle() && isdigit(peekNextChar(line, i)))
                  {
                        // found a bit field
                        // so do nothing special
                  }

                  else if (isCStyle() && isInClass && prevNonSpaceCh != ')')
                  {
                        // found a 'private:' or 'public:' inside a class definition
                        --tabCount;
                  }

                  else if (isJavaStyle() && lastLineHeader == &AS_FOR)
                  {
                        // found a java for-each statement
                        // so do nothing special
                  }

                  else if (isCStyle() && prevNonSpaceCh == ')' && !isInCase)
                  {
                        isInClassHeader = true;
                        if (i == 0)
                              tabCount += classInitializerTabs;
                  }
                  else
                  {
                        currentNonSpaceCh = ';'; // so that brackets after the ':' will appear as block-openers
                        if (isInCase)
                        {
                              isInCase = false;
                              ch = ';'; // from here on, treat char as ';'
                        }
                        else if (isCStyle() || (isSharpStyle() && peekNextChar(line, i) == ';'))    // is in a label (e.g. 'label1:')
                        {
                              if (labelIndent)
                                    --tabCount; // unindent label by one indent
                              else if (!lineBeginsWithBracket)
                                    tabCount = 0; // completely flush indent to left
                        }
                  }
            }

            if ((ch == ';'  || (parenDepth > 0 && ch == ','))  && !inStatementIndentStackSizeStack->empty())
                  while ((int) inStatementIndentStackSizeStack->back() + (parenDepth > 0 ? 1 : 0)
                          < (int) inStatementIndentStack->size())
                        inStatementIndentStack->pop_back();


            // handle ends of statements
            if ((ch == ';' && parenDepth == 0) || ch == '}'/* || (ch == ',' && parenDepth == 0)*/)
            {
                  if (ch == '}')
                  {
                        // first check if this '}' closes a previous block, or a static array...
                        if (!bracketBlockStateStack->empty())
                        {
                              bool bracketBlockState = bracketBlockStateStack->back();
                              bracketBlockStateStack->pop_back();
                              if (!bracketBlockState)
                              {
                                    if (!inStatementIndentStackSizeStack->empty())
                                    {
                                          // this bracket is a static array

                                          int previousIndentStackSize = inStatementIndentStackSizeStack->back();
                                          inStatementIndentStackSizeStack->pop_back();
                                          while (previousIndentStackSize < (int) inStatementIndentStack->size())
                                                inStatementIndentStack->pop_back();
                                          parenDepth--;
                                          if (i == 0)
                                                shouldIndentBrackettedLine = false;

                                          if (!parenIndentStack->empty())
                                          {
                                                int poppedIndent = parenIndentStack->back();
                                                parenIndentStack->pop_back();
                                                if (i == 0)
                                                      spaceTabCount = poppedIndent;
                                          }
                                    }
                                    continue;
                              }
                        }

                        // this bracket is block closer...

                        ++lineClosingBlocksNum;

                        if (!inStatementIndentStackSizeStack->empty())
                              inStatementIndentStackSizeStack->pop_back();

                        if (!blockParenDepthStack->empty())
                        {
                              parenDepth = blockParenDepthStack->back();
                              blockParenDepthStack->pop_back();
                              isInStatement = blockStatementStack->back();
                              blockStatementStack->pop_back();

                              if (isInStatement)
                                    blockTabCount--;
                        }

                        closingBracketReached = true;
                        int headerPlace = indexOf(*headerStack, &AS_OPEN_BRACKET);
                        if (headerPlace != -1)
                        {
                              const string *popped = headerStack->back();
                              while (popped != &AS_OPEN_BRACKET)
                              {
                                    headerStack->pop_back();
                                    popped = headerStack->back();
                              }
                              headerStack->pop_back();

                              // do not indent namespace bracket unless namespaces are indented
                              if (!namespaceIndent && headerStack->size() > 0
                                      && (*headerStack).back() == &AS_NAMESPACE)
                                    shouldIndentBrackettedLine = false;

                              if (!tempStacks->empty())
                              {
                                    vector<const string*> *temp =  tempStacks->back();
                                    tempStacks->pop_back();
                                    delete temp;
                              }
                        }


                        ch = ' '; // needed due to cases such as '}else{', so that headers ('else' tn tih case) will be identified...
                  }

                  /*
                   * Create a temporary snapshot of the current block's header-list in the
                   * uppermost inner stack in tempStacks, and clear the headerStack up to
                   * the begining of the block.
                   * Thus, the next future statement will think it comes one indent past
                   * the block's '{' unless it specifically checks for a companion-header
                   * (such as a previous 'if' for an 'else' header) within the tempStacks,
                   * and recreates the temporary snapshot by manipulating the tempStacks.
                   */
                  if (!tempStacks->back()->empty())
                        while (!tempStacks->back()->empty())
                              tempStacks->back()->pop_back();
                  while (!headerStack->empty() && headerStack->back() != &AS_OPEN_BRACKET)
                  {
                        tempStacks->back()->push_back(headerStack->back());
                        headerStack->pop_back();
                  }

                  if (parenDepth == 0 && ch == ';')
                        isInStatement = false;

                  previousLastLineHeader = NULL;
                  isInClassHeader = false;
                  isInQuestion = false;

                  continue;
            }

            if (isPotentialHeader)
            {
                  // check for preBlockStatements in C/C++ ONLY if not within parenthesies
                  // (otherwise 'struct XXX' statements would be wrongly interpreted...)
                  if (!isInTemplate && !(isCStyle() && parenDepth > 0))
                  {
                        const string *newHeader = findHeader(line, i, preBlockStatements);
                        if (newHeader != NULL)
                        {
                              isInClassHeader = true;

                              if (!isSharpStyle())
                                    headerStack->push_back(newHeader);
                              // do not need 'where' in the headerStack
                              // do not need second 'class' statement in a row
                              else if (!(newHeader == &AS_WHERE
                                         || (newHeader == &AS_CLASS
                                             && headerStack->size() > 0
                                             && headerStack->back() == &AS_CLASS)))
                                    headerStack->push_back(newHeader);

                              outBuffer.append(newHeader->substr(1));
                              i += newHeader->length() - 1;
                              continue;
                        }
                  }
                  const string *foundIndentableHeader = findHeader(line, i, indentableHeaders);

                  if (foundIndentableHeader != NULL)
                  {
                        // must bypass the header before registering the in statement
                        outBuffer.append(foundIndentableHeader->substr(1));
                        i += foundIndentableHeader->length() - 1;
                        if (!isInOperator && !isInTemplate && !isNonInStatementArray)
                        {
                              registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, false);
                              isInStatement = true;
                        }
                        continue;
                  }

                  if (isCStyle() && findKeyword(line, i, AS_OPERATOR))
                        isInOperator = true;

                  // "new" operator is a pointer, not a calculation
                  if (findKeyword(line, i, AS_NEW))
                  {
                        if (prevNonSpaceCh == '=' && isInStatement && !inStatementIndentStack->empty())
                              inStatementIndentStack->back() = 0;
                  }

                  // append the entire name for all others
                  string name = getCurrentWord(line, i);
                  outBuffer.append(name.substr(1));
                  i += name.length() - 1;
                  continue;
            }

            // Handle operators

            bool isPotentialOperator = isCharPotentialOperator(ch);

            if (isPotentialOperator)
            {
                  // Check if an operator has been reached.
                  const string *foundAssignmentOp = findOperator(line, i, assignmentOperators);
                  const string *foundNonAssignmentOp = findOperator(line, i, nonAssignmentOperators);

                  // Since findHeader's boundry checking was not used above, it is possible
                  // that both an assignment op and a non-assignment op where found,
                  // e.g. '>>' and '>>='. If this is the case, treat the LONGER one as the
                  // found operator.
                  if (foundAssignmentOp != NULL && foundNonAssignmentOp != NULL)
                  {
                        if (foundAssignmentOp->length() < foundNonAssignmentOp->length())
                              foundAssignmentOp = NULL;
                        else
                              foundNonAssignmentOp = NULL;
                  }

                  if (foundNonAssignmentOp != NULL)
                  {
                        if (foundNonAssignmentOp->length() > 1)
                        {
                              outBuffer.append(foundNonAssignmentOp->substr(1));
                              i += foundNonAssignmentOp->length() - 1;
                        }
                  }

                  else if (foundAssignmentOp != NULL)
                  {
                        if (foundAssignmentOp->length() > 1)
                        {
                              outBuffer.append(foundAssignmentOp->substr(1));
                              i += foundAssignmentOp->length() - 1;
                        }

                        if (!isInOperator && !isInTemplate && !isNonInStatementArray)
                        {
                              registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, false);
                              isInStatement = true;
                        }
                  }
            }
      }   // end of for loop  *  end of for loop  *  end of for loop  *  end of for loop

      // handle special cases of unindentation:

      /*
       * if '{' doesn't follow an immediately previous '{' in the headerStack
       * (but rather another header such as "for" or "if", then unindent it
       * by one indentation relative to its block.
       */

      if (!lineStartsInComment
              && !blockIndent
              && outBuffer.length() > 0
              && outBuffer[0] == '{'
              && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum == lineClosingBlocksNum)
              && !(headerStack->size() > 1 && (*headerStack)[headerStack->size()-2] == &AS_OPEN_BRACKET)
              && shouldIndentBrackettedLine)
            --tabCount;

      // must check one less in headerStack if more than one header on a line (allow-addins)...
      else if (!lineStartsInComment
               && (int) headerStack->size() > iPrelim + 1
               && !blockIndent
               && outBuffer.length() > 0
               && outBuffer[0] == '{'
               && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum == lineClosingBlocksNum)
               && !(headerStack->size() > 2 && (*headerStack)[headerStack->size()-3] == &AS_OPEN_BRACKET)
               && shouldIndentBrackettedLine)
            --tabCount;

      // unindent a closing bracket...
      else if (!lineStartsInComment
               && outBuffer.length() > 0
               && outBuffer[0] == '}'
               && shouldIndentBrackettedLine)
            --tabCount;

      // correctly indent one-line-blocks...
      else if (!lineStartsInComment
               && outBuffer.length() > 0
               && lineOpeningBlocksNum > 0
               && lineOpeningBlocksNum == lineClosingBlocksNum
               && previousLineProbationTab)
            --tabCount; //lineOpeningBlocksNum - (blockIndent ? 1 : 0);

      // correctly indent class continuation lines...
      else if (!lineStartsInComment
               && !lineOpensComment
               && isInClassHeaderTab
               && !blockIndent
               && outBuffer.length() > 0
               && lineOpeningBlocksNum == 0
               && lineOpeningBlocksNum == lineClosingBlocksNum
               && (headerStack->size() > 0 && headerStack->back() == &AS_CLASS))
            --tabCount;

      if (tabCount < 0)
            tabCount = 0;

      // take care of extra bracket indentatation option...
      if (!lineStartsInComment
              && bracketIndent
              && shouldIndentBrackettedLine
              && outBuffer.length() > 0
              && (outBuffer[0] == '{' || outBuffer[0] == '}'))
            tabCount++;

      if (isInDefine)
      {
            if (outBuffer[0] == '#')
            {
                  string preproc = trim(string(outBuffer.c_str() + 1));
                  if (preproc.compare(0, 6, "define") == 0)
                  {
                        if (!inStatementIndentStack->empty()
                                && inStatementIndentStack->back() > 0)
                        {
                              defineTabCount = tabCount;
                        }
                        else
                        {
                              defineTabCount = tabCount - 1;
                              tabCount--;
                        }
                  }
            }

            tabCount -= defineTabCount;
      }

      if (tabCount < 0)
            tabCount = 0;
      if (lineCommentNoBeautify || blockCommentNoBeautify || isInQuoteContinuation)
            tabCount = spaceTabCount = 0;

      // finally, insert indentations into begining of line

      if (shouldForceTabIndentation)
      {
            tabCount += spaceTabCount / indentLength;
            spaceTabCount = spaceTabCount % indentLength;
      }

      outBuffer = preLineWS(spaceTabCount, tabCount) + outBuffer;

      prevFinalLineSpaceTabCount = spaceTabCount;
      prevFinalLineTabCount = tabCount;

      if (lastLineHeader != NULL)
            previousLastLineHeader = lastLineHeader;

      return outBuffer;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index