diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
commit | 931bffbda3668ddc609fc1da8f9eb576b170aa52 (patch) | |
tree | d8c1843a95da5ea0bb4acc09f7e37843d9995c86 /src/nvim/diff.c | |
parent | 142d9041391780ac15b89886a54015fdc5c73995 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-userreg.tar.gz rneovim-userreg.tar.bz2 rneovim-userreg.zip |
Merge remote-tracking branch 'upstream/master' into userreguserreg
Diffstat (limited to 'src/nvim/diff.c')
-rw-r--r-- | src/nvim/diff.c | 168 |
1 files changed, 81 insertions, 87 deletions
diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 032de561b3..0b7f6f266b 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1,6 +1,3 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - /// @file diff.c /// /// Code for diff'ing two, three or four buffers. @@ -19,9 +16,10 @@ #include <string.h> #include "auto/config.h" -#include "nvim/ascii.h" +#include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" +#include "nvim/bufwrite.h" #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -31,9 +29,10 @@ #include "nvim/ex_cmds.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" -#include "nvim/extmark_defs.h" +#include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" @@ -46,17 +45,18 @@ #include "nvim/move.h" #include "nvim/normal.h" #include "nvim/option.h" +#include "nvim/option_vars.h" #include "nvim/optionstr.h" -#include "nvim/os/fs_defs.h" +#include "nvim/os/fs.h" #include "nvim/os/os.h" #include "nvim/os/shell.h" #include "nvim/path.h" -#include "nvim/pos.h" +#include "nvim/pos_defs.h" #include "nvim/strings.h" -#include "nvim/types.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/undo.h" -#include "nvim/vim.h" +#include "nvim/vim_defs.h" #include "nvim/window.h" #include "xdiff/xdiff.h" @@ -80,7 +80,7 @@ static bool diff_need_update = false; // ex_diffupdate needs to be called #define ALL_WHITE_DIFF (DIFF_IWHITE | DIFF_IWHITEALL | DIFF_IWHITEEOL) static int diff_flags = DIFF_INTERNAL | DIFF_FILLER | DIFF_CLOSE_OFF; -static long diff_algorithm = 0; +static int diff_algorithm = 0; static int linematch_lines = 0; #define LBUFLEN 50 // length of line in diff file @@ -104,9 +104,9 @@ typedef struct { // used for recording hunks from xdiff typedef struct { linenr_T lnum_orig; - long count_orig; + int count_orig; linenr_T lnum_new; - long count_new; + int count_new; } diffhunk_T; // two diff inputs and one result @@ -264,24 +264,25 @@ void diff_invalidate(buf_T *buf) } } -/// Called by mark_adjust(): update line numbers in "curbuf". +/// Called by mark_adjust(): update line numbers in "buf". /// /// @param line1 /// @param line2 /// @param amount /// @param amount_after -void diff_mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after) +void diff_mark_adjust(buf_T *buf, linenr_T line1, linenr_T line2, linenr_T amount, + linenr_T amount_after) { - // Handle all tab pages that use the current buffer in a diff. + // Handle all tab pages that use "buf" in a diff. FOR_ALL_TABS(tp) { - int idx = diff_buf_idx_tp(curbuf, tp); + int idx = diff_buf_idx_tp(buf, tp); if (idx != DB_COUNT) { diff_mark_adjust_tp(tp, idx, line1, line2, amount, amount_after); } } } -/// Update line numbers in tab page "tp" for "curbuf" with index "idx". +/// Update line numbers in tab page "tp" for the buffer with index "idx". /// /// This attempts to update the changes as much as possible: /// When inserting/deleting lines outside of existing change blocks, create a @@ -326,7 +327,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, linenr_T diff_T *dp = tp->tp_first_diff; linenr_T lnum_deleted = line1; // lnum of remaining deletion - for (;;) { + while (true) { // If the change is after the previous diff block and before the next // diff block, thus not touching an existing change, create a new diff // block. Don't do this when ex_diffgetput() is busy. @@ -340,8 +341,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, linenr_T dnext->df_lnum[idx] = line1; dnext->df_count[idx] = inserted; - int i; - for (i = 0; i < DB_COUNT; i++) { + for (int i = 0; i < DB_COUNT; i++) { if ((tp->tp_diffbuf[i] != NULL) && (i != idx)) { if (dprev == NULL) { dnext->df_lnum[i] = line1; @@ -472,8 +472,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, linenr_T // check if this block touches the previous one, may merge them. if ((dprev != NULL) && !dp->is_linematched && (dprev->df_lnum[idx] + dprev->df_count[idx] == dp->df_lnum[idx])) { - int i; - for (i = 0; i < DB_COUNT; i++) { + for (int i = 0; i < DB_COUNT; i++) { if (tp->tp_diffbuf[i] != NULL) { dprev->df_count[i] += dp->df_count[i]; } @@ -586,7 +585,7 @@ static void diff_check_unchanged(tabpage_T *tp, diff_T *dp) linenr_T off_org = 0; linenr_T off_new = 0; int dir = FORWARD; - for (;;) { + while (true) { // Repeat until a line is found which is different or the number of // lines has become zero. while (dp->df_count[i_org] > 0) { @@ -594,9 +593,7 @@ static void diff_check_unchanged(tabpage_T *tp, diff_T *dp) if (dir == BACKWARD) { off_org = dp->df_count[i_org] - 1; } - char *line_org = xstrdup(ml_get_buf(tp->tp_diffbuf[i_org], - dp->df_lnum[i_org] + off_org, - false)); + char *line_org = xstrdup(ml_get_buf(tp->tp_diffbuf[i_org], dp->df_lnum[i_org] + off_org)); int i_new; for (i_new = i_org + 1; i_new < DB_COUNT; i_new++) { @@ -614,8 +611,7 @@ static void diff_check_unchanged(tabpage_T *tp, diff_T *dp) } if (diff_cmp(line_org, ml_get_buf(tp->tp_diffbuf[i_new], - dp->df_lnum[i_new] + off_new, - false)) != 0) { + dp->df_lnum[i_new] + off_new)) != 0) { break; } } @@ -754,7 +750,7 @@ static int diff_write_buffer(buf_T *buf, mmfile_t *m, linenr_T start, linenr_T e // xdiff requires one big block of memory with all the text. for (linenr_T lnum = start; lnum <= end; lnum++) { - len += strlen(ml_get_buf(buf, lnum, false)) + 1; + len += strlen(ml_get_buf(buf, lnum)) + 1; } char *ptr = try_malloc(len); if (ptr == NULL) { @@ -764,18 +760,18 @@ static int diff_write_buffer(buf_T *buf, mmfile_t *m, linenr_T start, linenr_T e buf->b_diff_failed = true; if (p_verbose > 0) { verbose_enter(); - smsg(_("Not enough memory to use internal diff for buffer \"%s\""), + smsg(0, _("Not enough memory to use internal diff for buffer \"%s\""), buf->b_fname); verbose_leave(); } return FAIL; } m->ptr = ptr; - m->size = (long)len; + m->size = (int)len; len = 0; for (linenr_T lnum = start; lnum <= end; lnum++) { - char *s = ml_get_buf(buf, lnum, false); + char *s = ml_get_buf(buf, lnum); if (diff_flags & DIFF_ICASE) { while (*s != NUL) { char cbuf[MB_MAXBYTES + 1]; @@ -824,7 +820,7 @@ static int diff_write(buf_T *buf, diffin_T *din) // so it shouldn't update the '[ and '] marks. cmdmod.cmod_flags |= CMOD_LOCKMARKS; int r = buf_write(buf, din->din_fname, NULL, - (linenr_T)1, buf->b_ml.ml_line_count, + 1, buf->b_ml.ml_line_count, NULL, false, false, false, true); cmdmod.cmod_flags = save_cmod_flags; free_string_option(buf->b_p_ff); @@ -1010,7 +1006,7 @@ static int check_external_diff(diffio_T *diffio) // May try twice, first with "-a" and then without. int io_error = false; TriState ok = kFalse; - for (;;) { + while (true) { ok = kFalse; FILE *fd = os_fopen(diffio->dio_orig.din_fname, "w"); @@ -1040,7 +1036,7 @@ static int check_external_diff(diffio_T *diffio) } else { char linebuf[LBUFLEN]; - for (;;) { + while (true) { // For normal diff there must be a line that contains // "1c1". For unified diff "@@ -1 +1 @@". if (vim_fgets(linebuf, LBUFLEN, fd)) { @@ -1208,7 +1204,7 @@ void ex_diffpatch(exarg_T *eap) // Write the current buffer to "tmp_orig". if (buf_write(curbuf, tmp_orig, NULL, - (linenr_T)1, curbuf->b_ml.ml_line_count, + 1, curbuf->b_ml.ml_line_count, NULL, false, false, false, true) == FAIL) { goto theend; } @@ -1387,14 +1383,14 @@ void ex_diffthis(exarg_T *eap) diff_win_options(curwin, true); } -static void set_diff_option(win_T *wp, int value) +static void set_diff_option(win_T *wp, bool value) { win_T *old_curwin = curwin; curwin = wp; curbuf = curwin->w_buffer; curbuf->b_ro_locked++; - set_option_value_give_err("diff", (long)value, NULL, OPT_LOCAL); + set_option_value_give_err("diff", BOOLEAN_OPTVAL(value), OPT_LOCAL); curbuf->b_ro_locked--; curwin = old_curwin; curbuf = curwin->w_buffer; @@ -1558,7 +1554,7 @@ static bool extract_hunk_internal(diffout_T *dout, diffhunk_T *hunk, int *line_i // Extract hunk by parsing the diff output from file and calculate the diffstyle. static bool extract_hunk(FILE *fd, diffhunk_T *hunk, diffstyle_T *diffstyle) { - for (;;) { + while (true) { char line[LBUFLEN]; // only need to hold the diff line if (vim_fgets(line, LBUFLEN, fd)) { return true; // end of file @@ -1579,10 +1575,10 @@ static bool extract_hunk(FILE *fd, diffhunk_T *hunk, diffstyle_T *diffstyle) *diffstyle = DIFF_ED; } else if ((strncmp(line, "@@ ", 3) == 0)) { *diffstyle = DIFF_UNIFIED; - } else if ((strncmp(line, "--- ", 4) == 0) // -V501 - && (vim_fgets(line, LBUFLEN, fd) == 0) // -V501 + } else if ((strncmp(line, "--- ", 4) == 0) + && (vim_fgets(line, LBUFLEN, fd) == 0) && (strncmp(line, "+++ ", 4) == 0) - && (vim_fgets(line, LBUFLEN, fd) == 0) // -V501 + && (vim_fgets(line, LBUFLEN, fd) == 0) && (strncmp(line, "@@ ", 3) == 0)) { *diffstyle = DIFF_UNIFIED; } else { @@ -1745,7 +1741,7 @@ static void diff_read(int idx_orig, int idx_new, diffio_T *dio) } } - for (;;) { + while (true) { diffhunk_T hunk = { 0 }; bool eof = dio->dio_internal ? extract_hunk_internal(dout, &hunk, &line_idx) @@ -2242,11 +2238,9 @@ static bool diff_equal_entry(diff_T *dp, int idx1, int idx2) } for (int i = 0; i < dp->df_count[idx1]; i++) { - char *line = xstrdup(ml_get_buf(curtab->tp_diffbuf[idx1], - dp->df_lnum[idx1] + i, false)); + char *line = xstrdup(ml_get_buf(curtab->tp_diffbuf[idx1], dp->df_lnum[idx1] + i)); - int cmp = diff_cmp(line, ml_get_buf(curtab->tp_diffbuf[idx2], - dp->df_lnum[idx2] + i, false)); + int cmp = diff_cmp(line, ml_get_buf(curtab->tp_diffbuf[idx2], dp->df_lnum[idx2] + i)); xfree(line); if (cmp != 0) { @@ -2382,7 +2376,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin) towin->w_topline = lnum + (dp->df_lnum[toidx] - dp->df_lnum[fromidx]); if (lnum >= dp->df_lnum[fromidx]) { - if (diff_flags & DIFF_LINEMATCH) { + if (dp->is_linematched) { calculate_topfill_and_topline(fromidx, toidx, fromwin->w_topline, fromwin->w_topfill, &towin->w_topfill, &towin->w_topline); } else { @@ -2447,7 +2441,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin) } // When w_topline changes need to recompute w_botline and cursor position - invalidate_botline_win(towin); + invalidate_botline(towin); changed_line_abv_curs_win(towin); check_topfill(towin, false); @@ -2464,11 +2458,12 @@ int diffopt_changed(void) int linematch_lines_new = 0; int diff_flags_new = 0; int diff_foldcolumn_new = 2; - long diff_algorithm_new = 0; - long diff_indent_heuristic = 0; + int diff_algorithm_new = 0; + int diff_indent_heuristic = 0; char *p = p_dip; while (*p != NUL) { + // Note: Keep this in sync with p_dip_values if (strncmp(p, "filler", 6) == 0) { p += 6; diff_flags_new |= DIFF_FILLER; @@ -2515,6 +2510,7 @@ int diffopt_changed(void) p += 8; diff_flags_new |= DIFF_INTERNAL; } else if (strncmp(p, "algorithm:", 10) == 0) { + // Note: Keep this in sync with p_dip_algorithm_values. p += 10; if (strncmp(p, "myers", 5) == 0) { p += 5; @@ -2571,7 +2567,7 @@ int diffopt_changed(void) // recompute the scroll binding with the new option value, may // remove or add filler lines - check_scrollbind((linenr_T)0, 0L); + check_scrollbind(0, 0); return OK; } @@ -2615,7 +2611,7 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { // Make a copy of the line, the next ml_get() will invalidate it. - char *line_org = xstrdup(ml_get_buf(wp->w_buffer, lnum, false)); + char *line_org = xstrdup(ml_get_buf(wp->w_buffer, lnum)); int idx = diff_buf_idx(wp->w_buffer); if (idx == DB_COUNT) { @@ -2652,15 +2648,14 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) bool added = true; linenr_T off = lnum - dp->df_lnum[idx]; - int i; - for (i = 0; i < DB_COUNT; i++) { + for (int i = 0; i < DB_COUNT; i++) { if ((curtab->tp_diffbuf[i] != NULL) && (i != idx)) { // Skip lines that are not in the other change (filler lines). if (off >= dp->df_count[i]) { continue; } added = false; - char *line_new = ml_get_buf(curtab->tp_diffbuf[i], dp->df_lnum[i] + off, false); + char *line_new = ml_get_buf(curtab->tp_diffbuf[i], dp->df_lnum[i] + off); // Search for start of difference si_org = si_new = 0; @@ -2951,7 +2946,7 @@ void ex_diffgetput(exarg_T *eap) } const int idx_from = eap->cmdidx == CMD_diffget ? idx_other : idx_cur; - const int idx_to = eap->cmdidx == CMD_diffget ? idx_cur : idx_other; + const int idx_to = eap->cmdidx == CMD_diffget ? idx_cur : idx_other; // May give the warning for a changed buffer here, which can trigger the // FileChangedRO autocommand, which may do nasty things and mess @@ -3096,15 +3091,18 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr if (nr > curtab->tp_diffbuf[idx_from]->b_ml.ml_line_count) { break; } - char *p = xstrdup(ml_get_buf(curtab->tp_diffbuf[idx_from], nr, false)); + char *p = xstrdup(ml_get_buf(curtab->tp_diffbuf[idx_from], nr)); ml_append(lnum + i - 1, p, 0, false); xfree(p); added++; if (buf_empty && (curbuf->b_ml.ml_line_count == 2)) { // Added the first line into an empty buffer, need to // delete the dummy empty line. + // This has a side effect of incrementing curbuf->deleted_bytes, + // which results in inaccurate reporting of the byte count of + // previous contents in buffer-update events. buf_empty = false; - ml_delete((linenr_T)2, false); + ml_delete(2, false); } } linenr_T new_count = dp->df_count[idx_to] + added; @@ -3133,7 +3131,7 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr if (added != 0) { // Adjust marks. This will change the following entries! - mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, added, kExtmarkUndo); + mark_adjust(lnum, lnum + count - 1, MAXLNUM, added, kExtmarkNOOP); if (curwin->w_cursor.lnum >= lnum) { // Adjust the cursor position if it's in/after the changed // lines. @@ -3144,7 +3142,8 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr } } } - changed_lines(lnum, 0, lnum + count, added, true); + extmark_adjust(curbuf, lnum, lnum + count - 1, MAXLNUM, added, kExtmarkUndo); + changed_lines(curbuf, lnum, 0, lnum + count, added, true); if (did_free) { // Diff is deleted, update folds in other windows. @@ -3214,7 +3213,7 @@ bool diff_mode_buf(buf_T *buf) /// @param count /// /// @return FAIL if there isn't such a diff block. -int diff_move_to(int dir, long count) +int diff_move_to(int dir, int count) { linenr_T lnum = curwin->w_cursor.lnum; int idx = diff_buf_idx(curbuf); @@ -3357,7 +3356,7 @@ linenr_T diff_lnum_win(linenr_T lnum, win_T *wp) if (idx == DB_COUNT) { // safety check - return (linenr_T)0; + return 0; } if (curtab->tp_diff_invalid) { @@ -3383,7 +3382,7 @@ linenr_T diff_lnum_win(linenr_T lnum, win_T *wp) if (i == DB_COUNT) { // safety check - return (linenr_T)0; + return 0; } linenr_T n = lnum + (dp->df_lnum[i] - dp->df_lnum[idx]); @@ -3393,13 +3392,12 @@ linenr_T diff_lnum_win(linenr_T lnum, win_T *wp) return n; } -/// /// Handle an ED style diff line. -/// Return FAIL if the line does not contain diff info. /// +/// @return FAIL if the line does not contain diff info. static int parse_diff_ed(char *line, diffhunk_T *hunk) { - long l1, l2; + int l1, l2; // The line must be one of three formats: // change: {first}[,{last}]c{first}[,{last}] @@ -3409,7 +3407,7 @@ static int parse_diff_ed(char *line, diffhunk_T *hunk) linenr_T f1 = getdigits_int32(&p, true, 0); if (*p == ',') { p++; - l1 = getdigits(&p, true, 0); + l1 = getdigits_int(&p, true, 0); } else { l1 = f1; } @@ -3417,10 +3415,10 @@ static int parse_diff_ed(char *line, diffhunk_T *hunk) return FAIL; // invalid diff format } int difftype = (uint8_t)(*p++); - long f2 = getdigits(&p, true, 0); + int f2 = getdigits_int(&p, true, 0); if (*p == ',') { p++; - l2 = getdigits(&p, true, 0); + l2 = getdigits_int(&p, true, 0); } else { l2 = f2; } @@ -3445,31 +3443,29 @@ static int parse_diff_ed(char *line, diffhunk_T *hunk) return OK; } -/// /// Parses unified diff with zero(!) context lines. /// Return FAIL if there is no diff information in "line". -/// static int parse_diff_unified(char *line, diffhunk_T *hunk) { // Parse unified diff hunk header: // @@ -oldline,oldcount +newline,newcount @@ char *p = line; if (*p++ == '@' && *p++ == '@' && *p++ == ' ' && *p++ == '-') { - long oldcount; - long newline; - long newcount; - long oldline = getdigits(&p, true, 0); + int oldcount; + linenr_T newline; + int newcount; + linenr_T oldline = getdigits_int32(&p, true, 0); if (*p == ',') { p++; - oldcount = getdigits(&p, true, 0); + oldcount = getdigits_int(&p, true, 0); } else { oldcount = 1; } if (*p++ == ' ' && *p++ == '+') { - newline = getdigits(&p, true, 0); + newline = getdigits_int(&p, true, 0); if (*p == ',') { p++; - newcount = getdigits(&p, true, 0); + newcount = getdigits_int(&p, true, 0); } else { newcount = 1; } @@ -3487,9 +3483,9 @@ static int parse_diff_unified(char *line, diffhunk_T *hunk) newline = 1; } - hunk->lnum_orig = (linenr_T)oldline; + hunk->lnum_orig = oldline; hunk->count_orig = oldcount; - hunk->lnum_new = (linenr_T)newline; + hunk->lnum_new = newline; hunk->count_new = newcount; return OK; @@ -3498,18 +3494,16 @@ static int parse_diff_unified(char *line, diffhunk_T *hunk) return FAIL; } -/// /// Callback function for the xdl_diff() function. /// Stores the diff output in a grow array. -/// -static int xdiff_out(long start_a, long count_a, long start_b, long count_b, void *priv) +static int xdiff_out(int start_a, int count_a, int start_b, int count_b, void *priv) { diffout_T *dout = (diffout_T *)priv; GA_APPEND(diffhunk_T, &(dout->dout_ga), ((diffhunk_T){ - .lnum_orig = (linenr_T)start_a + 1, + .lnum_orig = (linenr_T)start_a + 1, .count_orig = count_a, - .lnum_new = (linenr_T)start_b + 1, - .count_new = count_b, + .lnum_new = (linenr_T)start_b + 1, + .count_new = count_b, })); return 0; } |