/**
 * @file indent.cpp
 * Does all the indenting stuff.
 *
 * @author  Ben Gardner
 * @license GPL v2+
 */
#include "uncrustify_types.h"
#include "chunk_list.h"
#include "prototypes.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include "unc_ctype.h"


/**
 * 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);
static bool ifdef_over_whole_file();


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


enum align_mode
{
   ALMODE_SHIFT,     /* shift relative to the current column */
   ALMODE_KEEP_ABS,  /* try to keep the original absolute column */
   ALMODE_KEEP_REL,  /* try to keep the original gap */
};

/* Same as indent_to_column, except we can move both ways */
void align_to_column(chunk_t *pc, int column)
{
   LOG_FUNC_ENTRY();
   if (column == pc->column)
   {
      return;
   }

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

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

   pc->column = column;
   do
   {
      chunk_t    *next = chunk_get_next(pc);
      chunk_t    *prev;
      align_mode almod = ALMODE_SHIFT;

      if (next == NULL)
      {
         break;
      }
      min_delta = space_col_align(pc, next);
      min_col  += min_delta;
      prev      = pc;
      pc        = next;

      if (chunk_is_comment(pc) && (pc->parent_type != CT_COMMENT_EMBED))
      {
         almod = (chunk_is_single_line_comment(pc) &&
                  cpd.settings[UO_indent_relative_single_line_comments].b) ?
                 ALMODE_KEEP_REL : ALMODE_KEEP_ABS;
      }

      if (almod == ALMODE_KEEP_ABS)
      {
         /* Keep same absolute column */
         pc->column = pc->orig_col;
         if (pc->column < min_col)
         {
            pc->column = min_col;
         }
      }
      else if (almod == ALMODE_KEEP_REL)
      {
         /* Keep same relative column */
         int orig_delta = pc->orig_col - prev->orig_col;
         if (orig_delta < min_delta)
         {
            orig_delta = min_delta;
         }
         pc->column = prev->column + orig_delta;
      }
      else /* ALMODE_SHIFT */
      {
         /* Shift by the same amount */
         pc->column += col_delta;
         if (pc->column < min_col)
         {
            pc->column = min_col;
         }
      }
      LOG_FMT(LINDLINED, "   %s set column of %s on line %d to col %d (orig %d)\n",
              (almod == ALMODE_KEEP_ABS) ? "abs" :
              (almod == ALMODE_KEEP_REL) ? "rel" : "sft",
              get_token_name(pc->type), pc->orig_line, pc->column, pc->orig_col);
   } while ((pc != NULL) && (pc->nl_count == 0));
}


/**
 * 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)
{
   LOG_FUNC_ENTRY();
   LOG_FMT(LINDLINE, "%s: %d] col %d on '%s' [%s/%s] => %d",
           __func__, pc->orig_line, pc->column, pc->str.c_str(),
           get_token_name(pc->type), get_token_name(pc->parent_type),
           column);
   log_func_stack_inline(LINDLINE);

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

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

   pc->column = column;
   do
   {
      chunk_t *next = chunk_get_next(pc);

      if (next == NULL)
      {
         break;
      }
      if (pc->nl_count)
      {
         min_col   = 0;
         col_delta = 0;
      }
      min_col += space_col_align(pc, next);
      pc       = next;

      bool is_comment = chunk_is_comment(pc);
      bool keep       = is_comment && chunk_is_single_line_comment(pc) &&
                        cpd.settings[UO_indent_relative_single_line_comments].b;

      if (is_comment && (pc->parent_type != CT_COMMENT_EMBED) && !keep)
      {
         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;
         }
         LOG_FMT(LINDLINED, "   set column of '%s' to %d (orig %d)\n",
                 pc->str.c_str(), pc->column, pc->orig_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)
{
   LOG_FUNC_ENTRY();
   static int ref = 0;

   /* check the stack depth */
   if (frm.pse_tos < ((int)ARRAY_SIZE(frm.pse) - 1))
   {
      /* 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] (pp=%d) OPEN  [%d,%s] level=%d\n",
              pc->orig_line, cpd.pp_level, frm.pse_tos, get_token_name(pc->type), pc->level);

      frm.pse[frm.pse_tos].pc          = pc;
      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;
      frm.pse[frm.pse_tos].indent_tab  = frm.pse[frm.pse_tos - 1].indent_tab;
      frm.pse[frm.pse_tos].indent_cont = frm.pse[frm.pse_tos - 1].indent_cont;
      frm.pse[frm.pse_tos].non_vardef  = false;
      frm.pse[frm.pse_tos].ns_cnt      = frm.pse[frm.pse_tos - 1].ns_cnt;
      memcpy(&frm.pse[frm.pse_tos].ip, &frm.pse[frm.pse_tos - 1].ip, sizeof(frm.pse[frm.pse_tos].ip));
   }
}


/**
 * 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)
{
   LOG_FUNC_ENTRY();
   /* Bump up the index and initialize it */
   if (frm.pse_tos > 0)
   {
      if (pc != NULL)
      {
         LOG_FMT(LINDPSE, "%4d] (pp=%d) CLOSE [%d,%s] on %s, started on line %d, level=%d/%d\n",
                 pc->orig_line, cpd.pp_level, 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);
      }

      /* Don't clear the stack entry because some code 'cheats' and uses the
       * just-popped indent values
       */
      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:
   case CT_USING_STMT:
      return(6);

   case CT_SWITCH:
      return(7);

   case CT_ELSEIF:
      return(8);

   default:
      return(0);
   }
}


#define indent_column_set(X)                              \
   do {                                                   \
      indent_column = (X);                                \
      LOG_FMT(LINDENT2, "[line %d] indent_column = %d\n", \
              __LINE__, indent_column);                   \
   } while (0)


static int calc_indent_continue(struct parse_frame& frm, int pse_tos)
{
   int ic = cpd.settings[UO_indent_continue].n;

   if ((ic < 0) && frm.pse[pse_tos].indent_cont)
   {
      return frm.pse[pse_tos].indent;
   }
   return frm.pse[pse_tos].indent + abs(ic);
}


/**
 * We are on a '{' that has parent = OC_BLOCK_EXPR
 * find the column of the param tag
 */
