/**
 * @file indent.cpp
 * Does all the indenting stuff.
 *
 * $Id: indent.cpp 548 2006-10-21 02:31:55Z bengardner $
 */
#include "uncrustify_types.h"
#include "chunk_list.h"
#include "prototypes.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <cctype>


/**
 * General indenting approach:
 * Indenting levels are put into a stack.
 *
 * The stack entries contain:
 *  - opening type
 *  - brace column
 *  - continuation column
 *
 * Items that start a new stack item:
 *  - preprocessor (new parse frame)
 *  - Brace Open (Virtual brace also)
 *  - Paren, Square, Angle open
 *  - Assignments
 *  - C++ '<<' operator (ie, cout << "blah")
 *  - case
 *  - class colon
 *  - return
 *  - types
 *  - any other continued statement
 *
 * Note that the column of items marked 'PCF_WAS_ALIGNED' is not changed.
 *
 * For an open brace:
 *  - indent increases by indent_columns
 *  - if part of if/else/do/while/switch/etc, an extra indent may be applied
 *  - if in a paren, then cont-col is set to column + 1, ie "({ some code })"
 *
 * Open paren/square/angle:
 * cont-col is set to the column of the item after the open paren, unless
 * followed by a newline, then it is set to (brace-col + indent_columns).
 * Examples:
 *    a_really_long_funcion_name(
 *       param1, param2);
 *    a_really_long_funcion_name(param1,
 *                               param2);
 *
 * Assignments:
 * Assignments are continued aligned with the first item after the assignment,
 * unless the assign is followed by a newline.
 * Examples:
 *    some.variable = asdf + asdf +
 *                    asdf;
 *    some.variable =
 *       asdf + asdf + asdf;
 *
 * C++ << operator:
 * Handled the same as assignment.
 * Examples:
 *    cout << "this is test number: "
 *         << test_number;
 *
 * case:
 * Started with case or default.
 * Terminated with close brace at level or another case or default.
 * Special indenting according to various rules.
 *  - indent of case label
 *  - indent of case body
 *  - how to handle optional braces
 * Examples:
 * {
 * case x: {
 *    a++;
 *    break;
 *    }
 * case y:
 *    b--;
 *    break;
 * default:
 *    c++;
 *    break;
 * }
 *
 * Class colon:
 * Indent continuation by indent_columns:
 * class my_class :
 *    baseclass1,
 *    baseclass2
 * {
 *
 * Return: same as assignemts
 * If the return statement is not fully paren'd, then the indent continues at
 * the column of the item after the return. If it is paren'd, then the paren
 * rules apply.
 * return somevalue +
 *        othervalue;
 *
 * Type: pretty much the same as assignments
 * Examples:
 * int foo,
 *     bar,
 *     baz;
 *
 * Any other continued item:
 * There shouldn't be anything not covered by the above cases, but any other
 * continued item is indented by indent_columns:
 * Example:
 * somereallycrazylongname.with[lotsoflongstuff].
 *    thatreallyannoysme.whenIhavetomaintain[thecode] = 3;
 */

static void indent_comment(chunk_t *pc, int col);


void indent_to_column(chunk_t *pc, int column)
  {
  if (column < pc->column)
    column = pc->column;

  reindent_line(pc, column);
  }

/**
 * Changes the initial indent for a line to the given column
 *
 * @param pc      The chunk at the start of the line
 * @param column  The desired column
 */
void reindent_line(chunk_t *pc, int column)
  {
  int col_delta;
  int min_col;

  LOG_FMT(LINDLINE, "%s: %d] col %d on %.*s [%s] => %d\n",
          __func__, pc->orig_line, pc->column, pc->len, pc->str,
          get_token_name(pc->type), column);

  if (column == pc->column)
    return;

  col_delta  = column - pc->column;
  pc->column = column;
  min_col    = pc->column;

  do
    {
    min_col += pc->len;
    pc       = chunk_get_next(pc);

    if (pc != NULL)
      {
      if (chunk_is_comment(pc))
        {
        pc->column = pc->orig_col;

        if (pc->column < min_col)
          pc->column = min_col + 1;

        LOG_FMT(LINDLINE, "%s: set comment on line %d to col %d (orig %d)\n",
                __func__, pc->orig_line, pc->column, pc->orig_col);
        }
      else
        {
        pc->column += col_delta;

        if (pc->column < min_col)
          pc->column = min_col;
        }
      }
    }
  while ((pc != NULL) && (pc->nl_count == 0));
  }

