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(); }
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); }
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(); }