static chunk_t *oc_msg_block_indent(chunk_t *pc, bool from_brace,
                                    bool from_caret, bool from_colon,
                                    bool from_keyword)
{
   LOG_FUNC_ENTRY();
   chunk_t *tmp = chunk_get_prev_nc(pc);

   if (from_brace)
   {
      return pc;
   }

   if (chunk_is_paren_close(tmp))
   {
      tmp = chunk_get_prev_nc(chunk_skip_to_match_rev(tmp));
   }
   if (!tmp || (tmp->type != CT_OC_BLOCK_CARET))
   {
      return NULL;
   }
   if (from_caret)
   {
      return tmp;
   }
   tmp = chunk_get_prev_nc(tmp);
   if (!tmp || (tmp->type != CT_OC_COLON))
   {
      return NULL;
   }
   if (from_colon)
   {
      return tmp;
   }
   tmp = chunk_get_prev_nc(tmp);
   if (!tmp || ((tmp->type != CT_OC_MSG_NAME) && (tmp->type != CT_OC_MSG_FUNC)))
   {
      return NULL;
   }
   if (from_keyword)
   {
      return tmp;
   }
   return NULL;
}


/**
 * We are on a '{' that has parent = OC_BLOCK_EXPR
 */
static chunk_t *oc_msg_prev_colon(chunk_t *pc)
{
   return chunk_get_prev_type(pc, CT_OC_COLON, pc->level, CNAV_ALL);
}