/**
 * Starts a new entry
 *
 * @param frm  The parse frame
 * @param pc   The chunk causing the push
 */
static void indent_pse_push(struct parse_frame& frm, chunk_t *pc)
  {
  static int ref = 0;

    /* check the stack depth */
  if (frm.pse_tos < (int)ARRAY_SIZE(frm.pse))
    {
      /* Bump up the index and initialize it */
    frm.pse_tos++;
    memset(&frm.pse[frm.pse_tos], 0, sizeof(frm.pse[frm.pse_tos]));

    LOG_FMT(LINDPSE, "%4d] OPEN  [%d,%s] level=%d\n",
            pc->orig_line, frm.pse_tos, get_token_name(pc->type), pc->level);

    frm.pse[frm.pse_tos].type       = pc->type;
    frm.pse[frm.pse_tos].level      = pc->level;
    frm.pse[frm.pse_tos].open_line  = pc->orig_line;
    frm.pse[frm.pse_tos].ref        = ++ref;
    frm.pse[frm.pse_tos].in_preproc = (pc->flags & PCF_IN_PREPROC) != 0;
    }
  }

/**
 * Removes the top entry
 *
 * @param frm  The parse frame
 * @param pc   The chunk causing the push
 */
static void indent_pse_pop(struct parse_frame& frm, chunk_t *pc)
  {
    /* Bump up the index and initialize it */
  if (frm.pse_tos > 0)
    {
    if (pc != NULL)
      {
      LOG_FMT(LINDPSE, "%4d] CLOSE [%d,%s] on %s, started on line %d, level=%d/%d\n",
              pc->orig_line, frm.pse_tos,
              get_token_name(frm.pse[frm.pse_tos].type),
              get_token_name(pc->type),
              frm.pse[frm.pse_tos].open_line,
              frm.pse[frm.pse_tos].level,
              pc->level);
      }
    else
      {
      LOG_FMT(LINDPSE, " EOF] CLOSE [%d,%s], started on line %d\n",
              frm.pse_tos, get_token_name(frm.pse[frm.pse_tos].type),
              frm.pse[frm.pse_tos].open_line);
      }

    frm.pse_tos--;
    }
  }

static int token_indent(c_token_t type)
  {
  switch (type)
    {
    case CT_IF:
    case CT_DO:
      return 3;

    case CT_FOR:
    case CT_ELSE: // wacky, but that's what is wanted
      return 4;

    case CT_WHILE:
      return 6;

    case CT_SWITCH:
      return 7;

    case CT_ELSEIF:
      return 8;

    default:
      return 0;  //cpd.settings[UO_indent_braces].n;
    }
  }

/**
 * Change the top-level indentation only by changing the column member in
 * the chunk structures.
 * The level indicator must already be set.
 */
