Пример #1
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();
}
Пример #2
0
int main(int argc, char *argv[])
{
   string     cfg_file;
   const char *parsed_file = NULL;
   const char *source_file = NULL;
   const char *output_file = NULL;
   const char *source_list = NULL;
   log_mask_t mask;
   int        idx;
   const char *p_arg;

   /* If ran without options... check keyword sort and show the usage info */
   if (argc == 1)
   {
      keywords_are_sorted();
      usage_exit(NULL, argv[0], EXIT_SUCCESS);
   }

   /* Build options map */
   register_options();

   Args arg(argc, argv);

   if (arg.Present("--version") || arg.Present("-v"))
   {
      version_exit();
   }
   if (arg.Present("--help") || arg.Present("-h") ||
       arg.Present("--usage") || arg.Present("-?"))
   {
      usage_exit(NULL, argv[0], EXIT_SUCCESS);
   }

   if (arg.Present("--show-config"))
   {
      print_options(stdout, true);
      return(0);
   }

#ifdef WIN32
   /* tell windoze not to change what I write to stdout */
   (void)_setmode(_fileno(stdout), _O_BINARY);
#endif

   /* Init logging */
   log_init(stderr);
   if (arg.Present("-q"))
   {
      logmask_from_string("", mask);
      log_set_mask(mask);
   }
   if (((p_arg = arg.Param("-L")) != NULL) ||
       ((p_arg = arg.Param("--log")) != NULL))
   {
      logmask_from_string(p_arg, mask);
      log_set_mask(mask);
   }
   cpd.frag = arg.Present("--frag");

   if ((p_arg = arg.Param("--decode")) != NULL)
   {
      log_pcf_flags(LSYS, strtoul(p_arg, NULL, 16));
      exit(EXIT_SUCCESS);
   }

   /* Get the config file name */
   if (((p_arg = arg.Param("--config")) != NULL) ||
       ((p_arg = arg.Param("-c")) != NULL))
   {
      cfg_file = p_arg;
   }

   /* Try to file a config at an alternate location */
   if (cfg_file.empty())
   {
      if (!unc_getenv("UNCRUSTIFY_CONFIG", cfg_file))
      {
         string home;

         if (unc_homedir(home))
         {
            struct stat tmp_stat;
            string      path;

            path = home + "/uncrustify.cfg";
            if (stat(path.c_str(), &tmp_stat) == 0)
            {
               cfg_file = path;
            }
            else
            {
               path = home + "/.uncrustify.cfg";
               if (stat(path.c_str(), &tmp_stat) == 0)
               {
                  cfg_file = path;
               }
            }
         }
      }
   }

   /* Get the parsed file name */
   if (((parsed_file = arg.Param("--parsed")) != NULL) ||
       ((parsed_file = arg.Param("-p")) != NULL))
   {
      LOG_FMT(LNOTE, "Will export parsed data to: %s\n", parsed_file);
   }

   /* Enable log sevs? */
   if (arg.Present("-s") || arg.Present("--show"))
   {
      log_show_sev(true);
   }

   /* Load the config file */
   set_option_defaults();

   /* Load type files */
   idx = 0;
   while ((p_arg = arg.Params("-t", idx)) != NULL)
   {
      load_keyword_file(p_arg);
   }

   /* add types */
   idx = 0;
   while ((p_arg = arg.Params("--type", idx)) != NULL)
   {
      add_keyword(p_arg, CT_TYPE);
   }

   /* Load define files */
   idx = 0;
   while ((p_arg = arg.Params("-d", idx)) != NULL)
   {
      load_define_file(p_arg);
   }

   /* add defines */
   idx = 0;
   while ((p_arg = arg.Params("--define", idx)) != NULL)
   {
      add_define(p_arg, NULL);
   }

   /* Check for a language override */
   if ((p_arg = arg.Param("-l")) != NULL)
   {
      cpd.lang_flags = language_from_tag(p_arg);
      if (cpd.lang_flags == 0)
      {
         LOG_FMT(LWARN, "Ignoring unknown language: %s\n", p_arg);
      }
      else
      {
         cpd.lang_forced = true;
      }
   }

   /* Get the source file name */
   if (((source_file = arg.Param("--file")) == NULL) &&
       ((source_file = arg.Param("-f")) == NULL))
   {
      // not using a single file, source_file is NULL
   }

   if (((source_list = arg.Param("--files")) == NULL) &&
       ((source_list = arg.Param("-F")) == NULL))
   {
      // not using a file list, source_list is NULL
   }

   const char *prefix = arg.Param("--prefix");
   const char *suffix = arg.Param("--suffix");

   bool no_backup        = arg.Present("--no-backup");
   bool replace          = arg.Present("--replace");
   bool keep_mtime       = arg.Present("--mtime");
   bool update_config    = arg.Present("--update-config");
   bool update_config_wd = arg.Present("--update-config-with-doc");
   bool detect           = arg.Present("--detect");

   /* Grab the output override */
   output_file = arg.Param("-o");

   LOG_FMT(LDATA, "config_file = %s\n", cfg_file.c_str());
   LOG_FMT(LDATA, "output_file = %s\n", (output_file != NULL) ? output_file : "null");
   LOG_FMT(LDATA, "source_file = %s\n", (source_file != NULL) ? source_file : "null");
   LOG_FMT(LDATA, "source_list = %s\n", (source_list != NULL) ? source_list : "null");
   LOG_FMT(LDATA, "prefix      = %s\n", (prefix != NULL) ? prefix : "null");
   LOG_FMT(LDATA, "suffix      = %s\n", (suffix != NULL) ? suffix : "null");
   LOG_FMT(LDATA, "replace     = %d\n", replace);
   LOG_FMT(LDATA, "no_backup   = %d\n", no_backup);
   LOG_FMT(LDATA, "detect      = %d\n", detect);

   if (replace || no_backup)
   {
      if ((prefix != NULL) || (suffix != NULL))
      {
         usage_exit("Cannot use --replace with --prefix or --suffix", argv[0], 66);
      }
      if ((source_file != NULL) || (output_file != NULL))
      {
         usage_exit("Cannot use --replace or --no-backup with -f or -o", argv[0], 66);
      }
   }
   else
   {
      if ((prefix == NULL) && (suffix == NULL))
      {
         suffix = ".uncrustify";
      }
   }

   /* Try to load the config file, if available.
    * It is optional for "--universalindent" and "--detect", but required for
    * everything else.
    */
   if (!cfg_file.empty())
   {
      cpd.filename = cfg_file.c_str();
      if (load_option_file(cpd.filename) < 0)
      {
         usage_exit("Unable to load the config file", argv[0], 56);
      }
   }

   if (arg.Present("--universalindent"))
   {
      FILE *pfile = stdout;

      if (output_file != NULL)
      {
         pfile = fopen(output_file, "w");
         if (pfile == NULL)
         {
            fprintf(stderr, "Unable to open %s for write: %s (%d)\n",
                    output_file, strerror(errno), errno);
            return(EXIT_FAILURE);
         }
      }

      print_universal_indent_cfg(pfile);

      return(EXIT_SUCCESS);
   }

   if (detect)
   {
      file_mem fm;

      if ((source_file == NULL) || (source_list != NULL))
      {
         fprintf(stderr, "The --detect option requires a single input file\n");
         return(EXIT_FAILURE);
      }

      /* Do some simple language detection based on the filename extension */
      if (!cpd.lang_forced || (cpd.lang_flags == 0))
      {
         cpd.lang_flags = language_from_filename(source_file);
      }

      /* Try to read in the source file */
      if (load_mem_file(source_file, fm) < 0)
      {
         LOG_FMT(LERR, "Failed to load (%s)\n", source_file);
         cpd.error_count++;
         return(EXIT_FAILURE);
      }

      uncrustify_start(fm.data);
      detect_options();
      uncrustify_end();

      redir_stdout(output_file);
      save_option_file(stdout, update_config_wd);
      return(EXIT_SUCCESS);
   }

   /* Everything beyond this point requires a config file, so complain and
    * bail if we don't have one.
    */
   if (cfg_file.empty())
   {
      usage_exit("Specify the config file with '-c file' or set UNCRUSTIFY_CONFIG",
                 argv[0], 58);
   }

   /*
    *  Done parsing args
    */

   if (update_config || update_config_wd)
   {
      redir_stdout(output_file);
      save_option_file(stdout, update_config_wd);
      return(0);
   }

   /* Check for unused args (ignore them) */
   idx   = 1;
   p_arg = arg.Unused(idx);

   /* Check args - for multifile options */
   if ((source_list != NULL) || (p_arg != NULL))
   {
      if (source_file != NULL)
      {
         usage_exit("Cannot specify both the single file option and a multi-file option.",
                    argv[0], 67);
      }

      if (output_file != NULL)
      {
         usage_exit("Cannot specify -o with a multi-file option.",
                    argv[0], 68);
      }
   }

   /* This relies on cpd.filename being the config file name */
   load_header_files();

   if ((source_file == NULL) && (source_list == NULL) && (p_arg == NULL))
   {
      /* no input specified, so use stdin */
      if (cpd.lang_flags == 0)
      {
         cpd.lang_flags = LANG_C;
      }

      redir_stdout(output_file);

      file_mem fm;
      if (!read_stdin(fm))
      {
         LOG_FMT(LERR, "Failed to read stdin\n");
         return(100);
      }

      cpd.filename = "stdin";

      /* Done reading from stdin */
      LOG_FMT(LSYS, "Parsing: %d bytes (%d chars) from stdin as language %s\n",
              (int)fm.raw.size(), (int)fm.data.size(),
              language_to_string(cpd.lang_flags));

      uncrustify_file(fm, stdout, parsed_file);
   }
   else if (source_file != NULL)
   {
      /* Doing a single file */
      do_source_file(source_file, output_file, parsed_file, no_backup, keep_mtime);
   }
   else
   {
      /* Doing multiple files */
      if (prefix != NULL)
      {
         LOG_FMT(LSYS, "Output prefix: %s/\n", prefix);
      }
      if (suffix != NULL)
      {
         LOG_FMT(LSYS, "Output suffix: %s\n", suffix);
      }

      /* Do the files on the command line first */
      idx = 1;
      while ((p_arg = arg.Unused(idx)) != NULL)
      {
         char outbuf[1024];
         do_source_file(p_arg,
                        make_output_filename(outbuf, sizeof(outbuf), p_arg, prefix, suffix),
                        NULL, no_backup, keep_mtime);
      }

      if (source_list != NULL)
      {
         process_source_list(source_list, prefix, suffix, no_backup, keep_mtime);
      }
   }

   clear_keyword_file();
   clear_defines();

   return((cpd.error_count != 0) ? 1 : 0);
}
Пример #3
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();
}