/**
 * 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)
{
   LOG_FUNC_ENTRY();
   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;
   int                indent_column;
   int                parent_token_indent = 0;
   int                xml_indent          = 0;
   bool               token_used;
   int                sql_col      = 0;
   int                sql_orig_col = 0;
   bool               in_func_def = false;
   c_token_t          memtype;

   memset(&frm, 0, sizeof(frm));
   cpd.frame_count = 0;

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

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

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

      /* Handle "force indentation of function definition to start in column 1" */
      if (cpd.settings[UO_indent_func_def_force_col1].b)
      {
         if (!in_func_def)
         {
            next = chunk_get_next_ncnl(pc);
            if ((pc->parent_type == CT_FUNC_DEF) ||
                ((pc->type == CT_COMMENT) &&
                 (next != NULL) &&
                 (next->parent_type == CT_FUNC_DEF)))
            {
               in_func_def = true;
               indent_pse_push(frm, pc);
               frm.pse[frm.pse_tos].indent_tmp = 1;
               frm.pse[frm.pse_tos].indent     = 1;
               frm.pse[frm.pse_tos].indent_tab = 1;
            }
         }
         else
         {
            prev = chunk_get_prev(pc);
            if ((prev->type == CT_BRACE_CLOSE) &&
                (prev->parent_type == CT_FUNC_DEF))
            {
               in_func_def = false;
               indent_pse_pop(frm, pc);
            }
         }
      }

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

            /* If we just removed an #endregion, then check to see if a
             * PP_REGION_INDENT entry is right below it
             */
            if ((type == CT_PP_ENDREGION) &&
                (frm.pse[frm.pse_tos].type == CT_PP_REGION_INDENT))
            {
               indent_pse_pop(frm, pc);
            }
         }
      }
      else if (pc->type == CT_PREPROC)
      {
         /* Close out PP_IF_INDENT before playing with the parse frames */
         if ((frm.pse[frm.pse_tos].type == CT_PP_IF_INDENT) &&
             ((pc->parent_type == CT_PP_ENDIF) ||
              (pc->parent_type == CT_PP_ELSE)))
         {
            indent_pse_pop(frm, pc);
         }

         pf_check(&frm, pc);

         /* Indent the body of a #region here */
         if (cpd.settings[UO_pp_region_indent_code].b &&
             (pc->parent_type == CT_PP_REGION))
         {
            next = chunk_get_next(pc);
            /* Hack to get the logs to look right */
            set_chunk_type(next, CT_PP_REGION_INDENT);
            indent_pse_push(frm, next);
            set_chunk_type(next, CT_PP_REGION);

            /* Indent one level */
            frm.pse[frm.pse_tos].indent     = frm.pse[frm.pse_tos - 1].indent + indent_size;
            frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos - 1].indent_tab + indent_size;
            frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
            frm.pse[frm.pse_tos].in_preproc = false;
         }

         /* Indent the body of a #if here */
         if (cpd.settings[UO_pp_if_indent_code].b &&
             ((pc->parent_type == CT_PP_IF) ||
              (pc->parent_type == CT_PP_ELSE)))
         {
            next = chunk_get_next(pc);
            /* Hack to get the logs to look right */
            memtype = next->type;
            set_chunk_type(next, CT_PP_IF_INDENT);
            indent_pse_push(frm, next);
            set_chunk_type(next, memtype);

            /* Indent one level except if the #if is a #include guard */
            int extra = ((pc->pp_level == 0) && ifdef_over_whole_file()) ? 0 : indent_size;
            frm.pse[frm.pse_tos].indent     = frm.pse[frm.pse_tos - 1].indent + extra;
            frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos - 1].indent_tab + extra;
            frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
            frm.pse[frm.pse_tos].in_preproc = false;
         }

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

         if (pc->parent_type == CT_PP_DEFINE)
         {
            frm.pse[frm.pse_tos].indent_tmp = cpd.settings[UO_pp_define_at_level].b ?
                                              frm.pse[frm.pse_tos - 1].indent_tmp : 1;
            frm.pse[frm.pse_tos].indent     = frm.pse[frm.pse_tos].indent_tmp + indent_size;
            frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
         }
         else
         {
            if ((frm.pse[frm.pse_tos - 1].type == CT_PP_REGION_INDENT) ||
                ((frm.pse[frm.pse_tos - 1].type == CT_PP_IF_INDENT) &&
                 (frm.pse[frm.pse_tos].type != CT_PP_ENDIF)))
            {
               frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 2].indent;
            }
            else
            {
               frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent;
            }
            if ((pc->parent_type == CT_PP_REGION) ||
                (pc->parent_type == CT_PP_ENDREGION))
            {
               int val = cpd.settings[UO_pp_indent_region].n;
               if (val > 0)
               {
                  frm.pse[frm.pse_tos].indent = val;
               }
               else
               {
                  frm.pse[frm.pse_tos].indent += val;
               }
            }
            else if ((pc->parent_type == CT_PP_IF) ||
                     (pc->parent_type == CT_PP_ELSE) ||
                     (pc->parent_type == CT_PP_ENDIF))
            {
               int val = cpd.settings[UO_pp_indent_if].n;
               if (val > 0)
               {
                  frm.pse[frm.pse_tos].indent = val;
               }
               else
               {
                  frm.pse[frm.pse_tos].indent += val;
               }
            }
            frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
         }
      }

      /* Check for close XML tags "</..." */
      if (cpd.settings[UO_indent_xml_string].n > 0)
      {
         if (pc->type == CT_STRING)
         {
            if ((pc->len() > 4) &&
                (xml_indent > 0) &&
                (pc->str[1] == '<') &&
                (pc->str[2] == '/'))
            {
               xml_indent -= cpd.settings[UO_indent_xml_string].n;
            }
         }
         else
         {
            if (!chunk_is_comment(pc) && !chunk_is_newline(pc))
            {
               xml_indent = 0;
            }
         }
      }

      /**
       * Handle non-brace closures
       */

      token_used = false;
      int old_pse_tos;
      do
      {
         old_pse_tos = frm.pse_tos;

         /* End anything that drops a level */
         if (!chunk_is_newline(pc) &&
             !chunk_is_comment(pc) &&
             (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);
               if (!pc)
               {
                  /* need to break out of both the do and while loops */
                  goto null_pc;
               }
            }

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

            /* End any assign operations with a semicolon on the same level */
            if (chunk_is_semicolon(pc) &&
                ((frm.pse[frm.pse_tos].type == CT_IMPORT) ||
                 (frm.pse[frm.pse_tos].type == CT_USING)))
            {
               indent_pse_pop(frm, pc);
            }

            /* End any custom macro-based open/closes */
            if (!token_used &&
                (frm.pse[frm.pse_tos].type == CT_MACRO_OPEN) &&
                (pc->type == CT_MACRO_CLOSE))
            {
               token_used = true;
               indent_pse_pop(frm, pc);
            }

            /* End any CPP/ObjC class colon stuff */
            if (((frm.pse[frm.pse_tos].type == CT_CLASS_COLON) ||
                 (frm.pse[frm.pse_tos].type == CT_CONSTR_COLON)) &&
                ((pc->type == CT_BRACE_OPEN) ||
                 (pc->type == CT_OC_END) ||
                 (pc->type == CT_OC_SCOPE) ||
                 (pc->type == CT_OC_PROPERTY) ||
                 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 class scope is ended with another class scope or a close brace */
            if (cpd.settings[UO_indent_access_spec_body].b &&
                (frm.pse[frm.pse_tos].type == CT_PRIVATE) &&
                ((pc->type == CT_BRACE_CLOSE) ||
                 (pc->type == CT_PRIVATE)))
            {
               indent_pse_pop(frm, pc);
            }

            /* return & throw are ended with a semicolon */
            if (chunk_is_semicolon(pc) &&
                ((frm.pse[frm.pse_tos].type == CT_RETURN) ||
                 (frm.pse[frm.pse_tos].type == CT_THROW)))
            {
               indent_pse_pop(frm, pc);
            }

            /* an OC SCOPE ('-' or '+') ends with a semicolon or brace open */
            if ((frm.pse[frm.pse_tos].type == CT_OC_SCOPE) &&
                (chunk_is_semicolon(pc) ||
                 (pc->type == CT_BRACE_OPEN)))
            {
               indent_pse_pop(frm, pc);
            }

            /* a typedef and an OC SCOPE ('-' or '+') ends with a semicolon or
             * brace open */
            if ((frm.pse[frm.pse_tos].type == CT_TYPEDEF) &&
                (chunk_is_semicolon(pc) ||
                 chunk_is_paren_open(pc) ||
                 (pc->type == CT_BRACE_OPEN)))
            {
               indent_pse_pop(frm, pc);
            }

            /* an SQL EXEC is ended with a semicolon */
            if ((frm.pse[frm.pse_tos].type == CT_SQL_EXEC) &&
                chunk_is_semicolon(pc))
            {
               indent_pse_pop(frm, pc);
            }

            /* an CLASS is ended with a semicolon or brace open */
            if ((frm.pse[frm.pse_tos].type == CT_CLASS) &&
                ((pc->type == CT_CLASS_COLON) ||
                 (pc->type == CT_BRACE_OPEN) ||
                 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_set(frm.pse[frm.pse_tos].indent_tmp);

      if (!chunk_is_newline(pc) && !chunk_is_comment(pc) && log_sev_on(LINDPC))
      {
         LOG_FMT(LINDPC, " -=[ %d:%d %s ]=-\n",
                 pc->orig_line, pc->orig_col, pc->str.c_str());
         for (int ttidx = frm.pse_tos; ttidx > 0; ttidx--)
         {
            LOG_FMT(LINDPC, "     [%d %d:%d %s/%s tmp=%d ind=%d bri=%d tab=%d cont=%d lvl=%d blvl=%d]\n",
                    ttidx,
                    frm.pse[ttidx].pc->orig_line,
                    frm.pse[ttidx].pc->orig_col,
                    get_token_name(frm.pse[ttidx].type),
                    get_token_name(frm.pse[ttidx].pc->parent_type),
                    frm.pse[ttidx].indent_tmp,
                    frm.pse[ttidx].indent,
                    frm.pse[ttidx].brace_indent,
                    frm.pse[ttidx].indent_tab,
                    frm.pse[ttidx].indent_cont,
                    frm.pse[ttidx].level,
                    frm.pse[ttidx].pc->brace_level);
         }
      }

      /**
       * 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
       */

      bool brace_indent = false;
      if ((pc->type == CT_BRACE_CLOSE) || (pc->type == CT_BRACE_OPEN))
      {
         brace_indent = (cpd.settings[UO_indent_braces].b &&
                         (!cpd.settings[UO_indent_braces_no_func].b ||
                          (pc->parent_type != CT_FUNC_DEF)) &&
                         (!cpd.settings[UO_indent_braces_no_func].b ||
                          (pc->parent_type != CT_FUNC_CLASS_DEF)) &&
                         (!cpd.settings[UO_indent_braces_no_class].b ||
                          (pc->parent_type != CT_CLASS)) &&
                         (!cpd.settings[UO_indent_braces_no_struct].b ||
                          (pc->parent_type != CT_STRUCT)));
      }

      if (pc->type == CT_BRACE_CLOSE)
      {
         if (frm.pse[frm.pse_tos].type == CT_BRACE_OPEN)
         {
            /* Indent the brace to match the open brace */
            indent_column_set(frm.pse[frm.pse_tos].brace_indent);

            if (frm.pse[frm.pse_tos].ip.ref)
            {
               pc->indent.ref   = frm.pse[frm.pse_tos].ip.ref;
               pc->indent.delta = 0;
            }

            indent_pse_pop(frm, pc);
            frm.level--;
         }
      }
      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;
         frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;

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

         /* any '{' that is inside of a '(' overrides the '(' indent */
         if (!cpd.settings[UO_indent_paren_open_brace].b &&
             chunk_is_paren_open(frm.pse[frm.pse_tos - 1].pc) &&
             chunk_is_newline(chunk_get_next_nc(pc)))
         {
            /* FIXME: I don't know how much of this is necessary, but it seems to work */
            frm.pse[frm.pse_tos].brace_indent = 1 + (pc->brace_level * indent_size);
            indent_column = frm.pse[frm.pse_tos].brace_indent;
            frm.pse[frm.pse_tos].indent       = indent_column + indent_size;
            frm.pse[frm.pse_tos].indent_tab   = frm.pse[frm.pse_tos].indent;
            frm.pse[frm.pse_tos].indent_tmp   = frm.pse[frm.pse_tos].indent;

            frm.pse[frm.pse_tos - 1].indent_tmp = frm.pse[frm.pse_tos].indent_tmp;
         }
         else if (frm.paren_count != 0)
         {
            if (frm.pse[frm.pse_tos].pc->parent_type == CT_OC_BLOCK_EXPR)
            {
               if ((pc->flags & PCF_IN_OC_MSG) &&
                   cpd.settings[UO_indent_oc_block_msg].n)
               {
                  frm.pse[frm.pse_tos].ip.ref   = oc_msg_block_indent(pc, false, false, false, true);
                  frm.pse[frm.pse_tos].ip.delta = cpd.settings[UO_indent_oc_block_msg].n;
               }

               if (cpd.settings[UO_indent_oc_block].b ||
                   cpd.settings[UO_indent_oc_block_msg_xcode_style].b)
               {
                  bool in_oc_msg = (pc->flags & PCF_IN_OC_MSG);
                  bool indent_from_keyword = cpd.settings[UO_indent_oc_block_msg_from_keyword].b && in_oc_msg;
                  bool indent_from_colon = cpd.settings[UO_indent_oc_block_msg_from_colon].b && in_oc_msg;
                  bool indent_from_caret = cpd.settings[UO_indent_oc_block_msg_from_caret].b && in_oc_msg;
                  bool indent_from_brace = cpd.settings[UO_indent_oc_block_msg_from_brace].b && in_oc_msg;

                  // In "Xcode indent mode", we want to indent:
                  //  - if the colon is aligned (namely, if a newline has been
                  //    added before it), indent_from_brace
                  //  - otherwise, indent from previous block (the "else" statement here)
                  if (cpd.settings[UO_indent_oc_block_msg_xcode_style].b)
                  {
                     chunk_t *colon = oc_msg_prev_colon(pc);
                     chunk_t *param_name = chunk_get_prev(colon);
                     chunk_t *before_param = chunk_get_prev(param_name);

                     if (before_param && (before_param->type == CT_NEWLINE))
                     {
                        indent_from_keyword = true;
                        indent_from_colon   = false;
                        indent_from_caret   = false;
                        indent_from_brace   = false;
                     }
                     else
                     {
                        indent_from_brace   = false;
                        indent_from_colon   = false;
                        indent_from_caret   = false;
                        indent_from_keyword = false;
                     }
                  }

                  chunk_t *ref = oc_msg_block_indent(pc, indent_from_brace,
                                                     indent_from_caret,
                                                     indent_from_colon,
                                                     indent_from_keyword);
                  if (ref)
                  {
                     frm.pse[frm.pse_tos].indent = indent_size + ref->column;
                     indent_column_set(frm.pse[frm.pse_tos].indent - indent_size);
                  }
                  else
                  {
                     frm.pse[frm.pse_tos].indent = 1 + ((pc->brace_level + 1) * indent_size);
                     indent_column_set(frm.pse[frm.pse_tos].indent - indent_size);
                  }
               }
               else
               {
                  frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size;
               }
            }
            else
            {
               /* 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_TRY) ||
                (pc->parent_type == CT_CATCH) ||
                (pc->parent_type == CT_DO) ||
                (pc->parent_type == CT_WHILE) ||
                (pc->parent_type == CT_USING_STMT) ||
                (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_set(indent_column + cpd.settings[UO_indent_brace].n);
               }
            }
            else if (pc->parent_type == CT_CASE)
            {
               /* An open brace with the parent of case does not indent by default
                * UO_indent_case_brace can be used to indent the brace.
                * So we need to take the CASE indent, subtract off the
                * indent_size that was added above and then add indent_case_brace.
                */
               indent_column_set(frm.pse[frm.pse_tos - 1].indent - indent_size +
                                 cpd.settings[UO_indent_case_brace].n);

               /* Stuff inside the brace still needs to be indented */
               frm.pse[frm.pse_tos].indent     = indent_column + indent_size;
               frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
            }
            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)
            {
               if (cpd.settings[UO_indent_namespace].b &&
                   cpd.settings[UO_indent_namespace_single_indent].b)
               {
                  if (frm.pse[frm.pse_tos].ns_cnt)
                  {
                     /* undo indent on all except the first namespace */
                     frm.pse[frm.pse_tos].indent -= indent_size;
                  }
                  indent_column_set((frm.pse_tos <= 1) ? 1 : frm.pse[frm.pse_tos - 1].brace_indent);
               }
               else if ((pc->flags & PCF_LONG_BLOCK) ||
                        !cpd.settings[UO_indent_namespace].b)
               {
                  /* don't indent long blocks */
                  frm.pse[frm.pse_tos].indent -= indent_size;
               }
               else /* indenting 'short' namespace */
               {
                  if (cpd.settings[UO_indent_namespace_level].n > 0)
                  {
                     frm.pse[frm.pse_tos].indent -= indent_size;
                     frm.pse[frm.pse_tos].indent +=
                        cpd.settings[UO_indent_namespace_level].n;
                  }
               }
               frm.pse[frm.pse_tos].ns_cnt++;
            }
            else if ((pc->parent_type == CT_EXTERN) && !cpd.settings[UO_indent_extern].b)
            {
               frm.pse[frm.pse_tos].indent -= indent_size;
            }

            frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
         }

         if ((pc->flags & PCF_DONT_INDENT) != 0)
         {
            frm.pse[frm.pse_tos].indent = pc->column;
            indent_column_set(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 (brace_indent || (parent_token_indent != 0))
            {
               indent_column_set(frm.pse[frm.pse_tos].indent_tmp);
            }
         }

         /* Save the brace indent */
         frm.pse[frm.pse_tos].brace_indent = indent_column;
      }
      else if (pc->type == CT_SQL_END)
      {
         if (frm.pse[frm.pse_tos].type == CT_SQL_BEGIN)
         {
            indent_pse_pop(frm, pc);
            frm.level--;
            indent_column_set(frm.pse[frm.pse_tos].indent_tmp);
         }
      }
      else if (pc->type == CT_SQL_BEGIN)
      {
         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;
         frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
      }
      else if (pc->type == CT_SQL_EXEC)
      {
         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;
      }
      else if (pc->type == CT_MACRO_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;
         frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
      }
      else if (pc->type == CT_MACRO_ELSE)
      {
         if (frm.pse[frm.pse_tos].type == CT_MACRO_OPEN)
         {
            indent_column_set(frm.pse[frm.pse_tos - 1].indent);
         }
      }
      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 + cpd.settings[UO_indent_case_shift].n;
         frm.pse[frm.pse_tos].indent_tab = tmp;

         /* Always set on case statements */
         indent_column_set(frm.pse[frm.pse_tos].indent_tmp);

         /* comments before 'case' need to be aligned with the 'case' */
         chunk_t *pct = pc;
         while (((pct = chunk_get_prev_nnl(pct)) != NULL) &&
                chunk_is_comment(pct))
         {
            chunk_t *t2 = chunk_get_prev(pct);
            if (chunk_is_newline(t2))
            {
               pct->column        = frm.pse[frm.pse_tos].indent_tmp;
               pct->column_indent = pct->column;
            }
         }
      }
      else if (pc->type == CT_BREAK)
      {
         prev = chunk_get_prev_ncnl(pc);
         if ((prev != NULL) &&
             (prev->type == CT_BRACE_CLOSE) &&
             (prev->parent_type == CT_CASE))
         {
            /* This only affects the 'break', so no need for a stack entry */
            indent_column_set(prev->column);
         }
      }
      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_set(cpd.settings[UO_indent_label].n);
         }
         else
         {
            indent_column_set(frm.pse[frm.pse_tos].indent +
                              cpd.settings[UO_indent_label].n);
         }
      }
      else if (pc->type == CT_PRIVATE)
      {
         if (cpd.settings[UO_indent_access_spec_body].b)
         {
            tmp = frm.pse[frm.pse_tos].indent + indent_size;

            indent_pse_push(frm, pc);

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

            /* If we are indenting the body, then we must leave the access spec
             * indented at brace level
             */
            indent_column_set(frm.pse[frm.pse_tos].indent_tmp);
         }
         else
         {
            /* Access spec labels get sent to the left or backed up */
            if (cpd.settings[UO_indent_access_spec].n > 0)
            {
               indent_column_set(cpd.settings[UO_indent_access_spec].n);
            }
            else
            {
               indent_column_set(frm.pse[frm.pse_tos].indent +
                                 cpd.settings[UO_indent_access_spec].n);
            }
         }
      }
      else if (pc->type == CT_CLASS)
      {
         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;
         frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
      }
      else if ((pc->type == CT_CLASS_COLON) ||
               (pc->type == CT_CONSTR_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;
         frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;

         indent_column_set(frm.pse[frm.pse_tos].indent_tmp);

         if ((cpd.settings[UO_indent_class_colon].b && (pc->type == CT_CLASS_COLON)) ||
             (cpd.settings[UO_indent_constr_colon].b && (pc->type == CT_CONSTR_COLON)))
         {
            prev = chunk_get_prev(pc);
            if (chunk_is_newline(prev))
            {
               frm.pse[frm.pse_tos].indent += cpd.settings[UO_indent_ctor_init_leading].n;

               if (cpd.settings[UO_indent_ctor_init].n > 0)
               {
                  frm.pse[frm.pse_tos].indent     += cpd.settings[UO_indent_ctor_init].n;
                  frm.pse[frm.pse_tos].indent_tmp += cpd.settings[UO_indent_ctor_init].n;
                  frm.pse[frm.pse_tos].indent_tab += cpd.settings[UO_indent_ctor_init].n;
                  indent_column_set(frm.pse[frm.pse_tos].indent_tmp);
               }
            }
            else
            {
               if (cpd.settings[UO_indent_class_on_colon].b && (pc->type == CT_CLASS_COLON))
               {
                  frm.pse[frm.pse_tos].indent = pc->column;
               }
               else
               {
                  next = chunk_get_next(pc);
                  if ((next != NULL) && !chunk_is_newline(next))
                  {
                     frm.pse[frm.pse_tos].indent = next->column;
                  }
               }
            }
         }
      }
      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, unless right
          * after a newline.
          */
         bool skipped = false;

         indent_pse_push(frm, pc);
         if (chunk_is_newline(chunk_get_prev(pc)) &&
             (pc->column != indent_column))
         {
            LOG_FMT(LINDENT, "%s: %d] indent => %d [%s]\n",
                    __func__, pc->orig_line, indent_column, pc->str.c_str());
            reindent_line(pc, indent_column);
         }
         frm.pse[frm.pse_tos].indent = pc->column + pc->len();

         if ((pc->type == CT_SQUARE_OPEN) && (cpd.lang_flags & LANG_D))
         {
            frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
         }

         if (((pc->type == CT_FPAREN_OPEN) || (pc->type == CT_ANGLE_OPEN)) &&
             ((cpd.settings[UO_indent_func_call_param].b &&
               ((pc->parent_type == CT_FUNC_CALL) ||
                (pc->parent_type == CT_FUNC_CALL_USER)))
              ||
              (cpd.settings[UO_indent_func_proto_param].b &&
               ((pc->parent_type == CT_FUNC_PROTO) ||
                (pc->parent_type == CT_FUNC_CLASS_PROTO)))
              ||
              (cpd.settings[UO_indent_func_class_param].b &&
               ((pc->parent_type == CT_FUNC_CLASS_DEF) ||
                (pc->parent_type == CT_FUNC_CLASS_PROTO)))
              ||
              (cpd.settings[UO_indent_template_param].b &&
               (pc->parent_type == CT_TEMPLATE))
              ||
              (cpd.settings[UO_indent_func_ctor_var_param].b &&
               (pc->parent_type == CT_FUNC_CTOR_VAR))
              ||
              (cpd.settings[UO_indent_func_def_param].b &&
               (pc->parent_type == CT_FUNC_DEF))))
         {
            /* Skip any continuation indents */
            idx = frm.pse_tos - 1;
            while ((idx > 0) &&
                   (frm.pse[idx].type != CT_BRACE_OPEN) &&
                   (frm.pse[idx].type != CT_VBRACE_OPEN) &&
                   (frm.pse[idx].type != CT_PAREN_OPEN) &&
                   (frm.pse[idx].type != CT_FPAREN_OPEN) &&
                   (frm.pse[idx].type != CT_SPAREN_OPEN) &&
                   (frm.pse[idx].type != CT_SQUARE_OPEN) &&
                   (frm.pse[idx].type != CT_ANGLE_OPEN) &&
                   (frm.pse[idx].type != CT_CLASS_COLON) &&
                   (frm.pse[idx].type != CT_CONSTR_COLON) &&
                   (frm.pse[idx].type != CT_ASSIGN_NL))
            {
               idx--;
               skipped = true;
            }
            frm.pse[frm.pse_tos].indent = frm.pse[idx].indent + indent_size;
            if (cpd.settings[UO_indent_func_param_double].b)
            {
               frm.pse[frm.pse_tos].indent += indent_size;
            }
            frm.pse[frm.pse_tos].indent_tab = frm.pse[frm.pse_tos].indent;
         }

         else if ((chunk_is_str(pc, "(", 1) && !cpd.settings[UO_indent_paren_nl].b) ||
                  (chunk_is_str(pc, "<", 1) && !cpd.settings[UO_indent_paren_nl].b) || /* TODO: add indent_angle_nl? */
                  (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 ||
                   frm.pse[frm.pse_tos - 1].type == CT_RETURN)
               {
                  sub = 2;
               }
               frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - sub].indent + indent_size;
               skipped = true;
            }
            else
            {
               if (next && !chunk_is_comment(next))
               {
                  if (next->type == CT_SPACE)
                  {
                     next = chunk_get_next_nc(next);
                  }
                  frm.pse[frm.pse_tos].indent = next->column;
               }
            }
         }

         if ((pc->type == CT_FPAREN_OPEN) &&
             chunk_is_newline(chunk_get_prev(pc)) &&
             !chunk_is_newline(chunk_get_next(pc)))
         {
            frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;
            indent_column_set(frm.pse[frm.pse_tos].indent);
         }
         if ((cpd.settings[UO_indent_continue].n != 0) && (!skipped))
         {
            frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent;
            if ((pc->level == pc->brace_level) &&
                ((pc->type == CT_FPAREN_OPEN) || (pc->type == CT_SPAREN_OPEN)))
            {
               //frm.pse[frm.pse_tos].indent += abs(cpd.settings[UO_indent_continue].n);
               frm.pse[frm.pse_tos].indent = calc_indent_continue(frm, frm.pse_tos);
               frm.pse[frm.pse_tos].indent_cont = true;
            }
         }
         frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
         frm.paren_count++;
      }
      else if ((pc->type == CT_ASSIGN) ||
               (pc->type == CT_IMPORT) ||
               (pc->type == CT_USING))
      {
         /**
          * if there is a newline after the '=' or the line starts with a '=',
          * just indent one level,
          * otherwise align on the '='.
          */
         if ((pc->type == CT_ASSIGN) && chunk_is_newline(chunk_get_prev(pc)))
         {
            frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent + indent_size;
            indent_column_set(frm.pse[frm.pse_tos].indent_tmp);
            LOG_FMT(LINDENT, "%s: %d] assign => %d [%s]\n",
                    __func__, pc->orig_line, indent_column, pc->str.c_str());
            reindent_line(pc, frm.pse[frm.pse_tos].indent_tmp);
         }

         next = chunk_get_next(pc);
         if (next != NULL)
         {
            indent_pse_push(frm, pc);
            if (cpd.settings[UO_indent_continue].n != 0)
            {
               frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent;
               if ((pc->level == pc->brace_level) &&
                   ((pc->type != CT_ASSIGN) ||
                    ((pc->parent_type != CT_FUNC_PROTO) && (pc->parent_type != CT_FUNC_DEF))))
               {
                  //frm.pse[frm.pse_tos].indent += abs(cpd.settings[UO_indent_continue].n);
                  frm.pse[frm.pse_tos].indent = calc_indent_continue(frm, frm.pse_tos);
                  frm.pse[frm.pse_tos].indent_cont = true;

               }
            }
            else if (chunk_is_newline(next) || !cpd.settings[UO_indent_align_assign].b)
            {
               frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size;
               if (pc->type == CT_ASSIGN)
               {
                  frm.pse[frm.pse_tos].type = CT_ASSIGN_NL;
               }
            }
            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) ||
               ((pc->type == CT_THROW) && (pc->parent_type == CT_NONE)))
      {
         /* don't count returns inside a () or [] */
         if (pc->level == pc->brace_level)
         {
            indent_pse_push(frm, pc);
            if (chunk_is_newline(chunk_get_next(pc)))
            {
               frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;
            }
            else
            {
               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 ((pc->type == CT_OC_SCOPE) || (pc->type == CT_TYPEDEF))
      {
         indent_pse_push(frm, pc);
         if (cpd.settings[UO_indent_continue].n != 0)
         {
            //frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent +
            //                              abs(cpd.settings[UO_indent_continue].n);
            frm.pse[frm.pse_tos].indent = calc_indent_continue(frm, frm.pse_tos - 1);
            frm.pse[frm.pse_tos].indent_cont = true;
         }
         else
         {
            frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;
         }
      }
      else
      {
         /* anything else? */
      }

      /**
       * Handle variable definition continuation indenting
       */
      if ((vardefcol == 0) &&
          ((pc->type == CT_WORD) || (pc->type == CT_FUNC_CTOR_VAR)) &&
          ((pc->flags & PCF_IN_FCN_DEF) == 0) &&
          ((pc->flags & PCF_VAR_1ST_DEF) == PCF_VAR_1ST_DEF))
      {
         if (cpd.settings[UO_indent_continue].n != 0)
         {
            //vardefcol = frm.pse[frm.pse_tos].indent +
            //            abs(cpd.settings[UO_indent_continue].n);
            vardefcol = calc_indent_continue(frm, frm.pse_tos);
            frm.pse[frm.pse_tos].indent_cont = true;
         }
         else if (cpd.settings[UO_indent_var_def_cont].b ||
                  chunk_is_newline(chunk_get_prev(pc)))
         {
            vardefcol = frm.pse[frm.pse_tos].indent + indent_size;
         }
         else
         {
            vardefcol = pc->column;
            /* need to skip backward over any '*' */
            chunk_t *tmp = chunk_get_prev_nc(pc);
            while (chunk_is_token(tmp, CT_PTR_TYPE))
            {
               vardefcol = tmp->column;
               tmp = chunk_get_prev_nc(tmp);
            }
         }
      }
      if (chunk_is_semicolon(pc) ||
          ((pc->type == CT_BRACE_OPEN) && (pc->parent_type == CT_FUNCTION)))
      {
         vardefcol = 0;
      }

      /**
       * Indent the line if needed
       */
      if (did_newline && !chunk_is_newline(pc) && (pc->len() != 0))
      {
         pc->column_indent = frm.pse[frm.pse_tos].indent_tab;

         if (frm.pse[frm.pse_tos].ip.ref)
         {
            pc->indent.ref   = frm.pse[frm.pse_tos].ip.ref;
            pc->indent.delta = frm.pse[frm.pse_tos].ip.delta;
         }

         LOG_FMT(LINDENT2, "%s: %d] %d/%d for %s\n",
                 __func__, pc->orig_line, pc->column_indent, indent_column, pc->str.c_str());

         /**
          * 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);
         next = chunk_get_next_ncnl(pc);

         bool do_vardefcol = false;
         if ((vardefcol > 0) &&
             (pc->level == pc->brace_level) &&
             prev &&
             ((prev->type == CT_COMMA) ||
              (prev->type == CT_TYPE) ||
              (prev->type == CT_PTR_TYPE) ||
              (prev->type == CT_WORD)))
         {
            chunk_t *tmp = pc;
            while (chunk_is_token(tmp, CT_PTR_TYPE))
            {
               tmp = chunk_get_next_ncnl(tmp);
            }
            if (tmp && ((tmp->flags & PCF_VAR_DEF) != 0) &&
                ((tmp->type == CT_WORD) || (tmp->type == CT_FUNC_CTOR_VAR)))
            {
               do_vardefcol = true;
            }
         }

         if ((pc->flags & PCF_DONT_INDENT) != 0)
         {
            /* no change */
         }
         else if ((pc->parent_type == CT_SQL_EXEC) &&
                  cpd.settings[UO_indent_preserve_sql].b)
         {
            reindent_line(pc, sql_col + (pc->orig_col - sql_orig_col));
            LOG_FMT(LINDENT, "Indent SQL: [%s] to %d (%d/%d)\n",
                    pc->str.c_str(), pc->column, sql_col, sql_orig_col);
         }
         else if (((pc->flags & PCF_STMT_START) == 0) &&
                  ((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 (do_vardefcol)
         {
            LOG_FMT(LINDENT, "%s: %d] Vardefcol => %d\n",
                    __func__, pc->orig_line, vardefcol);
            reindent_line(pc, vardefcol);
         }
         else if ((pc->type == CT_NAMESPACE) &&
                  cpd.settings[UO_indent_namespace].b &&
                  cpd.settings[UO_indent_namespace_single_indent].b &&
                  frm.pse[frm.pse_tos].ns_cnt)
         {
            LOG_FMT(LINDENT, "%s: %d] Namespace => %d\n",
                    __func__, pc->orig_line, frm.pse[frm.pse_tos].brace_indent);
            reindent_line(pc, frm.pse[frm.pse_tos].brace_indent);
         }
         else if ((pc->type == CT_STRING) && (prev != NULL) && (prev->type == CT_STRING) &&
                  cpd.settings[UO_indent_align_string].b)
         {
            tmp = (xml_indent != 0) ? xml_indent : prev->column;

            LOG_FMT(LINDENT, "%s: %d] String => %d\n",
                    __func__, pc->orig_line, tmp);
            reindent_line(pc, tmp);
         }
         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)
         {
            LOG_FMT(LINDENT, "%s: %d] pp-indent => %d [%s]\n",
                    __func__, pc->orig_line, indent_column, pc->str.c_str());
            reindent_line(pc, indent_column);
         }
         else if (chunk_is_paren_close(pc) || (pc->type == CT_ANGLE_CLOSE))
         {
            /* This is a big hack. We assume that since we hit a paren close,
             * that we just removed a paren open */
            if (frm.pse[frm.pse_tos + 1].type == c_token_t(pc->type - 1))
            {
               chunk_t *ck1 = frm.pse[frm.pse_tos + 1].pc;
               chunk_t *ck2 = chunk_get_prev(ck1);

               /* If the open paren was the first thing on the line or we are
               * doing mode 1, then put the close paren in the same column */
               if (chunk_is_newline(ck2) ||
                   (cpd.settings[UO_indent_paren_close].n == 1))
               {
                  indent_column_set(ck1->column);
               }
               else
               {
                  if (cpd.settings[UO_indent_paren_close].n != 2)
                  {
                     indent_column_set(frm.pse[frm.pse_tos + 1].indent_tmp);
                     if (cpd.settings[UO_indent_paren_close].n == 1)
                     {
                        indent_column--;
                     }
                  }
               }
            }
            LOG_FMT(LINDENT, "%s: %d] cl paren => %d [%s]\n",
                    __func__, pc->orig_line, indent_column, pc->str.c_str());
            reindent_line(pc, indent_column);
         }
         else if (pc->type == CT_COMMA)
         {
            if (cpd.settings[UO_indent_comma_paren].b &&
                chunk_is_paren_open(frm.pse[frm.pse_tos].pc))
            {
               indent_column_set(frm.pse[frm.pse_tos].pc->column);
            }
            LOG_FMT(LINDENT, "%s: %d] comma => %d [%s]\n",
                    __func__, pc->orig_line, indent_column, pc->str.c_str());
            reindent_line(pc, indent_column);
         }
         else if (cpd.settings[UO_indent_func_const].n &&
                  (pc->type == CT_QUALIFIER) &&
                  (strncasecmp(pc->text(), "const", pc->len()) == 0) &&
                  ((next == NULL) ||
                   (next->type == CT_BRACED) ||
                   (next->type == CT_BRACE_OPEN) ||
                   (next->type == CT_NEWLINE) ||
                   (next->type == CT_SEMICOLON) ||
                   (next->type == CT_THROW) ||
                   (next->type == CT_VBRACE_OPEN)))
         {
            // indent const - void GetFoo(void)\n const\n { return (m_Foo); }
            indent_column_set(cpd.settings[UO_indent_func_const].n);
            LOG_FMT(LINDENT, "%s: %d] const => %d [%s]\n",
                    __func__, pc->orig_line, indent_column, pc->str.c_str());
            reindent_line(pc, indent_column);
         }
         else if (cpd.settings[UO_indent_func_throw].n &&
                  (pc->type == CT_THROW) &&
                  (pc->parent_type != CT_NONE))
         {
            // indent throw - void GetFoo(void)\n throw()\n { return (m_Foo); }
            indent_column_set(cpd.settings[UO_indent_func_throw].n);
            LOG_FMT(LINDENT, "%s: %d] throw => %d [%s]\n",
                    __func__, pc->orig_line, indent_column, pc->str.c_str());
            reindent_line(pc, indent_column);
         }
         else if (pc->type == CT_BOOL)
         {
            if (cpd.settings[UO_indent_bool_paren].b &&
                chunk_is_paren_open(frm.pse[frm.pse_tos].pc))
            {
               indent_column_set(frm.pse[frm.pse_tos].pc->column);
               if (cpd.settings[UO_indent_first_bool_expr].b)
               {
                  reindent_line(chunk_get_next(frm.pse[frm.pse_tos].pc),
                                indent_column + pc->len() + 1);
               }
            }
            LOG_FMT(LINDENT, "%s: %d] bool => %d [%s]\n",
                    __func__, pc->orig_line, indent_column, pc->str.c_str());
            reindent_line(pc, indent_column);
         }
         else
         {
            if (pc->column != indent_column)
            {
               LOG_FMT(LINDENT, "%s: %d] indent => %d [%s]\n",
                       __func__, pc->orig_line, indent_column, pc->str.c_str());
               reindent_line(pc, indent_column);
            }
         }
         did_newline = false;

         if ((pc->type == CT_SQL_EXEC) ||
             (pc->type == CT_SQL_BEGIN) ||
             (pc->type == CT_SQL_END))
         {
            sql_col      = pc->column;
            sql_orig_col = pc->orig_col;
         }

         /* Handle indent for variable defs at the top of a block of code */
         if (pc->flags & PCF_VAR_TYPE)
         {
            if (!frm.pse[frm.pse_tos].non_vardef &&
                (frm.pse[frm.pse_tos].type == CT_BRACE_OPEN))
            {
               tmp = indent_column;
               if (cpd.settings[UO_indent_var_def_blk].n > 0)
               {
                  tmp = cpd.settings[UO_indent_var_def_blk].n;
               }
               else
               {
                  tmp += cpd.settings[UO_indent_var_def_blk].n;
               }
               reindent_line(pc, tmp);
               LOG_FMT(LINDENT, "%s: %d] var_type indent => %d [%s]\n",
                       __func__, pc->orig_line, tmp, pc->str.c_str());
            }
         }
         else
         {
            if (pc != frm.pse[frm.pse_tos].pc)
            {
               frm.pse[frm.pse_tos].non_vardef = true;
            }
         }
      }

      /* 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;
      }

      /* Check for open XML tags "</..." */
      if (cpd.settings[UO_indent_xml_string].n > 0)
      {
         if (pc->type == CT_STRING)
         {
            if ((pc->len() > 4) &&
                (pc->str[1] == '<') &&
                (pc->str[2] != '/') &&
                (pc->str[pc->len() - 3] != '/'))
            {
               if (xml_indent <= 0)
               {
                  xml_indent = pc->column;
               }
               xml_indent += cpd.settings[UO_indent_xml_string].n;
            }
         }
      }

      if (!chunk_is_comment(pc) && !chunk_is_newline(pc))
      {
         prev = pc;
      }
      pc = chunk_get_next(pc);
   }
null_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);
   }

   /* Throw out any VBRACE_OPEN at the end - implied with the end of file  */
   while ((frm.pse_tos > 0) && (frm.pse[frm.pse_tos].type == CT_VBRACE_OPEN))
   {
      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++;
   }

   quick_align_again();
   quick_indent_again();
}