void indent_text(void)
  {
  chunk_t            *pc;
  chunk_t            *next;
  chunk_t            *prev       = NULL;
  bool did_newline = true;
  int idx;
  int vardefcol   = 0;
  int indent_size = cpd.settings[UO_indent_columns].n;
  int tmp;
  struct parse_frame frm;
  bool in_preproc = false, was_preproc = false;
  int indent_column;
  int cout_col            = 0;                 // for aligning << stuff
  int cout_level          = 0;                 // for aligning << stuff
  int parent_token_indent = 0;

  memset(&frm, 0, sizeof(frm));

    /* dummy top-level entry */
  frm.pse[0].indent     = 1;
  frm.pse[0].indent_tmp = 1;
  frm.pse[0].type       = CT_EOF;

  pc = chunk_get_head();

  while (pc != NULL)
    {
      /* Handle proprocessor transitions */
    was_preproc = in_preproc;
    in_preproc  = (pc->flags & PCF_IN_PREPROC) != 0;

    if (cpd.settings[UO_indent_brace_parent].b)
      parent_token_indent = token_indent(pc->parent_type);

      /* Clean up after a #define */
    if (!in_preproc)
      while ((frm.pse_tos > 0) && frm.pse[frm.pse_tos].in_preproc)
        indent_pse_pop(frm, pc);

    else
      {
      pf_check(&frm, pc);

      if (!was_preproc)
        {
          /* Transition into a preproc by creating a dummy indent */
        frm.level++;
        indent_pse_push(frm, pc);

        frm.pse[frm.pse_tos].indent     = 1 + indent_size;
        frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
        }
      }

    if ((cout_col > 0) &&
        (chunk_is_semicolon(pc) ||
         (pc->level < cout_level)))
      {
      cout_col   = 0;
      cout_level = 0;
      }

    /**
     * Handle non-brace closures
     */

    int old_pse_tos;

    do
      {
      old_pse_tos = frm.pse_tos;

      /* End anything that drops a level
       * REVISIT: not sure about the preproc check
       */
      if (!chunk_is_newline(pc) &&
          !chunk_is_comment(pc) &&
          ((pc->flags & PCF_IN_PREPROC) == 0) &&
          (frm.pse[frm.pse_tos].level > pc->level))
        indent_pse_pop(frm, pc);

      if (frm.pse[frm.pse_tos].level == pc->level)
        {
          /* process virtual braces closes (no text output) */
        if ((pc->type == CT_VBRACE_CLOSE) &&
            (frm.pse[frm.pse_tos].type == CT_VBRACE_OPEN))
          {
          indent_pse_pop(frm, pc);
          frm.level--;
          pc = chunk_get_next(pc);
          }

          /* End any assign operations with a semicolon on the same level */
        if ((frm.pse[frm.pse_tos].type == CT_ASSIGN) &&
            (chunk_is_semicolon(pc) ||
             (pc->type == CT_COMMA) ||
             (pc->type == CT_BRACE_OPEN)))
          indent_pse_pop(frm, pc);

          /* End any CPP class colon crap */
        if ((frm.pse[frm.pse_tos].type == CT_CLASS_COLON) &&
            ((pc->type == CT_BRACE_OPEN) ||
             chunk_is_semicolon(pc)))
          indent_pse_pop(frm, pc);

          /* a case is ended with another case or a close brace */
        if ((frm.pse[frm.pse_tos].type == CT_CASE) &&
            ((pc->type == CT_BRACE_CLOSE) ||
             (pc->type == CT_CASE)))
          indent_pse_pop(frm, pc);

          /* a return is ended with a semicolon */
        if ((frm.pse[frm.pse_tos].type == CT_RETURN) &&
            chunk_is_semicolon(pc))
          indent_pse_pop(frm, pc);

          /* Close out parens and squares */
        if ((frm.pse[frm.pse_tos].type == (pc->type - 1)) &&
            ((pc->type == CT_PAREN_CLOSE) ||
             (pc->type == CT_SPAREN_CLOSE) ||
             (pc->type == CT_FPAREN_CLOSE) ||
             (pc->type == CT_SQUARE_CLOSE) ||
             (pc->type == CT_ANGLE_CLOSE)))
          {
          indent_pse_pop(frm, pc);
          frm.paren_count--;
          }
        }
      }
    while (old_pse_tos > frm.pse_tos);

      /* Grab a copy of the current indent */
    indent_column = frm.pse[frm.pse_tos].indent_tmp;

    if (!chunk_is_newline(pc) && !chunk_is_comment(pc))
      {
      LOG_FMT(LINDPC, " -=[ %.*s ]=- top=%d %s %d/%d\n",
              pc->len, pc->str,
              frm.pse_tos,
              get_token_name(frm.pse[frm.pse_tos].type),
              frm.pse[frm.pse_tos].indent_tmp,
              frm.pse[frm.pse_tos].indent);
      }

    /**
     * Handle stuff that can affect the current indent:
     *  - brace close
     *  - vbrace open
     *  - brace open
     *  - case         (immediate)
     *  - labels       (immediate)
     *  - class colons (immediate)
     *
     * And some stuff that can't
     *  - open paren
     *  - open square
     *  - assignment
     *  - return
     */

    if (pc->type == CT_BRACE_CLOSE)
      {
      if (frm.pse[frm.pse_tos].type == CT_BRACE_OPEN)
        {
        indent_pse_pop(frm, pc);
        frm.level--;

          /* Update the indent_column if needed */
        if (!cpd.settings[UO_indent_braces].b &&
            (parent_token_indent == 0))
          indent_column = frm.pse[frm.pse_tos].indent_tmp;

        if ((pc->parent_type == CT_IF) ||
            (pc->parent_type == CT_ELSE) ||
            (pc->parent_type == CT_ELSEIF) ||
            (pc->parent_type == CT_DO) ||
            (pc->parent_type == CT_WHILE) ||
            (pc->parent_type == CT_SWITCH) ||
            (pc->parent_type == CT_FOR))
          indent_column += cpd.settings[UO_indent_brace].n;
        }
      }
    else if (pc->type == CT_VBRACE_OPEN)
      {
      frm.level++;
      indent_pse_push(frm, pc);

      frm.pse[frm.pse_tos].indent     = frm.pse[frm.pse_tos - 1].indent + indent_size;
      frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;

        /* Always indent on virtual braces */
      indent_column = frm.pse[frm.pse_tos].indent_tmp;
      }
    else if (pc->type == CT_BRACE_OPEN)
      {
      frm.level++;
      indent_pse_push(frm, pc);

      if (frm.paren_count != 0)
          /* We are inside ({ ... }) -- indent one tab from the paren */
        frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size;
      else
        {
          /* Use the prev indent level + indent_size. */
        frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;

          /* If this brace is part of a statement, bump it out by indent_brace */
        if ((pc->parent_type == CT_IF) ||
            (pc->parent_type == CT_ELSE) ||
            (pc->parent_type == CT_ELSEIF) ||
            (pc->parent_type == CT_DO) ||
            (pc->parent_type == CT_WHILE) ||
            (pc->parent_type == CT_SWITCH) ||
            (pc->parent_type == CT_FOR))
          {
          if (parent_token_indent != 0)
            frm.pse[frm.pse_tos].indent += parent_token_indent - indent_size;
          else
            {
            frm.pse[frm.pse_tos].indent += cpd.settings[UO_indent_brace].n;
            indent_column += cpd.settings[UO_indent_brace].n;
            }
          }
        else if (pc->parent_type == CT_CASE)
          {
            /* The indent_case_brace setting affects the parent CT_CASE */
          frm.pse[frm.pse_tos].indent_tmp += cpd.settings[UO_indent_case_brace].n;
          frm.pse[frm.pse_tos].indent     += cpd.settings[UO_indent_case_brace].n;
          }
        else if ((pc->parent_type == CT_CLASS) && !cpd.settings[UO_indent_class].b)
          frm.pse[frm.pse_tos].indent -= indent_size;
        else if ((pc->parent_type == CT_NAMESPACE) && !cpd.settings[UO_indent_namespace].b)
          frm.pse[frm.pse_tos].indent -= indent_size;
        }

      if ((pc->flags & PCF_DONT_INDENT) != 0)
        {
        frm.pse[frm.pse_tos].indent = pc->column;
        indent_column = pc->column;
        }
      else
        {
        /**
         * If there isn't a newline between the open brace and the next
         * item, just indent to wherever the next token is.
         * This covers this sort of stuff:
         * { a++;
         *   b--; };
         */
        next = chunk_get_next_ncnl(pc);

        if (!chunk_is_newline_between(pc, next))
          frm.pse[frm.pse_tos].indent = next->column;

        frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
        frm.pse[frm.pse_tos].open_line  = pc->orig_line;

          /* Update the indent_column if needed */
        if (cpd.settings[UO_indent_braces].n ||
            (parent_token_indent != 0))
          indent_column = frm.pse[frm.pse_tos].indent_tmp;
        }
      }
    else if (pc->type == CT_CASE)
      {
        /* Start a case - indent UO_indent_switch_case from the switch level */
      tmp = frm.pse[frm.pse_tos].indent + cpd.settings[UO_indent_switch_case].n;

      indent_pse_push(frm, pc);

      frm.pse[frm.pse_tos].indent     = tmp;
      frm.pse[frm.pse_tos].indent_tmp = tmp - indent_size;

        /* Always set on case statements */
      indent_column = frm.pse[frm.pse_tos].indent_tmp;
      }
    else if (pc->type == CT_LABEL)
      {
        /* Labels get sent to the left or backed up */
      if (cpd.settings[UO_indent_label].n > 0)
        indent_column = cpd.settings[UO_indent_label].n;
      else
        indent_column = frm.pse[frm.pse_tos].indent +
                        cpd.settings[UO_indent_label].n;
      }
    else if (pc->type == CT_CLASS_COLON)
      {
        /* just indent one level */
      indent_pse_push(frm, pc);
      frm.pse[frm.pse_tos].indent     = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size;
      frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;

      indent_column = frm.pse[frm.pse_tos].indent_tmp;

      if (cpd.settings[UO_indent_class_colon].b)
        {
        prev = chunk_get_prev(pc);

        if (chunk_is_newline(prev))
          frm.pse[frm.pse_tos].indent += 2;
          /* don't change indent of current line */
        }
      }
    else if ((pc->type == CT_PAREN_OPEN) ||
             (pc->type == CT_SPAREN_OPEN) ||
             (pc->type == CT_FPAREN_OPEN) ||
             (pc->type == CT_SQUARE_OPEN) ||
             (pc->type == CT_ANGLE_OPEN))
      {
        /* Open parens and squares - never update indent_column */
      indent_pse_push(frm, pc);
      frm.pse[frm.pse_tos].indent = pc->column + pc->len;

      if (cpd.settings[UO_indent_func_call_param].b &&
          (pc->type == CT_FPAREN_OPEN) &&
          (pc->parent_type == CT_FUNC_CALL))
        frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;

      if ((chunk_is_str(pc, "(", 1) && !cpd.settings[UO_indent_paren_nl].b) ||
          (chunk_is_str(pc, "[", 1) && !cpd.settings[UO_indent_square_nl].b))
        {
        next = chunk_get_next_nc(pc);

        if (chunk_is_newline(next))
          {
          int sub = 1;

          if (frm.pse[frm.pse_tos - 1].type == CT_ASSIGN)
            sub = 2;

          frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - sub].indent + indent_size;
          }
        }

      frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
      frm.paren_count++;
      }
    else if (pc->type == CT_ASSIGN)
      {
      /**
       * if there is a newline after the '=', just indent one level,
       * otherwise align on the '='.
       * Never update indent_column.
       */
      next = chunk_get_next(pc);

      if (next != NULL)
        {
        indent_pse_push(frm, pc);

        if (chunk_is_newline(next))
          frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size;
        else
          frm.pse[frm.pse_tos].indent = pc->column + pc->len + 1;

        frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
        }
      }
    else if (pc->type == CT_RETURN)
      {
        /* don't count returns inside a () or [] */
      if (pc->level == pc->brace_level)
        {
        indent_pse_push(frm, pc);
        frm.pse[frm.pse_tos].indent     = frm.pse[frm.pse_tos - 1].indent + pc->len + 1;
        frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos - 1].indent;
        }
      }
    else if (chunk_is_str(pc, "<<", 2))
      {
      if (cout_col == 0)
        {
        cout_col   = pc->column;
        cout_level = pc->level;
        }
      }
    else
      {
      /* anything else? */
      }

    /**
     * Indent the line if needed
     */
    if (did_newline && !chunk_is_newline(pc) && (pc->len != 0))
      {
      /**
       * Check for special continuations.
       * Note that some of these could be done as a stack item like
       * everything else
       */

      prev = chunk_get_prev_ncnl(pc);

      if ((pc->type == CT_MEMBER) ||
          (pc->type == CT_DC_MEMBER) ||
          ((prev != NULL) &&
           ((prev->type == CT_MEMBER) ||
            (prev->type == CT_DC_MEMBER))))
        {
        tmp = cpd.settings[UO_indent_member].n + indent_column;
        LOG_FMT(LINDENT, "%s: %d] member => %d\n",
                __func__, pc->orig_line, tmp);
        reindent_line(pc, tmp);
        }
      else if (chunk_is_str(pc, "<<", 2) && (cout_col > 0))
        {
        LOG_FMT(LINDENT, "%s: %d] cout_col => %d\n",
                __func__, pc->orig_line, cout_col);
        reindent_line(pc, cout_col);
        }
      else if ((vardefcol > 0) &&
               (pc->type == CT_WORD) &&
               ((pc->flags & PCF_VAR_DEF) != 0) &&
               (prev != NULL) && (prev->type == CT_COMMA))
        {
        LOG_FMT(LINDENT, "%s: %d] Vardefcol => %d\n",
                __func__, pc->orig_line, vardefcol);
        reindent_line(pc, vardefcol);
        }
      else if ((pc->type == CT_STRING) && (prev->type == CT_STRING) &&
               cpd.settings[UO_indent_align_string].b)
        {
        LOG_FMT(LINDENT, "%s: %d] String => %d\n",
                __func__, pc->orig_line, prev->column);
        reindent_line(pc, prev->column);
        }
      else if (chunk_is_comment(pc))
        {
        LOG_FMT(LINDENT, "%s: %d] comment => %d\n",
                __func__, pc->orig_line, frm.pse[frm.pse_tos].indent_tmp);
        indent_comment(pc, frm.pse[frm.pse_tos].indent_tmp);
        }
      else if (pc->type == CT_PREPROC)
        {
          /* Preprocs are always in column 1. See indent_preproc() */
        if (pc->column != 1)
          reindent_line(pc, 1);
        }
      else
        {
        if (pc->column != indent_column)
          {
          LOG_FMT(LINDENT, "%s: %d] indent => %d [%.*s]\n",
                  __func__, pc->orig_line, indent_column, pc->len, pc->str);
          reindent_line(pc, indent_column);
          }
        }

      did_newline = false;
      }

    /**
     * Handle variable definition continuation indenting
     */
    if ((pc->type == CT_WORD) &&
        ((pc->flags & PCF_IN_FCN_DEF) == 0) &&
        ((pc->flags & PCF_VAR_1ST_DEF) == PCF_VAR_1ST_DEF))
      vardefcol = pc->column;

    if (chunk_is_semicolon(pc) ||
        ((pc->type == CT_BRACE_OPEN) && (pc->parent_type == CT_FUNCTION)))
      vardefcol = 0;

      /* if we hit a newline, reset indent_tmp */
    if (chunk_is_newline(pc) ||
        (pc->type == CT_COMMENT_MULTI) ||
        (pc->type == CT_COMMENT_CPP))
      {
      frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;

      /**
       * Handle the case of a multi-line #define w/o anything on the
       * first line (indent_tmp will be 1 or 0)
       */
      if ((pc->type == CT_NL_CONT) &&
          (frm.pse[frm.pse_tos].indent_tmp <= indent_size))
        frm.pse[frm.pse_tos].indent_tmp = indent_size + 1;

        /* Get ready to indent the next item */
      did_newline = true;
      }

    if (!chunk_is_comment(pc) && !chunk_is_newline(pc))
      prev = pc;

    pc = chunk_get_next(pc);
    }

    /* Throw out any stuff inside a preprocessor - no need to warn */
  while ((frm.pse_tos > 0) && frm.pse[frm.pse_tos].in_preproc)
    indent_pse_pop(frm, pc);

  for (idx = 1; idx <= frm.pse_tos; idx++)
    {
    LOG_FMT(LWARN, "%s:%d Unmatched %s\n",
            cpd.filename, frm.pse[idx].open_line,
            get_token_name(frm.pse[idx].type));
    cpd.error_count++;
    }
  }

