mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
+14
-1
@@ -1112,6 +1112,9 @@ au BufNewFile,BufRead *.ldif setf ldif
|
||||
" Ld loader
|
||||
au BufNewFile,BufRead *.ld setf ld
|
||||
|
||||
" Lean
|
||||
au BufNewFile,BufRead *.lean setf lean
|
||||
|
||||
" Ledger
|
||||
au BufRead,BufNewFile *.ldg,*.ledger,*.journal setf ledger
|
||||
|
||||
@@ -1396,6 +1399,9 @@ au BufNewFile,BufRead *.nse setf lua
|
||||
" NSIS
|
||||
au BufNewFile,BufRead *.nsi,*.nsh setf nsis
|
||||
|
||||
" Nu
|
||||
au BufNewFile,BufRead {env,config}.nu setf nu
|
||||
|
||||
" Oblivion Language and Oblivion Script Extender
|
||||
au BufNewFile,BufRead *.obl,*.obse,*.oblivion,*.obscript setf obse
|
||||
|
||||
@@ -1805,6 +1811,9 @@ au BufNewFile,BufRead Cargo.lock,*/.cargo/config,*/.cargo/credentials setf toml
|
||||
" S-lang (or shader language, or SmallLisp)
|
||||
au BufNewFile,BufRead *.sl setf slang
|
||||
|
||||
" Sage
|
||||
au BufNewFile,BufRead *.sage setf sage
|
||||
|
||||
" Samba config
|
||||
au BufNewFile,BufRead smb.conf setf samba
|
||||
|
||||
@@ -2334,7 +2343,11 @@ au BufNewFile,BufRead *.vroom setf vroom
|
||||
au BufNewFile,BufRead *.vue setf vue
|
||||
|
||||
" WebAssembly
|
||||
au BufNewFile,BufRead *.wast,*.wat setf wast
|
||||
au BufNewFile,BufRead *.wat setf wat
|
||||
au BufNewFile,BufRead *.wast setf wast
|
||||
|
||||
" WebAssembly Interface Type (WIT)
|
||||
au BufNewFile,BufRead *.wit setf wit
|
||||
|
||||
" Webmacro
|
||||
au BufNewFile,BufRead *.wm setf webmacro
|
||||
|
||||
+3
-1
@@ -769,7 +769,9 @@ cin_is_cpp_namespace(char_u *s)
|
||||
|
||||
s = cin_skipcomment(s);
|
||||
|
||||
if (STRNCMP(s, "inline", 6) == 0 && (s[6] == NUL || !vim_iswordc(s[6])))
|
||||
// skip over "inline" and "export" in any order
|
||||
while ((STRNCMP(s, "inline", 6) == 0 || STRNCMP(s, "export", 6) == 0)
|
||||
&& (s[6] == NUL || !vim_iswordc(s[6])))
|
||||
s = cin_skipcomment(skipwhite(s + 6));
|
||||
|
||||
if (STRNCMP(s, "namespace", 9) == 0 && (s[9] == NUL || !vim_iswordc(s[9])))
|
||||
|
||||
+4
-3
@@ -2447,12 +2447,12 @@ stop_insert(
|
||||
* otherwise CTRL-O w and then <Left> will clear "last_insert".
|
||||
*/
|
||||
ptr = get_inserted();
|
||||
if (did_restart_edit == 0 || (ptr != NULL
|
||||
&& (int)STRLEN(ptr) > new_insert_skip))
|
||||
int added = ptr == NULL ? 0 : (int)STRLEN(ptr) - new_insert_skip;
|
||||
if (did_restart_edit == 0 || added > 0)
|
||||
{
|
||||
vim_free(last_insert);
|
||||
last_insert = ptr;
|
||||
last_insert_skip = new_insert_skip;
|
||||
last_insert_skip = added < 0 ? 0 : new_insert_skip;
|
||||
}
|
||||
else
|
||||
vim_free(ptr);
|
||||
@@ -3697,6 +3697,7 @@ ins_esc(
|
||||
else
|
||||
{
|
||||
--curwin->w_cursor.col;
|
||||
curwin->w_valid &= ~(VALID_WCOL|VALID_VIRTCOL);
|
||||
// Correct cursor for multi-byte character.
|
||||
if (has_mbyte)
|
||||
mb_adjust_cursor();
|
||||
|
||||
+5
-1
@@ -320,7 +320,7 @@ main
|
||||
params.want_full_screen = FALSE;
|
||||
|
||||
/*
|
||||
* When certain to start the GUI, don't check capabilities of terminal.
|
||||
* When certain to start the GUI, don't check terminal capabilities.
|
||||
* For GTK we can't be sure, but when started from the desktop it doesn't
|
||||
* make sense to try using a terminal.
|
||||
*/
|
||||
@@ -1360,7 +1360,11 @@ main_loop(
|
||||
* update cursor and redraw.
|
||||
*/
|
||||
if (skip_redraw || exmode_active)
|
||||
{
|
||||
skip_redraw = FALSE;
|
||||
setcursor();
|
||||
cursor_on();
|
||||
}
|
||||
else if (do_redraw || stuff_empty())
|
||||
{
|
||||
#ifdef FEAT_GUI
|
||||
|
||||
@@ -436,21 +436,13 @@ static enum
|
||||
|
||||
static char *pexpand_cmds[] = {
|
||||
"start",
|
||||
#define PROFCMD_START 0
|
||||
"stop",
|
||||
#define PROFCMD_STOP 1
|
||||
"pause",
|
||||
#define PROFCMD_PAUSE 2
|
||||
"continue",
|
||||
#define PROFCMD_CONTINUE 3
|
||||
"func",
|
||||
#define PROFCMD_FUNC 4
|
||||
"file",
|
||||
#define PROFCMD_DUMP 5
|
||||
"dump",
|
||||
#define PROFCMD_FILE 6
|
||||
NULL
|
||||
#define PROFCMD_LAST 7
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+3
-1
@@ -6678,7 +6678,9 @@ nfa_regmatch(
|
||||
int subidx;
|
||||
int bytelen;
|
||||
|
||||
if (t->state->c <= NFA_BACKREF9)
|
||||
#ifdef FEAT_SYN_HL
|
||||
if (t->state->c >= NFA_BACKREF1 && t->state->c <= NFA_BACKREF9)
|
||||
#endif
|
||||
{
|
||||
subidx = t->state->c - NFA_BACKREF1 + 1;
|
||||
result = match_backref(&t->subs.norm, subidx, &bytelen);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
>:+0&#ffffff0| @58
|
||||
|~+0#4040ff13&| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
|~| @58
|
||||
| +0#0000000&@59
|
||||
@@ -4406,6 +4406,18 @@ def Test_cindent_47()
|
||||
inline/* test */namespace {
|
||||
111111111111111111;
|
||||
}
|
||||
export namespace {
|
||||
111111111111111111;
|
||||
}
|
||||
export inline namespace {
|
||||
111111111111111111;
|
||||
}
|
||||
export/* test */inline namespace {
|
||||
111111111111111111;
|
||||
}
|
||||
inline export namespace {
|
||||
111111111111111111;
|
||||
}
|
||||
|
||||
/* invalid namespaces use block indent */
|
||||
namespace test test2 {
|
||||
@@ -4509,6 +4521,18 @@ def Test_cindent_47()
|
||||
inline/* test */namespace {
|
||||
111111111111111111;
|
||||
}
|
||||
export namespace {
|
||||
111111111111111111;
|
||||
}
|
||||
export inline namespace {
|
||||
111111111111111111;
|
||||
}
|
||||
export/* test */inline namespace {
|
||||
111111111111111111;
|
||||
}
|
||||
inline export namespace {
|
||||
111111111111111111;
|
||||
}
|
||||
|
||||
/* invalid namespaces use block indent */
|
||||
namespace test test2 {
|
||||
|
||||
@@ -5,6 +5,7 @@ if exists("+t_kD")
|
||||
endif
|
||||
|
||||
source check.vim
|
||||
source screendump.vim
|
||||
|
||||
" Needed for testing basic rightleft: Test_edit_rightleft
|
||||
source view_util.vim
|
||||
@@ -1960,6 +1961,22 @@ func Test_edit_insert_reg()
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for positioning cursor after CTRL-R expression failed
|
||||
func Test_edit_ctrl_r_failed()
|
||||
CheckRunVimInTerminal
|
||||
|
||||
let buf = RunVimInTerminal('', #{rows: 6, cols: 60})
|
||||
|
||||
" trying to insert a dictionary produces an error
|
||||
call term_sendkeys(buf, "i\<C-R>={}\<CR>")
|
||||
|
||||
" ending Insert mode should put the cursor back on the ':'
|
||||
call term_sendkeys(buf, ":\<Esc>")
|
||||
call VerifyScreenDump(buf, 'Test_edit_ctlr_r_failed_1', {})
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
" When a character is inserted at the last position of the last line in a
|
||||
" window, the window contents should be scrolled one line up. If the top line
|
||||
" is part of a fold, then the entire fold should be scrolled up.
|
||||
|
||||
@@ -320,6 +320,7 @@ let s:filename_checks = {
|
||||
\ 'latte': ['file.latte', 'file.lte'],
|
||||
\ 'ld': ['file.ld'],
|
||||
\ 'ldif': ['file.ldif'],
|
||||
\ 'lean': ['file.lean'],
|
||||
\ 'ledger': ['file.ldg', 'file.ledger', 'file.journal'],
|
||||
\ 'less': ['file.less'],
|
||||
\ 'lex': ['file.lex', 'file.l', 'file.lxx', 'file.l++'],
|
||||
@@ -411,6 +412,7 @@ let s:filename_checks = {
|
||||
\ 'nqc': ['file.nqc'],
|
||||
\ 'nroff': ['file.tr', 'file.nr', 'file.roff', 'file.tmac', 'file.mom', 'tmac.file'],
|
||||
\ 'nsis': ['file.nsi', 'file.nsh'],
|
||||
\ 'nu': ['env.nu', 'config.nu'],
|
||||
\ 'obj': ['file.obj'],
|
||||
\ 'obse': ['file.obl', 'file.obse', 'file.oblivion', 'file.obscript'],
|
||||
\ 'ocaml': ['file.ml', 'file.mli', 'file.mll', 'file.mly', '.ocamlinit', 'file.mlt', 'file.mlp', 'file.mlip', 'file.mli.cppo', 'file.ml.cppo'],
|
||||
@@ -538,6 +540,7 @@ let s:filename_checks = {
|
||||
\ 'skill': ['file.il', 'file.ils', 'file.cdf'],
|
||||
\ 'cdc': ['file.cdc'],
|
||||
\ 'slang': ['file.sl'],
|
||||
\ 'sage': ['file.sage'],
|
||||
\ 'slice': ['file.ice'],
|
||||
\ 'slpconf': ['/etc/slp.conf', 'any/etc/slp.conf'],
|
||||
\ 'slpreg': ['/etc/slp.reg', 'any/etc/slp.reg'],
|
||||
@@ -654,12 +657,14 @@ let s:filename_checks = {
|
||||
\ 'vrml': ['file.wrl'],
|
||||
\ 'vroom': ['file.vroom'],
|
||||
\ 'vue': ['file.vue'],
|
||||
\ 'wast': ['file.wast', 'file.wat'],
|
||||
\ 'wat': ['file.wat'],
|
||||
\ 'wast': ['file.wast'],
|
||||
\ 'wdl': ['file.wdl'],
|
||||
\ 'webmacro': ['file.wm'],
|
||||
\ 'wget': ['.wgetrc', 'wgetrc'],
|
||||
\ 'wget2': ['.wget2rc', 'wget2rc'],
|
||||
\ 'winbatch': ['file.wbt'],
|
||||
\ 'wit': ['file.wit'],
|
||||
\ 'wml': ['file.wml'],
|
||||
\ 'wsh': ['file.wsf', 'file.wsc'],
|
||||
\ 'wsml': ['file.wsml'],
|
||||
|
||||
@@ -710,6 +710,30 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1429,
|
||||
/**/
|
||||
1428,
|
||||
/**/
|
||||
1427,
|
||||
/**/
|
||||
1426,
|
||||
/**/
|
||||
1425,
|
||||
/**/
|
||||
1424,
|
||||
/**/
|
||||
1423,
|
||||
/**/
|
||||
1422,
|
||||
/**/
|
||||
1421,
|
||||
/**/
|
||||
1420,
|
||||
/**/
|
||||
1419,
|
||||
/**/
|
||||
1418,
|
||||
/**/
|
||||
1417,
|
||||
/**/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The files in this directory come from the xdiff implementation in git.
|
||||
You can find it here: https://github.com/git/git/tree/master/xdiff
|
||||
The files were last updated August 31, 2021 from git release v.2.33.0
|
||||
The files were last updated March 17, 2023 from git release v.2.40.0
|
||||
|
||||
This is originally based on libxdiff, which can be found here:
|
||||
http://www.xmailserver.org/xdiff-lib.html
|
||||
|
||||
@@ -66,6 +66,7 @@ extern "C" {
|
||||
|
||||
/* merge output styles */
|
||||
#define XDL_MERGE_DIFF3 1
|
||||
#define XDL_MERGE_ZEALOUS_DIFF3 2
|
||||
|
||||
typedef struct s_mmfile {
|
||||
char *ptr;
|
||||
@@ -126,6 +127,7 @@ typedef struct s_bdiffparam {
|
||||
#endif
|
||||
|
||||
#define xdl_malloc(x) lalloc((x), TRUE)
|
||||
#define xdl_calloc(n, sz) lalloc_clear(n*sz, TRUE)
|
||||
#define xdl_free(ptr) vim_free(ptr)
|
||||
#define xdl_realloc(ptr,x) vim_realloc((ptr),(x))
|
||||
|
||||
|
||||
+29
-31
@@ -315,16 +315,19 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
long *kvd, *kvdf, *kvdb;
|
||||
xdalgoenv_t xenv;
|
||||
diffdata_t dd1, dd2;
|
||||
int res;
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF)
|
||||
return xdl_do_patience_diff(mf1, mf2, xpp, xe);
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
|
||||
return xdl_do_histogram_diff(mf1, mf2, xpp, xe);
|
||||
|
||||
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {
|
||||
|
||||
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0)
|
||||
return -1;
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF) {
|
||||
res = xdl_do_patience_diff(xpp, xe);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF) {
|
||||
res = xdl_do_histogram_diff(xpp, xe);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -334,7 +337,7 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
* One is to store the forward path and one to store the backward path.
|
||||
*/
|
||||
ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
|
||||
if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {
|
||||
if (!XDL_ALLOC_ARRAY(kvd, 2 * ndiags + 2)) {
|
||||
|
||||
xdl_free_env(xe);
|
||||
return -1;
|
||||
@@ -359,17 +362,15 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
dd2.rchg = xe->xdf2.rchg;
|
||||
dd2.rindex = xe->xdf2.rindex;
|
||||
|
||||
if (xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
|
||||
kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0, &xenv) < 0) {
|
||||
|
||||
xdl_free(kvd);
|
||||
xdl_free_env(xe);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
|
||||
kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0,
|
||||
&xenv);
|
||||
xdl_free(kvd);
|
||||
out:
|
||||
if (res < 0)
|
||||
xdl_free_env(xe);
|
||||
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -390,12 +391,9 @@ static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1,
|
||||
}
|
||||
|
||||
|
||||
static int recs_match(xrecord_t *rec1, xrecord_t *rec2, long flags)
|
||||
static int recs_match(xrecord_t *rec1, xrecord_t *rec2)
|
||||
{
|
||||
return (rec1->ha == rec2->ha &&
|
||||
xdl_recmatch(rec1->ptr, rec1->size,
|
||||
rec2->ptr, rec2->size,
|
||||
flags));
|
||||
return (rec1->ha == rec2->ha);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -759,10 +757,10 @@ static inline int group_previous(xdfile_t *xdf, struct xdlgroup *g)
|
||||
* following group, expand this group to include it. Return 0 on success or -1
|
||||
* if g cannot be slid down.
|
||||
*/
|
||||
static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g, long flags)
|
||||
static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g)
|
||||
{
|
||||
if (g->end < xdf->nrec &&
|
||||
recs_match(xdf->recs[g->start], xdf->recs[g->end], flags)) {
|
||||
recs_match(xdf->recs[g->start], xdf->recs[g->end])) {
|
||||
xdf->rchg[g->start++] = 0;
|
||||
xdf->rchg[g->end++] = 1;
|
||||
|
||||
@@ -780,10 +778,10 @@ static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g, long flags)
|
||||
* into a previous group, expand this group to include it. Return 0 on success
|
||||
* or -1 if g cannot be slid up.
|
||||
*/
|
||||
static int group_slide_up(xdfile_t *xdf, struct xdlgroup *g, long flags)
|
||||
static int group_slide_up(xdfile_t *xdf, struct xdlgroup *g)
|
||||
{
|
||||
if (g->start > 0 &&
|
||||
recs_match(xdf->recs[g->start - 1], xdf->recs[g->end - 1], flags)) {
|
||||
recs_match(xdf->recs[g->start - 1], xdf->recs[g->end - 1])) {
|
||||
xdf->rchg[--g->start] = 1;
|
||||
xdf->rchg[--g->end] = 0;
|
||||
|
||||
@@ -839,7 +837,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
|
||||
end_matching_other = -1;
|
||||
|
||||
/* Shift the group backward as much as possible: */
|
||||
while (!group_slide_up(xdf, &g, flags))
|
||||
while (!group_slide_up(xdf, &g))
|
||||
if (group_previous(xdfo, &go))
|
||||
xdl_bug("group sync broken sliding up");
|
||||
|
||||
@@ -854,7 +852,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
|
||||
|
||||
/* Now shift the group forward as far as possible: */
|
||||
while (1) {
|
||||
if (group_slide_down(xdf, &g, flags))
|
||||
if (group_slide_down(xdf, &g))
|
||||
break;
|
||||
if (group_next(xdfo, &go))
|
||||
xdl_bug("group sync broken sliding down");
|
||||
@@ -881,7 +879,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
|
||||
* other file that it can align with.
|
||||
*/
|
||||
while (go.end == go.start) {
|
||||
if (group_slide_up(xdf, &g, flags))
|
||||
if (group_slide_up(xdf, &g))
|
||||
xdl_bug("match disappeared");
|
||||
if (group_previous(xdfo, &go))
|
||||
xdl_bug("group sync broken sliding to match");
|
||||
@@ -924,7 +922,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
|
||||
}
|
||||
|
||||
while (g.end > best_shift) {
|
||||
if (group_slide_up(xdf, &g, flags))
|
||||
if (group_slide_up(xdf, &g))
|
||||
xdl_bug("best shift unreached");
|
||||
if (group_previous(xdfo, &go))
|
||||
xdl_bug("group sync broken sliding to blank line");
|
||||
|
||||
+2
-4
@@ -56,9 +56,7 @@ int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr);
|
||||
void xdl_free_script(xdchange_t *xscr);
|
||||
int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
|
||||
xdemitconf_t const *xecfg);
|
||||
int xdl_do_patience_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
xdfenv_t *env);
|
||||
int xdl_do_histogram_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
xdfenv_t *env);
|
||||
int xdl_do_patience_diff(xpparam_t const *xpp, xdfenv_t *env);
|
||||
int xdl_do_histogram_diff(xpparam_t const *xpp, xdfenv_t *env);
|
||||
|
||||
#endif /* #if !defined(XDIFFI_H) */
|
||||
|
||||
+3
-3
@@ -65,7 +65,7 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
|
||||
*xscr = xch;
|
||||
}
|
||||
|
||||
if (*xscr == NULL)
|
||||
if (!*xscr)
|
||||
return NULL;
|
||||
|
||||
lxch = *xscr;
|
||||
@@ -96,7 +96,7 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
|
||||
|
||||
|
||||
#if 0
|
||||
static long def_ff(const char *rec, long len, char *buf, long sz, void *priv UNUSED)
|
||||
static long def_ff(const char *rec, long len, char *buf, long sz)
|
||||
{
|
||||
if (len > 0 &&
|
||||
(isalpha((unsigned char)*rec) || /* identifier? */
|
||||
@@ -120,7 +120,7 @@ static long match_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri,
|
||||
const char *rec;
|
||||
long len = xdl_get_rec(xdf, ri, &rec);
|
||||
if (!xecfg->find_func)
|
||||
return def_ff(rec, len, buf, sz, xecfg->find_func_priv);
|
||||
return def_ff(rec, len, buf, sz);
|
||||
return xecfg->find_func(rec, len, buf, sz, xecfg->find_func_priv);
|
||||
}
|
||||
#endif
|
||||
|
||||
+11
-27
@@ -88,19 +88,14 @@ struct region {
|
||||
#define REC(env, s, l) \
|
||||
(env->xdf##s.recs[l - 1])
|
||||
|
||||
static int cmp_recs(xpparam_t const *xpp,
|
||||
xrecord_t *r1, xrecord_t *r2)
|
||||
static int cmp_recs(xrecord_t *r1, xrecord_t *r2)
|
||||
{
|
||||
return r1->ha == r2->ha &&
|
||||
xdl_recmatch(r1->ptr, r1->size, r2->ptr, r2->size,
|
||||
xpp->flags);
|
||||
return r1->ha == r2->ha;
|
||||
|
||||
}
|
||||
|
||||
#define CMP_ENV(xpp, env, s1, l1, s2, l2) \
|
||||
(cmp_recs(xpp, REC(env, s1, l1), REC(env, s2, l2)))
|
||||
|
||||
#define CMP(i, s1, l1, s2, l2) \
|
||||
(cmp_recs(i->xpp, REC(i->env, s1, l1), REC(i->env, s2, l2)))
|
||||
(cmp_recs(REC(i->env, s1, l1), REC(i->env, s2, l2)))
|
||||
|
||||
#define TABLE_HASH(index, side, line) \
|
||||
XDL_HASHLONG((REC(index->env, side, line))->ha, index->table_bits)
|
||||
@@ -256,7 +251,7 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
int b_ptr;
|
||||
int sz, ret = -1;
|
||||
int ret = -1;
|
||||
struct histindex index;
|
||||
|
||||
memset(&index, 0, sizeof(index));
|
||||
@@ -270,23 +265,16 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
|
||||
index.rcha.head = NULL;
|
||||
|
||||
index.table_bits = xdl_hashbits(count1);
|
||||
sz = index.records_size = 1 << index.table_bits;
|
||||
sz *= sizeof(struct record *);
|
||||
if (!(index.records = (struct record **) xdl_malloc(sz)))
|
||||
index.records_size = 1 << index.table_bits;
|
||||
if (!XDL_CALLOC_ARRAY(index.records, index.records_size))
|
||||
goto cleanup;
|
||||
memset(index.records, 0, sz);
|
||||
|
||||
sz = index.line_map_size = count1;
|
||||
sz *= sizeof(struct record *);
|
||||
if (!(index.line_map = (struct record **) xdl_malloc(sz)))
|
||||
index.line_map_size = count1;
|
||||
if (!XDL_CALLOC_ARRAY(index.line_map, index.line_map_size))
|
||||
goto cleanup;
|
||||
memset(index.line_map, 0, sz);
|
||||
|
||||
sz = index.line_map_size;
|
||||
sz *= sizeof(unsigned int);
|
||||
if (!(index.next_ptrs = (unsigned int *) xdl_malloc(sz)))
|
||||
if (!XDL_CALLOC_ARRAY(index.next_ptrs, index.line_map_size))
|
||||
goto cleanup;
|
||||
memset(index.next_ptrs, 0, sz);
|
||||
|
||||
/* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
|
||||
if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
|
||||
@@ -374,12 +362,8 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
int xdl_do_histogram_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env)
|
||||
int xdl_do_histogram_diff(xpparam_t const *xpp, xdfenv_t *env)
|
||||
{
|
||||
if (xdl_prepare_env(file1, file2, xpp, env) < 0)
|
||||
return -1;
|
||||
|
||||
return histogram_diff(xpp, env,
|
||||
env->xdf1.dstart + 1, env->xdf1.dend - env->xdf1.dstart + 1,
|
||||
env->xdf2.dstart + 1, env->xdf2.dend - env->xdf2.dstart + 1);
|
||||
|
||||
+23
-2
@@ -24,7 +24,11 @@
|
||||
#define XMACROS_H
|
||||
|
||||
|
||||
|
||||
#ifdef __hpux
|
||||
# ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t)(-1))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define XDL_MIN(a, b) ((a) < (b) ? (a): (b))
|
||||
#define XDL_MAX(a, b) ((a) > (b) ? (a): (b))
|
||||
@@ -34,7 +38,6 @@
|
||||
#define XDL_ADDBITS(v,b) ((v) + ((v) >> (b)))
|
||||
#define XDL_MASKBITS(b) ((1UL << (b)) - 1)
|
||||
#define XDL_HASHLONG(v,b) (XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
|
||||
#define XDL_PTRFREE(p) do { if (p) { xdl_free(p); (p) = NULL; } } while (0)
|
||||
#define XDL_LE32_PUT(p, v) \
|
||||
do { \
|
||||
unsigned char *__p = (unsigned char *) (p); \
|
||||
@@ -50,5 +53,23 @@ do { \
|
||||
((unsigned long) __p[2]) << 16 | ((unsigned long) __p[3]) << 24; \
|
||||
} while (0)
|
||||
|
||||
/* Allocate an array of nr elements, returns NULL on failure */
|
||||
#define XDL_ALLOC_ARRAY(p, nr) \
|
||||
((p) = SIZE_MAX / sizeof(*(p)) >= (size_t)(nr) \
|
||||
? xdl_malloc((nr) * sizeof(*(p))) \
|
||||
: NULL)
|
||||
|
||||
/* Allocate an array of nr zeroed out elements, returns NULL on failure */
|
||||
#define XDL_CALLOC_ARRAY(p, nr) ((p) = xdl_calloc(nr, sizeof(*(p))))
|
||||
|
||||
/*
|
||||
* Ensure array p can accommodate at least nr elements, growing the
|
||||
* array and updating alloc (which is the number of allocated
|
||||
* elements) as necessary. Frees p and returns -1 on failure, returns
|
||||
* 0 on success
|
||||
*/
|
||||
#define XDL_ALLOC_GROW(p, nr, alloc) \
|
||||
(-!((nr) <= (alloc) || \
|
||||
((p) = xdl_alloc_grow_helper((p), (nr), &(alloc), sizeof(*(p))))))
|
||||
|
||||
#endif /* #if !defined(XMACROS_H) */
|
||||
|
||||
+20
-33
@@ -69,7 +69,6 @@ struct hashmap {
|
||||
} *entries, *first, *last;
|
||||
/* were common records found? */
|
||||
unsigned long has_matches;
|
||||
mmfile_t *file1, *file2;
|
||||
xdfenv_t *env;
|
||||
xpparam_t const *xpp;
|
||||
};
|
||||
@@ -139,23 +138,17 @@ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
|
||||
*
|
||||
* It is assumed that env has been prepared using xdl_prepare().
|
||||
*/
|
||||
static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env,
|
||||
static int fill_hashmap(xpparam_t const *xpp, xdfenv_t *env,
|
||||
struct hashmap *result,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
result->file1 = file1;
|
||||
result->file2 = file2;
|
||||
result->xpp = xpp;
|
||||
result->env = env;
|
||||
|
||||
/* We know exactly how large we want the hash map */
|
||||
result->alloc = count1 * 2;
|
||||
result->entries = (struct entry *)
|
||||
xdl_malloc(result->alloc * sizeof(struct entry));
|
||||
if (!result->entries)
|
||||
if (!XDL_CALLOC_ARRAY(result->entries, result->alloc))
|
||||
return -1;
|
||||
memset(result->entries, 0, result->alloc * sizeof(struct entry));
|
||||
|
||||
/* First, fill with entries from the first file */
|
||||
while (count1--)
|
||||
@@ -198,9 +191,9 @@ static int binary_search(struct entry **sequence, int longest,
|
||||
* item per sequence length: the sequence with the smallest last
|
||||
* element (in terms of line2).
|
||||
*/
|
||||
static struct entry *find_longest_common_sequence(struct hashmap *map)
|
||||
static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
|
||||
{
|
||||
struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
|
||||
struct entry **sequence;
|
||||
int longest = 0, i;
|
||||
struct entry *entry;
|
||||
|
||||
@@ -211,9 +204,8 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
|
||||
*/
|
||||
int anchor_i = -1;
|
||||
|
||||
// Added to silence Coverity.
|
||||
if (sequence == NULL)
|
||||
return map->first;
|
||||
if (!XDL_ALLOC_ARRAY(sequence, map->nr))
|
||||
return -1;
|
||||
|
||||
for (entry = map->first; entry; entry = entry->next) {
|
||||
if (!entry->line2 || entry->line2 == NON_UNIQUE)
|
||||
@@ -234,8 +226,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
|
||||
|
||||
/* No common unique lines were found */
|
||||
if (!longest) {
|
||||
*res = NULL;
|
||||
xdl_free(sequence);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Iterate starting at the last element, adjusting the "next" members */
|
||||
@@ -245,8 +238,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
|
||||
entry->previous->next = entry;
|
||||
entry = entry->previous;
|
||||
}
|
||||
*res = entry;
|
||||
xdl_free(sequence);
|
||||
return entry;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int match(struct hashmap *map, int line1, int line2)
|
||||
@@ -256,8 +250,7 @@ static int match(struct hashmap *map, int line1, int line2)
|
||||
return record1->ha == record2->ha;
|
||||
}
|
||||
|
||||
static int patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env,
|
||||
static int patience_diff(xpparam_t const *xpp, xdfenv_t *env,
|
||||
int line1, int count1, int line2, int count2);
|
||||
|
||||
static int walk_common_sequence(struct hashmap *map, struct entry *first,
|
||||
@@ -288,8 +281,7 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first,
|
||||
|
||||
/* Recurse */
|
||||
if (next1 > line1 || next2 > line2) {
|
||||
if (patience_diff(map->file1, map->file2,
|
||||
map->xpp, map->env,
|
||||
if (patience_diff(map->xpp, map->env,
|
||||
line1, next1 - line1,
|
||||
line2, next2 - line2))
|
||||
return -1;
|
||||
@@ -328,8 +320,7 @@ static int fall_back_to_classic_diff(struct hashmap *map,
|
||||
*
|
||||
* This function assumes that env was prepared with xdl_prepare_env().
|
||||
*/
|
||||
static int patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env,
|
||||
static int patience_diff(xpparam_t const *xpp, xdfenv_t *env,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
struct hashmap map;
|
||||
@@ -348,7 +339,7 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
}
|
||||
|
||||
memset(&map, 0, sizeof(map));
|
||||
if (fill_hashmap(file1, file2, xpp, env, &map,
|
||||
if (fill_hashmap(xpp, env, &map,
|
||||
line1, count1, line2, count2))
|
||||
return -1;
|
||||
|
||||
@@ -362,25 +353,21 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
return 0;
|
||||
}
|
||||
|
||||
first = find_longest_common_sequence(&map);
|
||||
result = find_longest_common_sequence(&map, &first);
|
||||
if (result)
|
||||
goto out;
|
||||
if (first)
|
||||
result = walk_common_sequence(&map, first,
|
||||
line1, count1, line2, count2);
|
||||
else
|
||||
result = fall_back_to_classic_diff(&map,
|
||||
line1, count1, line2, count2);
|
||||
|
||||
out:
|
||||
xdl_free(map.entries);
|
||||
return result;
|
||||
}
|
||||
|
||||
int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env)
|
||||
int xdl_do_patience_diff(xpparam_t const *xpp, xdfenv_t *env)
|
||||
{
|
||||
if (xdl_prepare_env(file1, file2, xpp, env) < 0)
|
||||
return -1;
|
||||
|
||||
/* environment is cleaned up in xdl_diff() */
|
||||
return patience_diff(file1, file2, xpp, env,
|
||||
1, env->xdf1.nrec, 1, env->xdf2.nrec);
|
||||
return patience_diff(xpp, env, 1, env->xdf1.nrec, 1, env->xdf2.nrec);
|
||||
}
|
||||
|
||||
+24
-46
@@ -78,15 +78,14 @@ static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
if (!(cf->rchash = (xdlclass_t **) xdl_malloc(cf->hsize * sizeof(xdlclass_t *)))) {
|
||||
if (!XDL_CALLOC_ARRAY(cf->rchash, cf->hsize)) {
|
||||
|
||||
xdl_cha_free(&cf->ncha);
|
||||
return -1;
|
||||
}
|
||||
memset(cf->rchash, 0, cf->hsize * sizeof(xdlclass_t *));
|
||||
|
||||
cf->alloc = size;
|
||||
if (!(cf->rcrecs = (xdlclass_t **) xdl_malloc(cf->alloc * sizeof(xdlclass_t *)))) {
|
||||
if (!XDL_ALLOC_ARRAY(cf->rcrecs, cf->alloc)) {
|
||||
|
||||
xdl_free(cf->rchash);
|
||||
xdl_cha_free(&cf->ncha);
|
||||
@@ -112,7 +111,6 @@ static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t
|
||||
long hi;
|
||||
char const *line;
|
||||
xdlclass_t *rcrec;
|
||||
xdlclass_t **rcrecs;
|
||||
|
||||
line = rec->ptr;
|
||||
hi = (long) XDL_HASHLONG(rec->ha, cf->hbits);
|
||||
@@ -128,14 +126,8 @@ static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t
|
||||
return -1;
|
||||
}
|
||||
rcrec->idx = cf->count++;
|
||||
if (cf->count > cf->alloc) {
|
||||
cf->alloc *= 2;
|
||||
if (!(rcrecs = (xdlclass_t **) xdl_realloc(cf->rcrecs, cf->alloc * sizeof(xdlclass_t *)))) {
|
||||
|
||||
if (XDL_ALLOC_GROW(cf->rcrecs, cf->count, cf->alloc))
|
||||
return -1;
|
||||
}
|
||||
cf->rcrecs = rcrecs;
|
||||
}
|
||||
cf->rcrecs[rcrec->idx] = rcrec;
|
||||
rcrec->line = line;
|
||||
rcrec->size = rec->size;
|
||||
@@ -164,7 +156,7 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
|
||||
unsigned long hav;
|
||||
char const *blk, *cur, *top, *prev;
|
||||
xrecord_t *crec;
|
||||
xrecord_t **recs, **rrecs;
|
||||
xrecord_t **recs;
|
||||
xrecord_t **rhash;
|
||||
unsigned long *ha;
|
||||
char *rchg;
|
||||
@@ -178,51 +170,42 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
|
||||
|
||||
if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0)
|
||||
goto abort;
|
||||
if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))
|
||||
if (!XDL_ALLOC_ARRAY(recs, narec))
|
||||
goto abort;
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
|
||||
hbits = hsize = 0;
|
||||
else {
|
||||
hbits = xdl_hashbits((unsigned int) narec);
|
||||
hsize = 1 << hbits;
|
||||
if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *))))
|
||||
goto abort;
|
||||
memset(rhash, 0, hsize * sizeof(xrecord_t *));
|
||||
}
|
||||
hbits = xdl_hashbits((unsigned int) narec);
|
||||
hsize = 1 << hbits;
|
||||
if (!XDL_CALLOC_ARRAY(rhash, hsize))
|
||||
goto abort;
|
||||
|
||||
nrec = 0;
|
||||
if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {
|
||||
if ((cur = blk = xdl_mmfile_first(mf, &bsize))) {
|
||||
for (top = blk + bsize; cur < top; ) {
|
||||
prev = cur;
|
||||
hav = xdl_hash_record(&cur, top, xpp->flags);
|
||||
if (nrec >= narec) {
|
||||
narec *= 2;
|
||||
if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *))))
|
||||
goto abort;
|
||||
recs = rrecs;
|
||||
}
|
||||
if (XDL_ALLOC_GROW(recs, nrec + 1, narec))
|
||||
goto abort;
|
||||
if (!(crec = xdl_cha_alloc(&xdf->rcha)))
|
||||
goto abort;
|
||||
crec->ptr = prev;
|
||||
crec->size = (long) (cur - prev);
|
||||
crec->ha = hav;
|
||||
recs[nrec++] = crec;
|
||||
|
||||
if ((XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
|
||||
xdl_classify_record(pass, cf, rhash, hbits, crec) < 0)
|
||||
if (xdl_classify_record(pass, cf, rhash, hbits, crec) < 0)
|
||||
goto abort;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char))))
|
||||
if (!XDL_CALLOC_ARRAY(rchg, nrec + 2))
|
||||
goto abort;
|
||||
memset(rchg, 0, (nrec + 2) * sizeof(char));
|
||||
|
||||
if (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long))))
|
||||
goto abort;
|
||||
if (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long))))
|
||||
goto abort;
|
||||
if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
|
||||
(XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)) {
|
||||
if (!XDL_ALLOC_ARRAY(rindex, nrec + 1))
|
||||
goto abort;
|
||||
if (!XDL_ALLOC_ARRAY(ha, nrec + 1))
|
||||
goto abort;
|
||||
}
|
||||
|
||||
xdf->nrec = nrec;
|
||||
xdf->recs = recs;
|
||||
@@ -279,8 +262,7 @@ int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
enl1 = xdl_guess_lines(mf1, sample) + 1;
|
||||
enl2 = xdl_guess_lines(mf2, sample) + 1;
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF &&
|
||||
xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0)
|
||||
if (xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0)
|
||||
return -1;
|
||||
|
||||
if (xdl_prepare_ctx(1, mf1, enl1, xpp, &cf, &xe->xdf1) < 0) {
|
||||
@@ -305,8 +287,7 @@ int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)
|
||||
xdl_free_classifier(&cf);
|
||||
xdl_free_classifier(&cf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -388,11 +369,8 @@ static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xd
|
||||
xdlclass_t *rcrec;
|
||||
char *dis, *dis1, *dis2;
|
||||
|
||||
if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) {
|
||||
|
||||
if (!XDL_CALLOC_ARRAY(dis, xdf1->nrec + xdf2->nrec + 2))
|
||||
return -1;
|
||||
}
|
||||
memset(dis, 0, xdf1->nrec + xdf2->nrec + 2);
|
||||
dis1 = dis;
|
||||
dis2 = dis1 + xdf1->nrec + 1;
|
||||
|
||||
|
||||
+18
-1
@@ -122,7 +122,7 @@ long xdl_guess_lines(mmfile_t *mf, long sample) {
|
||||
long nl = 0, size, tsize = 0;
|
||||
char const *data, *cur, *top;
|
||||
|
||||
if ((cur = data = xdl_mmfile_first(mf, &size)) != NULL) {
|
||||
if ((cur = data = xdl_mmfile_first(mf, &size))) {
|
||||
for (top = data + size; nl < sample && cur < top; ) {
|
||||
nl++;
|
||||
if (!(cur = memchr(cur, '\n', top - cur)))
|
||||
@@ -432,3 +432,20 @@ int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* xdl_alloc_grow_helper(void *p, long nr, long *alloc, size_t size)
|
||||
{
|
||||
void *tmp = NULL;
|
||||
size_t n = ((LONG_MAX - 16) / 2 >= *alloc) ? 2 * *alloc + 16 : LONG_MAX;
|
||||
if (nr > (long)n)
|
||||
n = nr;
|
||||
if (SIZE_MAX / size >= n)
|
||||
tmp = xdl_realloc(p, n * size);
|
||||
if (tmp) {
|
||||
*alloc = n;
|
||||
} else {
|
||||
xdl_free(p);
|
||||
*alloc = 0;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
+2
-1
@@ -42,6 +42,7 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
|
||||
int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
|
||||
int line1, int count1, int line2, int count2);
|
||||
|
||||
|
||||
/* Do not call this function, use XDL_ALLOC_GROW instead */
|
||||
void* xdl_alloc_grow_helper(void* p, long nr, long* alloc, size_t size);
|
||||
|
||||
#endif /* #if !defined(XUTILS_H) */
|
||||
|
||||
Reference in New Issue
Block a user