/**
 * 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)
{
   LOG_FUNC_ENTRY();
   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)
{
   LOG_FUNC_ENTRY();
   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 &&
       ((pc->flags & PCF_INSERTED) == 0))
   {
      LOG_FMT(LCMTIND, "rule 1 - keep in col 1\n");
      reindent_line(pc, 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");
         reindent_line(pc, 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))
      {
         reindent_line(pc, 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))
   {
      reindent_line(pc, 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);

   reindent_line(pc, col);
}


/**
 * Scan to see if the whole file is covered by one #ifdef
 */
static bool ifdef_over_whole_file()
{
   LOG_FUNC_ENTRY();
   chunk_t *pc;
   chunk_t *next;

   int stage = 0;

   /* the results for this file are cached */
   if (cpd.ifdef_over_whole_file)
   {
      return (cpd.ifdef_over_whole_file > 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;
         }
      }
   }

   cpd.ifdef_over_whole_file = (stage == 2) ? 1 : -1;
   LOG_FMT(LNOTE, "The whole file is%s covered by a #IF\n",
           (cpd.ifdef_over_whole_file > 0) ? "" : " NOT");
   return (cpd.ifdef_over_whole_file > 0);
}


/**
 * Indent the preprocessor stuff from column 1.
 * FIXME: This is broken if there is a comment or escaped newline
 * between '#' and 'define'.
 */