/**
 * returns true if forward scan reveals only single newlines or comments
 * stops when hits code
 * false if next thing hit is a closing brace, also if 2 newlines in a row
 */


static bool single_line_comment_indent_rule_applies(chunk_t *start)
  {
  chunk_t *pc      = start;
  int nl_count = 0;

  if (!chunk_is_single_line_comment(pc))
    return false;

    /* scan forward, if only single newlines and comments before next line of code, we want to apply */
  while ((pc = chunk_get_next(pc)) != NULL)
    {
    if (chunk_is_newline(pc))
      {
      if (nl_count > 0 || pc->nl_count > 1)
        return false;

      nl_count++;
      }
    else
      {
      nl_count = 0;

      if (!chunk_is_single_line_comment(pc))
        {
          /* here we check for things to run into that we wouldn't want to indent the comment for */
          /* for example, non-single line comment, closing brace */
        if (chunk_is_comment(pc) || chunk_is_closing_brace(pc))
          return false;

        return true;
        }
      }
    }

  return false;
  }

/**
 * REVISIT: This needs to be re-checked, maybe cleaned up
 *
 * Indents comments in a (hopefully) smart manner.
 *
 * There are two type of comments that get indented:
 *  - stand alone (ie, no tokens on the line before the comment)
 *  - trailing comments (last token on the line apart from a linefeed)
 *    + note that a stand-alone comment is a special case of a trailing
 *
 * The stand alone comments will get indented in one of three ways:
 *  - column 1:
 *    + There is an empty line before the comment AND the indent level is 0
 *    + The comment was originally in column 1
 *
 *  - Same column as trailing comment on previous line (ie, aligned)
 *    + if originally within TBD (3) columns of the previous comment
 *
 *  - syntax indent level
 *    + doesn't fit in the previous categories
 *
 * Options modify this behavior:
 *  - keep original column (don't move the comment, if possible)
 *  - keep relative column (move out the same amount as first item on line)
 *  - fix trailing comment in column TBD
 *
 * @param pc   The comment, which is the first item on a line
 * @param col  The column if this is to be put at indent level
 */
