Beispiel #1
0
/**
 * Scan backwards to find the most appropriate spot to split the line
 * and insert a newline.
 *
 * See if this needs special function handling.
 * Scan backwards and find the best token for the split.
 *
 * @param start The first chunk that exceeded the limit
 */
static bool split_line(chunk_t *start)
{
   LOG_FUNC_ENTRY();
   LOG_FMT(LSPLIT, "%s: line %lu, col %d token: '%s' [%s] (IN_FUNC=%d) ",
           __func__, start->orig_line, start->column, start->text(),
           get_token_name(start->type),
           (start->flags & (PCF_IN_FCN_DEF | PCF_IN_FCN_CALL)) != 0);

   /**
    * break at maximum line length if ls_code_width is true
    */
   if (start->flags & PCF_ONE_LINER)
   {
      LOG_FMT(LSPLIT, " ** ONCE LINER SPLIT **\n");
      undo_one_liner(start);
      newlines_cleanup_braces(false);
      return(false);
   }

   if (cpd.settings[UO_ls_code_width].b)
   {
   }
   /* Check to see if we are in a for statement */
   else if (start->flags & PCF_IN_FOR)
   {
      LOG_FMT(LSPLIT, " ** FOR SPLIT **\n");
      split_for_stmt(start);
      if (!is_past_width(start))
      {
         return(true);
      }
      LOG_FMT(LSPLIT, "%s: for split didn't work\n", __func__);
   }

   /* If this is in a function call or prototype, split on commas or right
    * after the open paren
    */
   else if ((start->flags & PCF_IN_FCN_DEF) ||
            ((start->level == (start->brace_level + 1)) &&
             (start->flags & PCF_IN_FCN_CALL)))
   {
      LOG_FMT(LSPLIT, " ** FUNC SPLIT **\n");

      if (cpd.settings[UO_ls_func_split_full].b)
      {
         split_fcn_params_full(start);
         if (!is_past_width(start))
         {
            return(true);
         }
      }
      split_fcn_params(start);
      return(true);
   }

   /**
    * Try to find the best spot to split the line
    */
   cw_entry ent;

   memset(&ent, 0, sizeof(ent));
   chunk_t *pc = start;
   chunk_t *prev;

   while (((pc = chunk_get_prev(pc)) != NULL) && !chunk_is_newline(pc))
   {
      LOG_FMT(LSPLIT, "%s: at %s, col=%lu\n", __func__, pc->text(), pc->orig_col);
      if (pc->type != CT_SPACE)
      {
         try_split_here(ent, pc);
         /*  break at maximum line length */
         if ((ent.pc != NULL) && (cpd.settings[UO_ls_code_width].b))
         {
            break;
         }
      }
   }

   if (ent.pc == NULL)
   {
      LOG_FMT(LSPLIT, "\n%s:    TRY_SPLIT yielded NO SOLUTION for line %lu at %s [%s]\n",
              __func__, start->orig_line, start->text(), get_token_name(start->type));
   }
   else
   {
      LOG_FMT(LSPLIT, "\n%s:    TRY_SPLIT yielded '%s' [%s] on line %lu\n",
              __func__, ent.pc->text(), get_token_name(ent.pc->type), ent.pc->orig_line);
      LOG_FMT(LSPLIT, "%s: ent at %s, col=%lu\n",
              __func__, ent.pc->text(), ent.pc->orig_col);
   }

   /* Break before the token instead of after it according to the pos_xxx rules */
   if (ent.pc == NULL)
   {
      pc = NULL;
   }
   else
   {
      if (((chunk_is_token(ent.pc, CT_ARITH) || chunk_is_token(ent.pc, CT_CARET)) &&
           (cpd.settings[UO_pos_arith].tp & TP_LEAD)) ||
          (chunk_is_token(ent.pc, CT_ASSIGN) &&
           (cpd.settings[UO_pos_assign].tp & TP_LEAD)) ||
          (chunk_is_token(ent.pc, CT_COMPARE) &&
           (cpd.settings[UO_pos_compare].tp & TP_LEAD)) ||
          ((chunk_is_token(ent.pc, CT_COND_COLON) ||
            chunk_is_token(ent.pc, CT_QUESTION)) &&
           (cpd.settings[UO_pos_conditional].tp & TP_LEAD)) ||
          (chunk_is_token(ent.pc, CT_BOOL) &&
           (cpd.settings[UO_pos_bool].tp & TP_LEAD)))
      {
         pc = ent.pc;
      }
      else
      {
         pc = chunk_get_next(ent.pc);
      }
      LOG_FMT(LSPLIT, "%s: at %s, col=%lu\n", __func__, pc->text(), pc->orig_col);
   }

   if (pc == NULL)
   {
      pc = start;
      /* Don't break before a close, comma, or colon */
      if ((start->type == CT_PAREN_CLOSE) ||
          (start->type == CT_PAREN_OPEN) ||
          (start->type == CT_FPAREN_CLOSE) ||
          (start->type == CT_FPAREN_OPEN) ||
          (start->type == CT_SPAREN_CLOSE) ||
          (start->type == CT_SPAREN_OPEN) ||
          (start->type == CT_ANGLE_CLOSE) ||
          (start->type == CT_BRACE_CLOSE) ||
          (start->type == CT_COMMA) ||
          (start->type == CT_SEMICOLON) ||
          (start->type == CT_VSEMICOLON) ||
          (start->len() == 0))
      {
         LOG_FMT(LSPLIT, " ** NO GO **\n");

         /*TODO: Add in logic to handle 'hard' limits by backing up a token */
         return(true);
      }
   }

   /* add a newline before pc */
   prev = chunk_get_prev(pc);
   if ((prev != NULL) && !chunk_is_newline(pc) && !chunk_is_newline(prev))
   {
      //int plen = (pc->len() < 5) ? pc->len() : 5;
      //int slen = (start->len() < 5) ? start->len() : 5;
      //LOG_FMT(LSPLIT, " '%.*s' [%s], started on token '%.*s' [%s]\n",
      //        plen, pc->text(), get_token_name(pc->type),
      //        slen, start->text(), get_token_name(start->type));
      LOG_FMT(LSPLIT, "  %s [%s], started on token '%s' [%s]\n",
              pc->text(), get_token_name(pc->type),
              start->text(), get_token_name(start->type));

      split_before_chunk(pc);
   }
   return(true);
} // split_line
Beispiel #2
0
static void uncrustify_file(const file_mem& fm, FILE *pfout,
                            const char *parsed_file)
{
   const deque<int>& data = fm.data;

   /* Save off the encoding and whether a BOM is required */
   cpd.bom = fm.bom;
   cpd.enc = fm.enc;
   if (cpd.settings[UO_utf8_force].b ||
       ((cpd.enc == ENC_BYTE) && cpd.settings[UO_utf8_byte].b))
   {
      cpd.enc = ENC_UTF8;
   }
   argval_t av;
   switch (cpd.enc)
   {
   case ENC_UTF8:
      av = cpd.settings[UO_utf8_bom].a;
      break;

   case ENC_UTF16_LE:
   case ENC_UTF16_BE:
      av = AV_FORCE;
      break;

   default:
      av = AV_IGNORE;
      break;
   }
   if (av == AV_REMOVE)
   {
      cpd.bom = false;
   }
   else if (av != AV_IGNORE)
   {
      cpd.bom = true;
   }

   /* Check for embedded 0's (represents a decoding failure or corrupt file) */
   for (int idx = 0; idx < (int)data.size() - 1; idx++)
   {
      if (data[idx] == 0)
      {
         LOG_FMT(LERR, "An embedded 0 was found in '%s'.\n", cpd.filename);
         LOG_FMT(LERR, "The file may be encoded in an unsupported Unicode format.\n");
         LOG_FMT(LERR, "Aborting.\n");
         cpd.error_count++;
         return;
      }
   }

   uncrustify_start(data);

   /**
    * Done with detection. Do the rest only if the file will go somewhere.
    * The detection code needs as few changes as possible.
    */
   if (pfout != NULL)
   {
      /**
       * Add comments before function defs and classes
       */
      if (cpd.func_hdr.data.size() > 0)
      {
         add_func_header(CT_FUNC_DEF, cpd.func_hdr);
      }
      if (cpd.class_hdr.data.size() > 0)
      {
         add_func_header(CT_CLASS, cpd.class_hdr);
      }
      if (cpd.oc_msg_hdr.data.size() > 0)
      {
         add_msg_header(CT_OC_MSG_DECL, cpd.oc_msg_hdr);
      }

      /**
       * Change virtual braces into real braces...
       */
      do_braces();

      /* Scrub extra semicolons */
      if (cpd.settings[UO_mod_remove_extra_semicolon].b)
      {
         remove_extra_semicolons();
      }

      /* Remove unnecessary returns */
      if (cpd.settings[UO_mod_remove_empty_return].b)
      {
         remove_extra_returns();
      }

      /**
       * Add parens
       */
      do_parens();

      /**
       * Modify line breaks as needed
       */
      bool first = true;
      int  old_changes;

      if (cpd.settings[UO_nl_remove_extra_newlines].n == 2)
      {
         newlines_remove_newlines();
      }
      cpd.pass_count = 3;
      do
      {
         old_changes = cpd.changes;

         LOG_FMT(LNEWLINE, "Newline loop start: %d\n", cpd.changes);

         newlines_cleanup_dup();
         newlines_cleanup_braces(first);
         if (cpd.settings[UO_nl_after_multiline_comment].b)
         {
            newline_after_multiline_comment();
         }
         newlines_insert_blank_lines();
         if (cpd.settings[UO_pos_bool].tp != TP_IGNORE)
         {
            newlines_chunk_pos(CT_BOOL, cpd.settings[UO_pos_bool].tp);
         }
         if (cpd.settings[UO_pos_compare].tp != TP_IGNORE)
         {
            newlines_chunk_pos(CT_COMPARE, cpd.settings[UO_pos_compare].tp);
         }
         if (cpd.settings[UO_pos_conditional].tp != TP_IGNORE)
         {
            newlines_chunk_pos(CT_COND_COLON, cpd.settings[UO_pos_conditional].tp);
            newlines_chunk_pos(CT_QUESTION, cpd.settings[UO_pos_conditional].tp);
         }
         if (cpd.settings[UO_pos_comma].tp != TP_IGNORE)
         {
            newlines_chunk_pos(CT_COMMA, cpd.settings[UO_pos_comma].tp);
         }
         if (cpd.settings[UO_pos_assign].tp != TP_IGNORE)
         {
            newlines_chunk_pos(CT_ASSIGN, cpd.settings[UO_pos_assign].tp);
         }
         if (cpd.settings[UO_pos_arith].tp != TP_IGNORE)
         {
            newlines_chunk_pos(CT_ARITH, cpd.settings[UO_pos_arith].tp);
         }
         newlines_class_colon_pos();
         if (cpd.settings[UO_nl_squeeze_ifdef].b)
         {
            newlines_squeeze_ifdef();
         }
         do_blank_lines();
         newlines_eat_start_end();
         newlines_cleanup_dup();
         first = false;
      } while ((old_changes != cpd.changes) && (cpd.pass_count-- > 0));

      mark_comments();

      /**
       * Add balanced spaces around nested params
       */
      if (cpd.settings[UO_sp_balance_nested_parens].b)
      {
         space_text_balance_nested_parens();
      }

      /* Scrub certain added semicolons */
      if (((cpd.lang_flags & LANG_PAWN) != 0) &&
          cpd.settings[UO_mod_pawn_semicolon].b)
      {
         pawn_scrub_vsemi();
      }

      /* Sort imports/using/include */
      if (cpd.settings[UO_mod_sort_import].b ||
          cpd.settings[UO_mod_sort_include].b ||
          cpd.settings[UO_mod_sort_using].b)
      {
         sort_imports();
      }

      /**
       * Fix same-line inter-chunk spacing
       */
      space_text();

      /**
       * Do any aligning of preprocessors
       */
      if (cpd.settings[UO_align_pp_define_span].n > 0)
      {
         align_preprocessor();
      }

      /**
       * Indent the text
       */
      indent_preproc();
      indent_text();

      /* Insert trailing comments after certain close braces */
      if ((cpd.settings[UO_mod_add_long_switch_closebrace_comment].n > 0) ||
          (cpd.settings[UO_mod_add_long_function_closebrace_comment].n > 0))
      {
         add_long_closebrace_comment();
      }

      /* Insert trailing comments after certain preprocessor conditional blocks */
      if ((cpd.settings[UO_mod_add_long_ifdef_else_comment].n > 0) ||
          (cpd.settings[UO_mod_add_long_ifdef_endif_comment].n > 0))
      {
         add_long_preprocessor_conditional_block_comment();
      }

      /**
       * Align everything else, reindent and break at code_width
       */
      first          = true;
      cpd.pass_count = 3;
      do
      {
         align_all();
         indent_text();
         old_changes = cpd.changes;
         if (cpd.settings[UO_code_width].n > 0)
         {
            LOG_FMT(LNEWLINE, "Code_width loop start: %d\n", cpd.changes);

            do_code_width();
            if ((old_changes != cpd.changes) && first)
            {
               /* retry line breaks caused by splitting 1-liners */
               newlines_cleanup_braces(false);
               newlines_insert_blank_lines();
               first = false;
            }
         }
      } while ((old_changes != cpd.changes) && (cpd.pass_count-- > 0));

      /**
       * And finally, align the backslash newline stuff
       */
      align_right_comments();
      if (cpd.settings[UO_align_nl_cont].b)
      {
         align_backslash_newline();
      }

      /**
       * Now render it all to the output file
       */
      output_text(pfout);
   }

   /* Special hook for dumping parsed data for debugging */
   if (parsed_file != NULL)
   {
      FILE *p_file = fopen(parsed_file, "w");
      if (p_file != NULL)
      {
         output_parsed(p_file);
         fclose(p_file);
      }
      else
      {
         LOG_FMT(LERR, "%s: Failed to open '%s' for write: %s (%d)\n",
                 __func__, parsed_file, strerror(errno), errno);
      }
   }

   uncrustify_end();
}
Beispiel #3
0
static bool split_line(chunk_t *start)
{
   LOG_FUNC_ENTRY();
   LOG_FMT(LSPLIT, "%s(%d): start->text() '%s', orig_line is %zu, orig_col is %zu, type is %s\n",
           __func__, __LINE__, start->text(), start->orig_line, start->orig_col, get_token_name(start->type));
   LOG_FMT(LSPLIT, "   start->flags ");
   log_pcf_flags(LSPLIT, start->flags);
   LOG_FMT(LSPLIT, "   start->parent_type %s, (PCF_IN_FCN_DEF is %s), (PCF_IN_FCN_CALL is %s)\n",
           get_token_name(start->parent_type),
           ((start->flags & (PCF_IN_FCN_DEF)) != 0) ? "TRUE" : "FALSE",
           ((start->flags & (PCF_IN_FCN_CALL)) != 0) ? "TRUE" : "FALSE");

   // break at maximum line length if ls_code_width is true
   if (start->flags & PCF_ONE_LINER)
   {
      LOG_FMT(LSPLIT, "%s(%d): ** ONCE LINER SPLIT **\n", __func__, __LINE__);
      undo_one_liner(start);
      newlines_cleanup_braces(false);
      // Issue #1352
      cpd.changes++;
      return(false);
   }

   LOG_FMT(LSPLIT, "%s(%d):\n", __func__, __LINE__);
   if (cpd.settings[UO_ls_code_width].b)
   {
   }
   // Check to see if we are in a for statement
   else if (start->flags & PCF_IN_FOR)
   {
      LOG_FMT(LSPLIT, " ** FOR SPLIT **\n");
      split_for_stmt(start);
      if (!is_past_width(start))
      {
         return(true);
      }
      LOG_FMT(LSPLIT, "%s(%d): for split didn't work\n", __func__, __LINE__);
   }

   /*
    * If this is in a function call or prototype, split on commas or right
    * after the open parenthesis
    */
   else if (  (start->flags & PCF_IN_FCN_DEF)
           || start->parent_type == CT_FUNC_PROTO            // Issue #1169
           || (  (start->level == (start->brace_level + 1))
              && (start->flags & PCF_IN_FCN_CALL)))
   {
      LOG_FMT(LSPLIT, " ** FUNC SPLIT **\n");

      if (cpd.settings[UO_ls_func_split_full].b)
      {
         split_fcn_params_full(start);
         if (!is_past_width(start))
         {
            return(true);
         }
      }
      split_fcn_params(start);
      return(true);
   }

   /*
    * If this is in a template, split on commas, Issue #1170
    */
   else if (start->flags & PCF_IN_TEMPLATE)
   {
      LOG_FMT(LSPLIT, " ** TEMPLATE SPLIT **\n");
      split_template(start);
      return(true);
   }

   LOG_FMT(LSPLIT, "%s(%d):\n", __func__, __LINE__);
   // Try to find the best spot to split the line
   cw_entry ent;

   memset(&ent, 0, sizeof(ent));
   chunk_t *pc = start;
   chunk_t *prev;

   while (((pc = chunk_get_prev(pc)) != nullptr) && !chunk_is_newline(pc))
   {
      LOG_FMT(LSPLIT, "%s(%d): at %s, orig_line=%zu, orig_col=%zu\n",
              __func__, __LINE__, pc->text(), pc->orig_line, pc->orig_col);
      if (pc->type != CT_SPACE)
      {
         try_split_here(ent, pc);
         // break at maximum line length
         if (ent.pc != nullptr && (cpd.settings[UO_ls_code_width].b))
         {
            break;
         }
      }
   }

   if (ent.pc == nullptr)
   {
      LOG_FMT(LSPLIT, "\n%s(%d):    TRY_SPLIT yielded NO SOLUTION for orig_line %zu at '%s' [%s]\n",
              __func__, __LINE__, start->orig_line, start->text(), get_token_name(start->type));
   }
   else
   {
      LOG_FMT(LSPLIT, "\n%s(%d):    TRY_SPLIT yielded '%s' [%s] on orig_line %zu\n",
              __func__, __LINE__, ent.pc->text(), get_token_name(ent.pc->type), ent.pc->orig_line);
      LOG_FMT(LSPLIT, "%s(%d): ent at '%s', orig_col is %zu\n",
              __func__, __LINE__, ent.pc->text(), ent.pc->orig_col);
   }

   // Break before the token instead of after it according to the pos_xxx rules
   if (ent.pc == nullptr)
   {
      pc = nullptr;
   }
   else
   {
      if (  (  (  chunk_is_token(ent.pc, CT_ARITH)
               || chunk_is_token(ent.pc, CT_CARET))
            && (cpd.settings[UO_pos_arith].tp & TP_LEAD))
         || (  chunk_is_token(ent.pc, CT_ASSIGN)
            && (cpd.settings[UO_pos_assign].tp & TP_LEAD))
         || (  chunk_is_token(ent.pc, CT_COMPARE)
            && (cpd.settings[UO_pos_compare].tp & TP_LEAD))
         || (  (  chunk_is_token(ent.pc, CT_COND_COLON)
               || chunk_is_token(ent.pc, CT_QUESTION))
            && (cpd.settings[UO_pos_conditional].tp & TP_LEAD))
         || (  chunk_is_token(ent.pc, CT_BOOL)
            && (cpd.settings[UO_pos_bool].tp & TP_LEAD)))
      {
         pc = ent.pc;
      }
      else
      {
         pc = chunk_get_next(ent.pc);
      }
      LOG_FMT(LSPLIT, "%s(%d): at '%s', orig_col is %zu\n",
              __func__, __LINE__, pc->text(), pc->orig_col);
   }

   if (pc == nullptr)
   {
      pc = start;
      // Don't break before a close, comma, or colon
      if (  start->type == CT_PAREN_CLOSE
         || start->type == CT_PAREN_OPEN
         || start->type == CT_FPAREN_CLOSE
         || start->type == CT_FPAREN_OPEN
         || start->type == CT_SPAREN_CLOSE
         || start->type == CT_SPAREN_OPEN
         || start->type == CT_ANGLE_CLOSE
         || start->type == CT_BRACE_CLOSE
         || start->type == CT_COMMA
         || start->type == CT_SEMICOLON
         || start->type == CT_VSEMICOLON
         || start->len() == 0)
      {
         LOG_FMT(LSPLIT, " ** NO GO **\n");

         // TODO: Add in logic to handle 'hard' limits by backing up a token
         return(true);
      }
   }

   // add a newline before pc
   prev = chunk_get_prev(pc);
   if (  prev != nullptr
      && !chunk_is_newline(pc)
      && !chunk_is_newline(prev))
   {
      //int plen = (pc->len() < 5) ? pc->len() : 5;
      //int slen = (start->len() < 5) ? start->len() : 5;
      //LOG_FMT(LSPLIT, " '%.*s' [%s], started on token '%.*s' [%s]\n",
      //        plen, pc->text(), get_token_name(pc->type),
      //        slen, start->text(), get_token_name(start->type));
      LOG_FMT(LSPLIT, "%s(%d): text() '%s', type [%s], started on token '%s', type [%s]\n",
              __func__, __LINE__, pc->text(), get_token_name(pc->type),
              start->text(), get_token_name(start->type));

      split_before_chunk(pc);
   }
   return(true);
} // split_line
Beispiel #4
0
static void uncrustify_file(const char *data, int data_len, FILE *pfout,
                            const char *parsed_file)
{
   uncrustify_start(data, data_len);

   /**
    * Done with detection. Do the rest only if the file will go somewhere.
    * The detection code needs as few changes as possible.
    */
   if (pfout != NULL)
   {
      /**
       * Add comments before function defs and classes
       */
      if (cpd.func_hdr.data != NULL)
      {
         add_func_header(CT_FUNC_DEF, cpd.func_hdr);
      }
      if (cpd.class_hdr.data != NULL)
      {
         add_func_header(CT_CLASS, cpd.class_hdr);
      }

      /**
       * Change virtual braces into real braces...
       */
      do_braces();

      /* Scrub extra semicolons */
      if (cpd.settings[UO_mod_remove_extra_semicolon].b)
      {
         remove_extra_semicolons();
      }

      /* Remove unnecessary returns */
      if (cpd.settings[UO_mod_remove_empty_return].b)
      {
         remove_extra_returns();
      }

      /**
       * Add parens
       */
      do_parens();

      /**
       * Insert line breaks as needed
       */
      do_blank_lines();
      newlines_cleanup_braces();
      if (cpd.settings[UO_nl_after_multiline_comment].b)
      {
         newline_after_multiline_comment();
      }
      newlines_insert_blank_lines();
      if (cpd.settings[UO_pos_bool].tp != TP_IGNORE)
      {
         newlines_chunk_pos(CT_BOOL, cpd.settings[UO_pos_bool].tp);
      }
      if (cpd.settings[UO_pos_compare].tp != TP_IGNORE)
      {
         newlines_chunk_pos(CT_COMPARE, cpd.settings[UO_pos_compare].tp);
      }
      if (cpd.settings[UO_pos_conditional].tp != TP_IGNORE)
      {
         newlines_chunk_pos(CT_COND_COLON, cpd.settings[UO_pos_conditional].tp);
         newlines_chunk_pos(CT_QUESTION, cpd.settings[UO_pos_conditional].tp);
      }
      if (cpd.settings[UO_pos_comma].tp != TP_IGNORE)
      {
         newlines_chunk_pos(CT_COMMA, cpd.settings[UO_pos_comma].tp);
      }
      if (cpd.settings[UO_pos_assign].tp != TP_IGNORE)
      {
         newlines_chunk_pos(CT_ASSIGN, cpd.settings[UO_pos_assign].tp);
      }
      if (cpd.settings[UO_pos_arith].tp != TP_IGNORE)
      {
         newlines_chunk_pos(CT_ARITH, cpd.settings[UO_pos_arith].tp);
      }
      newlines_class_colon_pos();
      if (cpd.settings[UO_nl_squeeze_ifdef].b)
      {
         newlines_squeeze_ifdef();
      }
      newlines_eat_start_end();
      newlines_cleanup_dup();

      mark_comments();

      /**
       * Add balanced spaces around nested params
       */
      if (cpd.settings[UO_sp_balance_nested_parens].b)
      {
         space_text_balance_nested_parens();
      }

      /* Scrub certain added semicolons */
      if (((cpd.lang_flags & LANG_PAWN) != 0) &&
          cpd.settings[UO_mod_pawn_semicolon].b)
      {
         pawn_scrub_vsemi();
      }

      /* Sort imports/using/include */
      if (cpd.settings[UO_mod_sort_import].b ||
          cpd.settings[UO_mod_sort_include].b ||
          cpd.settings[UO_mod_sort_using].b)
      {
         sort_imports();
      }

      /**
       * Fix same-line inter-chunk spacing
       */
      space_text();

      /**
       * Do any aligning of preprocessors
       */
      if (cpd.settings[UO_align_pp_define_span].n > 0)
      {
         align_preprocessor();
      }

      /**
       * Indent the text
       */
      indent_preproc();
      indent_text();

      /* Insert trailing comments after certain close braces */
      if ((cpd.settings[UO_mod_add_long_switch_closebrace_comment].n > 0) ||
          (cpd.settings[UO_mod_add_long_function_closebrace_comment].n > 0))
      {
         add_long_closebrace_comment();
      }

      /* Insert trailing comments after certain preprocessor conditional blocks */
      if ((cpd.settings[UO_mod_add_long_ifdef_else_comment].n > 0) ||
          (cpd.settings[UO_mod_add_long_ifdef_endif_comment].n > 0))
      {
         add_long_preprocessor_conditional_block_comment();
      }

      /**
       * Aligning everything else and reindent
       */
      align_all();
      indent_text();

      if (cpd.settings[UO_code_width].n > 0)
      {
         int max_passes = 3;
         int prev_changes;
         do
         {
            prev_changes = cpd.changes;
            do_code_width();
            if (prev_changes != cpd.changes)
            {
               align_all();
               indent_text();
            }
         } while ((prev_changes != cpd.changes) && (--max_passes > 0));
      }

      /**
       * And finally, align the backslash newline stuff
       */
      align_right_comments();
      if (cpd.settings[UO_align_nl_cont].b)
      {
         align_backslash_newline();
      }

      /**
       * Now render it all to the output file
       */
      output_text(pfout);
   }

   /* Special hook for dumping parsed data for debugging */
   if (parsed_file != NULL)
   {
      FILE *p_file = fopen(parsed_file, "w");
      if (p_file != NULL)
      {
         output_parsed(p_file);
         fclose(p_file);
      }
      else
      {
         LOG_FMT(LERR, "%s: Failed to open '%s' for write: %s (%d)\n",
                 __func__, parsed_file, strerror(errno), errno);
      }
   }

   uncrustify_end();
}