void indent_preproc(void)
{
   LOG_FUNC_ENTRY();
   chunk_t *pc;
   chunk_t *next;
   int     pp_level;
   int     pp_level_sub = 0;

   /* Scan to see if the whole file is covered by one #ifdef */
   if (ifdef_over_whole_file())
   {
      pp_level_sub = 1;
   }

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

      next = chunk_get_next_ncnl(pc);

      pp_level = pc->pp_level - pp_level_sub;
      if (pp_level < 0)
      {
         pp_level = 0;
      }

      /* Adjust the indent of the '#' */
      if ((cpd.settings[UO_pp_indent].a & AV_ADD) != 0)
      {
         reindent_line(pc, 1 + pp_level * cpd.settings[UO_pp_indent_count].n);
      }
      else if ((cpd.settings[UO_pp_indent].a & AV_REMOVE) != 0)
      {
         reindent_line(pc, 1);
      }

      /* Add spacing by adjusting the length */
      if ((cpd.settings[UO_pp_space].a != AV_IGNORE) && (next != NULL))
      {
         if ((cpd.settings[UO_pp_space].a & AV_ADD) != 0)
         {
            int mult = cpd.settings[UO_pp_space_count].n;

            if (mult < 1)
            {
               mult = 1;
            }
            reindent_line(next, pc->column + pc->len() + (pp_level * mult));
         }
         else if ((cpd.settings[UO_pp_space].a & AV_REMOVE) != 0)
         {
            reindent_line(next, pc->column + pc->len());
         }
      }

      /* Mark as already handled if not region stuff or in column 1 */
      if ((!cpd.settings[UO_pp_indent_at_level].b ||
           (pc->brace_level <= ((pc->parent_type == CT_PP_DEFINE) ? 1 : 0))) &&
          (pc->parent_type != CT_PP_REGION) &&
          (pc->parent_type != CT_PP_ENDREGION))
      {
         if (!cpd.settings[UO_pp_define_at_level].b ||
             (pc->parent_type != CT_PP_DEFINE))
         {
            pc->flags |= PCF_DONT_INDENT;
         }
      }

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