static void indent_comment(chunk_t *pc, int col)
  {
  chunk_t *nl;
  chunk_t *prev;

  LOG_FMT(LCMTIND, "%s: line %d, col %d, level %d: ", __func__,
          pc->orig_line, pc->orig_col, pc->level);

    /* force column 1 comment to column 1 if not changing them */
  if ((pc->orig_col == 1) && !cpd.settings[UO_indent_col1_comment].b)
    {
    LOG_FMT(LCMTIND, "rule 1 - keep in col 1\n");
    pc->column = 1;
    return;
    }

  nl = chunk_get_prev(pc);

    /* outside of any expression or statement? */
  if (pc->level == 0)
    {
    if ((nl != NULL) && (nl->nl_count > 1))
      {
      LOG_FMT(LCMTIND, "rule 2 - level 0, nl before\n");
      pc->column = 1;
      return;
      }
    }

  prev = chunk_get_prev(nl);

  if (chunk_is_comment(prev) && (nl->nl_count == 1))
    {
    int coldiff = prev->orig_col - pc->orig_col;

    if ((coldiff <= 3) && (coldiff >= -3))
      {
      pc->column = prev->column;
      LOG_FMT(LCMTIND, "rule 3 - prev comment, coldiff = %d, now in %d\n",
              coldiff, pc->column);
      return;
      }
    }

    /* check if special single line comment rule applies */
  if (cpd.settings[UO_indent_sing_line_comments].n > 0 && single_line_comment_indent_rule_applies(pc))
    {
    pc->column = col + cpd.settings[UO_indent_sing_line_comments].n;
    LOG_FMT(LCMTIND, "rule 4 - single line comment indent, now in %d\n", pc->column);
    return;
    }

  LOG_FMT(LCMTIND, "rule 5 - fall-through, stay in %d\n", col);

  pc->column = col;
  }

/**
 * Put spaces on either side of the preproc (#) symbol.
 * This is done by pointing pc->str into pp_str and adjusting the
 * length.
 */
void indent_preproc(void)
  {
  chunk_t *pc;
  chunk_t *next;
  int pp_level;
  int pp_level_sub = 0;
  int tmp;

    /* Define a string of 16 spaces + # + 16 spaces */
  static const char *pp_str  = "                #                ";
  static const char *alt_str = "                %:                ";

    /* Scan to see if the whole file is covered by one #ifdef */
  int stage = 0;

  for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc))
    {
    if (chunk_is_comment(pc) || chunk_is_newline(pc))
      continue;

    if (stage == 0)
      {
        /* Check the first PP, make sure it is an #if type */
      if (pc->type != CT_PREPROC)
        break;

      next = chunk_get_next(pc);

      if ((next == NULL) || (next->type != CT_PP_IF))
        break;

      stage = 1;
      }
    else if (stage == 1)
      {
        /* Scan until a PP at level 0 is found - the close to the #if */
      if ((pc->type == CT_PREPROC) &&
          (pc->pp_level == 0))
        stage = 2;

      continue;
      }
    else if (stage == 2)
      {
        /* We should only see the rest of the preprocessor */
      if ((pc->type == CT_PREPROC) ||
          ((pc->flags & PCF_IN_PREPROC) == 0))
        {
        stage = 0;
        break;
        }
      }
    }

  if (stage == 2)
    {
    LOG_FMT(LINFO, "The whole file is covered by a #IF\n");
    pp_level_sub = 1;
    }

  for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc))
    {
    if (pc->type != CT_PREPROC)
      continue;

    if (pc->column != 1)
      {
        /* Don't handle preprocessors that aren't in column 1 */
      LOG_FMT(LINFO, "%s: Line %d doesn't start in column 1 (%d)\n",
              __func__, pc->orig_line, pc->column);
      continue;
      }

      /* point into pp_str */
    if (pc->len == 2)
        /* alternate token crap */
      pc->str = &alt_str[16];
    else
      pc->str = &pp_str[16];

    pp_level = pc->pp_level - pp_level_sub;

    if (pp_level < 0)
      pp_level = 0;
    else if (pp_level > 16)
      pp_level = 16;

      /* Note that the indent is removed by default */
    if ((cpd.settings[UO_pp_indent].a & AV_ADD) != 0)
      {
        /* Need to add some spaces */
      pc->str -= pp_level;
      pc->len += pp_level;
      }
    else if (cpd.settings[UO_pp_indent].a == AV_IGNORE)
      {
      tmp      = (pc->orig_col <= 16) ? pc->orig_col - 1 : 16;
      pc->str -= tmp;
      pc->len += tmp;
      }

      /* Add spacing by adjusting the length */
    if ((cpd.settings[UO_pp_space].a & AV_ADD) != 0)
      pc->len += pp_level;

    next = chunk_get_next(pc);

    if (next != NULL)
      reindent_line(next, pc->len + 1);

    LOG_FMT(LPPIS, "%s: Indent line %d to %d (len %d, next->col %d)\n",
            __func__, pc->orig_line, pp_level, pc->len, next->column);
    }
  }

