]> asedeno.scripts.mit.edu Git - git.git/commitdiff
Merge branch 'jc/diff'
authorJunio C Hamano <junkio@cox.net>
Mon, 26 Jun 2006 21:36:02 +0000 (14:36 -0700)
committerJunio C Hamano <junkio@cox.net>
Mon, 26 Jun 2006 21:36:02 +0000 (14:36 -0700)
* jc/diff:
  diff --color: use $GIT_DIR/config

18 files changed:
Documentation/git-grep.txt
Documentation/git-rebase.txt
connect.c
diff.c
diff.h
git-cvsimport.perl [changed mode: 0644->0755]
git-rebase.sh
merge-index.c
pkt-line.h
t/t3401-rebase-partial.sh
t/t3403-rebase-skip.sh [new file with mode: 0755]
xdiff/xdiff.h
xdiff/xdiffi.c
xdiff/xdiffi.h
xdiff/xmacros.h
xdiff/xprepare.c
xdiff/xutils.c
xdiff/xutils.h

index 7b810dfda760a01c78667015f7c6214fcaeceae6..62a8e7f222d480046beee5cf735fa92821e26f8d 100644 (file)
@@ -16,7 +16,7 @@ SYNOPSIS
           [-n] [-l | --files-with-matches] [-L | --files-without-match]
           [-c | --count]
           [-A <post-context>] [-B <pre-context>] [-C <context>]
-          [-f <file>] [-e <pattern>]
+          [-f <file>] [-e] <pattern>
           [<tree>...]
           [--] [<path>...]
 
@@ -71,6 +71,11 @@ OPTIONS
 -f <file>::
        Read patterns from <file>, one per line.
 
+-e::
+       The next parameter is the pattern. This option has to be
+       used for patterns starting with - and should be used in
+       scripts passing user input to grep.
+
 `<tree>...`::
        Search blobs in the trees for specified patterns.
 
index c339c4525c500f29d51063a34f1c7d238b37c2e6..9d7bcaa38cc5c13e29c00ddd18c64202e98cb5f8 100644 (file)
@@ -108,7 +108,6 @@ OPTIONS
 
 --skip::
        Restart the rebasing process by skipping the current patch.
-       This does not work with the --merge option.
 
 --merge::
        Use merging strategies to rebase.  When the recursive (default) merge
index db7342e4d26baa50dd944ebf06fb8b66fea59aaa..66e78a29054a121c92beca3d997105f0137c170d 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -8,6 +8,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#include <signal.h>
 
 static char *server_capabilities = NULL;
 
diff --git a/diff.c b/diff.c
index e73c0c3008407f24c8b150cb62f97bd37db6502f..fbb6c26cd9266e0ae453bb6c321f52d4996446a6 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -743,7 +743,7 @@ static void builtin_diff(const char *name_a,
                memset(&ecbdata, 0, sizeof(ecbdata));
                ecbdata.label_path = lbl;
                ecbdata.color_diff = o->color_diff;
-               xpp.flags = XDF_NEED_MINIMAL;
+               xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
                xecfg.ctxlen = o->context;
                xecfg.flags = XDL_EMIT_FUNCNAMES;
                if (!diffopts)
@@ -768,6 +768,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
                             struct diff_filespec *one,
                             struct diff_filespec *two,
                             struct diffstat_t *diffstat,
+                            struct diff_options *o,
                             int complete_rewrite)
 {
        mmfile_t mf1, mf2;
@@ -797,7 +798,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
                xdemitconf_t xecfg;
                xdemitcb_t ecb;
 
-               xpp.flags = XDF_NEED_MINIMAL;
+               xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
                xecfg.ctxlen = 0;
                xecfg.flags = 0;
                ecb.outf = xdiff_outf;
@@ -1382,7 +1383,7 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
 
        if (DIFF_PAIR_UNMERGED(p)) {
                /* unmerged */
-               builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, 0);
+               builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, 0);
                return;
        }
 
@@ -1394,7 +1395,7 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
 
        if (p->status == DIFF_STATUS_MODIFIED && p->score)
                complete_rewrite = 1;
-       builtin_diffstat(name, other, p->one, p->two, diffstat, complete_rewrite);
+       builtin_diffstat(name, other, p->one, p->two, diffstat, o, complete_rewrite);
 }
 
 static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
@@ -1600,6 +1601,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
        }
        else if (!strcmp(arg, "--color"))
                options->color_diff = 1;
+       else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
+               options->xdl_opts |= XDF_IGNORE_WHITESPACE;
+       else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change"))
+               options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
        else
                return 0;
        return 1;
diff --git a/diff.h b/diff.h
index de9de574e78693d27ff911d882030a59407a99d5..b61fdc8f1e4f34b608ed69cbbac6f74b81d47b53 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -46,6 +46,7 @@ struct diff_options {
        int setup;
        int abbrev;
        const char *stat_sep;
+       long xdl_opts;
 
        int nr_paths;
        const char **paths;
old mode 100644 (file)
new mode 100755 (executable)
index f3daa6c..50f5d96
@@ -17,7 +17,7 @@ use strict;
 use warnings;
 use Getopt::Std;
 use File::Spec;
-use File::Temp qw(tempfile);
+use File::Temp qw(tempfile tmpnam);
 use File::Path qw(mkpath);
 use File::Basename qw(basename dirname);
 use Time::Local;
@@ -467,13 +467,12 @@ my $orig_git_index;
 $orig_git_index = $ENV{GIT_INDEX_FILE} if exists $ENV{GIT_INDEX_FILE};
 
 my %index; # holds filenames of one index per branch
-{   # init with an index for origin
-    my ($fh, $fn) = tempfile('gitXXXXXX', SUFFIX => '.idx',
-                            DIR => File::Spec->tmpdir());
-    close ($fh);
-    $index{$opt_o} = $fn;
-}
+$index{$opt_o} = tmpnam();
+
 $ENV{GIT_INDEX_FILE} = $index{$opt_o};
+system("git-read-tree", $opt_o);
+die "read-tree failed: $?\n" if $?;
+
 unless(-d $git_dir) {
        system("git-init-db");
        die "Cannot init the GIT db at $git_tree: $?\n" if $?;
@@ -502,10 +501,7 @@ unless(-d $git_dir) {
 
        # populate index
        unless ($index{$last_branch}) {
-           my ($fh, $fn) = tempfile('gitXXXXXX', SUFFIX => '.idx',
-                                    DIR => File::Spec->tmpdir());
-           close ($fh);
-           $index{$last_branch} = $fn;
+           $index{$last_branch} = tmpnam();
        }
        $ENV{GIT_INDEX_FILE} = $index{$last_branch};
        system('git-read-tree', $last_branch);
@@ -818,16 +814,26 @@ while(<CVS>) {
                if(($ancestor || $branch) ne $last_branch) {
                        print "Switching from $last_branch to $branch\n" if $opt_v;
                        unless ($index{$branch}) {
-                           my ($fh, $fn) = tempfile('gitXXXXXX', SUFFIX => '.idx',
-                                                    DIR => File::Spec->tmpdir());
-                           close ($fh);
-                           $index{$branch} = $fn;
+                           $index{$branch} = tmpnam();
                            $ENV{GIT_INDEX_FILE} = $index{$branch};
                            system("git-read-tree", $branch);
                            die "read-tree failed: $?\n" if $?;
-                       } else {
+                       }
+                       # just in case
+                       $ENV{GIT_INDEX_FILE} = $index{$branch};
+                       if ($ancestor) {
+                           print "have ancestor $ancestor" if $opt_v;
+                           system("git-read-tree", $ancestor);
+                           die "read-tree failed: $?\n" if $?;
+                       }
+               } else {
+                       # just in case
+                       unless ($index{$branch}) {
+                           $index{$branch} = tmpnam();
                            $ENV{GIT_INDEX_FILE} = $index{$branch};
-                       }
+                           system("git-read-tree", $branch);
+                           die "read-tree failed: $?\n" if $?;
+                       }
                }
                $last_branch = $branch if $branch ne $last_branch;
                $state = 9;
index 91594775e6aad4ebe924506e779c51ea5333ad37..9ad1c44d4816f8c4f52eddc525bc24cd6bfe92d2 100755 (executable)
@@ -59,15 +59,16 @@ continue_merge () {
 
        if test -n "`git-diff-index HEAD`"
        then
+               printf "Committed: %0${prec}d" $msgnum
                git-commit -C "`cat $dotest/current`"
        else
-               echo "Previous merge succeeded automatically"
+               printf "Already applied: %0${prec}d" $msgnum
        fi
+       echo ' '`git-rev-list --pretty=oneline -1 HEAD | \
+                               sed 's/^[a-f0-9]\+ //'`
 
        prev_head=`git-rev-parse HEAD^0`
-
        # save the resulting commit so we can read-tree on it later
-       echo "$prev_head" > "$dotest/cmt.$msgnum.result"
        echo "$prev_head" > "$dotest/prev_head"
 
        # onto the next patch:
@@ -82,7 +83,7 @@ call_merge () {
        rv=$?
        case "$rv" in
        0)
-               git-commit -C "$cmt" || die "commit failed: $MRESOLVEMSG"
+               return
                ;;
        1)
                test -d "$GIT_DIR/rr-cache" && git-rerere
@@ -100,23 +101,6 @@ call_merge () {
 }
 
 finish_rb_merge () {
-       set -e
-
-       msgnum=1
-       echo "Finalizing rebased commits..."
-       git-reset --hard "`cat $dotest/onto`"
-       end="`cat $dotest/end`"
-       while test "$msgnum" -le "$end"
-       do
-               git-read-tree `cat "$dotest/cmt.$msgnum.result"`
-               git-checkout-index -q -f -u -a
-               git-commit -C "`cat $dotest/cmt.$msgnum`"
-
-               printf "Committed %0${prec}d" $msgnum
-               echo ' '`git-rev-list --pretty=oneline -1 HEAD | \
-                                       sed 's/^[a-f0-9]\+ //'`
-               msgnum=$(($msgnum + 1))
-       done
        rm -r "$dotest"
        echo "All done."
 }
@@ -153,7 +137,18 @@ do
        --skip)
                if test -d "$dotest"
                then
-                       die "--skip is not supported when using --merge"
+                       prev_head="`cat $dotest/prev_head`"
+                       end="`cat $dotest/end`"
+                       msgnum="`cat $dotest/msgnum`"
+                       msgnum=$(($msgnum + 1))
+                       onto="`cat $dotest/onto`"
+                       while test "$msgnum" -le "$end"
+                       do
+                               call_merge "$msgnum"
+                               continue_merge
+                       done
+                       finish_rb_merge
+                       exit
                fi
                git am -3 --skip --resolvemsg="$RESOLVEMSG"
                exit
index 190e12fb7ceeb012a063f8c97b574e9650d95cc1..0498a6f45e53947e356c6a390869d3f8194f05b7 100644 (file)
@@ -1,5 +1,6 @@
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <signal.h>
 
 #include "cache.h"
 
index 9abef24de36119a56a9bee48e49c2c8fccae32fc..9df653f6f5afe720870658d7093bddbf3e66beaf 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef PKTLINE_H
 #define PKTLINE_H
 
+#include "git-compat-util.h"
+
 /*
  * Silly packetized line writing interface
  */
index 32dc9c5e74e80e2483ae0bf49f3dfd549c6d8471..360a67060e1d1fd501fed7729712213360c456b2 100755 (executable)
@@ -37,7 +37,9 @@ test_expect_success \
 test_expect_success \
     'pick top patch from topic branch into master' \
     'git-cherry-pick my-topic-branch^0 &&
-     git-checkout -f my-topic-branch
+     git-checkout -f my-topic-branch &&
+     git-branch master-merge master &&
+     git-branch my-topic-branch-merge my-topic-branch
 '
 
 test_debug \
@@ -50,4 +52,13 @@ test_expect_success \
     'rebase topic branch against new master and check git-am did not get halted' \
     'git-rebase master && test ! -d .dotest'
 
+if test -z "$no_python"
+then
+    test_expect_success \
+       'rebase --merge topic branch that was partially merged upstream' \
+       'git-checkout -f my-topic-branch-merge &&
+        git-rebase --merge master-merge &&
+        test ! -d .git/.dotest-merge'
+fi
+
 test_done
diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh
new file mode 100755 (executable)
index 0000000..8ab63c5
--- /dev/null
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Eric Wong
+#
+
+test_description='git rebase --merge --skip tests'
+
+. ./test-lib.sh
+
+# we assume the default git-am -3 --skip strategy is tested independently
+# and always works :)
+
+if test "$no_python"; then
+       echo "Skipping: no python => no recursive merge"
+       test_done
+       exit 0
+fi
+
+test_expect_success setup '
+       echo hello > hello &&
+       git add hello &&
+       git commit -m "hello" &&
+       git branch skip-reference &&
+
+       echo world >> hello &&
+       git commit -a -m "hello world" &&
+       echo goodbye >> hello &&
+       git commit -a -m "goodbye" &&
+
+       git checkout -f skip-reference &&
+       echo moo > hello &&
+       git commit -a -m "we should skip this" &&
+       echo moo > cow &&
+       git add cow &&
+       git commit -m "this should not be skipped" &&
+       git branch pre-rebase skip-reference &&
+       git branch skip-merge skip-reference
+       '
+
+test_expect_failure 'rebase with git am -3 (default)' 'git rebase master'
+
+test_expect_success 'rebase --skip with am -3' '
+       git reset --hard HEAD &&
+       git rebase --skip
+       '
+test_expect_success 'checkout skip-merge' 'git checkout -f skip-merge'
+
+test_expect_failure 'rebase with --merge' 'git rebase --merge master'
+
+test_expect_success 'rebase --skip with --merge' '
+       git reset --hard HEAD &&
+       git rebase --skip
+       '
+
+test_expect_success 'merge and reference trees equal' \
+       'test -z "`git-diff-tree skip-merge skip-reference`"'
+
+test_debug 'gitk --all & sleep 1'
+
+test_done
+
index 2540e8a2ccc6781d23a42c03dadc050a3e233c39..2ce10b4c0d18aca467d3fb7a47badefa8c7c956f 100644 (file)
@@ -29,6 +29,9 @@ extern "C" {
 
 
 #define XDF_NEED_MINIMAL (1 << 1)
+#define XDF_IGNORE_WHITESPACE (1 << 2)
+#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 3)
+#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE)
 
 #define XDL_PATCH_NORMAL '-'
 #define XDL_PATCH_REVERSE '+'
index b95ade2c1b58a48a91bf9a87c7a3893559580225..ed7ad2041c6f81df8b0191374c5b0e4e91683a70 100644 (file)
@@ -45,7 +45,7 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
                      long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
                      xdalgoenv_t *xenv);
 static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2);
-static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo);
+static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags);
 
 
 
@@ -397,7 +397,7 @@ static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1,
 }
 
 
-static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo) {
+static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
        long ix, ixo, ixs, ixref, grpsiz, nrec = xdf->nrec;
        char *rchg = xdf->rchg, *rchgo = xdfo->rchg;
        xrecord_t **recs = xdf->recs;
@@ -440,7 +440,7 @@ static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo) {
                         * the group.
                         */
                        while (ixs > 0 && recs[ixs - 1]->ha == recs[ix - 1]->ha &&
-                              XDL_RECMATCH(recs[ixs - 1], recs[ix - 1])) {
+                              xdl_recmatch(recs[ixs - 1]->ptr, recs[ixs - 1]->size, recs[ix - 1]->ptr, recs[ix - 1]->size, flags)) {
                                rchg[--ixs] = 1;
                                rchg[--ix] = 0;
 
@@ -468,7 +468,7 @@ static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo) {
                         * the group.
                         */
                        while (ix < nrec && recs[ixs]->ha == recs[ix]->ha &&
-                              XDL_RECMATCH(recs[ixs], recs[ix])) {
+                              xdl_recmatch(recs[ixs]->ptr, recs[ixs]->size, recs[ix]->ptr, recs[ix]->size, flags)) {
                                rchg[ixs++] = 0;
                                rchg[ix++] = 1;
 
@@ -546,8 +546,8 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
 
                return -1;
        }
-       if (xdl_change_compact(&xe.xdf1, &xe.xdf2) < 0 ||
-           xdl_change_compact(&xe.xdf2, &xe.xdf1) < 0 ||
+       if (xdl_change_compact(&xe.xdf1, &xe.xdf2, xpp->flags) < 0 ||
+           xdl_change_compact(&xe.xdf2, &xe.xdf1, xpp->flags) < 0 ||
            xdl_build_script(&xe, &xscr) < 0) {
 
                xdl_free_env(&xe);
index dd8f3c986be9cefa8ac61d54ec9646bbc62234fd..d3b72716b58273169904a4351f02fab7ab2fc6e9 100644 (file)
@@ -55,6 +55,5 @@ void xdl_free_script(xdchange_t *xscr);
 int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
                  xdemitconf_t const *xecfg);
 
-
 #endif /* #if !defined(XDIFFI_H) */
 
index 78f02603b8abde66cb170ca867345cbb70660f60..4c2fde80c143b3aaf086dc36c1a050851f83feaa 100644 (file)
@@ -33,7 +33,6 @@
 #define XDL_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
 #define XDL_HASHLONG(v, b) (((unsigned long)(v) * GR_PRIME) >> ((CHAR_BIT * sizeof(unsigned long)) - (b)))
 #define XDL_PTRFREE(p) do { if (p) { xdl_free(p); (p) = NULL; } } while (0)
-#define XDL_RECMATCH(r1, r2) ((r1)->size == (r2)->size && memcmp((r1)->ptr, (r2)->ptr, (r1)->size) == 0)
 #define XDL_LE32_PUT(p, v) \
 do { \
        unsigned char *__p = (unsigned char *) (p); \
index add5a75c77f1164703138a3cc781d87bd0d72b82..1be7b3195059bebffe83d17301f3ff0fb261799e 100644 (file)
@@ -43,12 +43,13 @@ typedef struct s_xdlclassifier {
        xdlclass_t **rchash;
        chastore_t ncha;
        long count;
+       long flags;
 } xdlclassifier_t;
 
 
 
 
-static int xdl_init_classifier(xdlclassifier_t *cf, long size);
+static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags);
 static void xdl_free_classifier(xdlclassifier_t *cf);
 static int xdl_classify_record(xdlclassifier_t *cf, xrecord_t **rhash, unsigned int hbits,
                               xrecord_t *rec);
@@ -63,9 +64,11 @@ static int xdl_optimize_ctxs(xdfile_t *xdf1, xdfile_t *xdf2);
 
 
 
-static int xdl_init_classifier(xdlclassifier_t *cf, long size) {
+static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
        long i;
 
+       cf->flags = flags;
+
        cf->hbits = xdl_hashbits((unsigned int) size);
        cf->hsize = 1 << cf->hbits;
 
@@ -103,8 +106,9 @@ static int xdl_classify_record(xdlclassifier_t *cf, xrecord_t **rhash, unsigned
        line = rec->ptr;
        hi = (long) XDL_HASHLONG(rec->ha, cf->hbits);
        for (rcrec = cf->rchash[hi]; rcrec; rcrec = rcrec->next)
-               if (rcrec->ha == rec->ha && rcrec->size == rec->size &&
-                   !memcmp(line, rcrec->line, rec->size))
+               if (rcrec->ha == rec->ha &&
+                               xdl_recmatch(rcrec->line, rcrec->size,
+                                       rec->ptr, rec->size, cf->flags))
                        break;
 
        if (!rcrec) {
@@ -173,7 +177,7 @@ static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,
                                top = blk + bsize;
                        }
                        prev = cur;
-                       hav = xdl_hash_record(&cur, top);
+                       hav = xdl_hash_record(&cur, top, xpp->flags);
                        if (nrec >= narec) {
                                narec *= 2;
                                if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *)))) {
@@ -268,7 +272,7 @@ int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
        enl1 = xdl_guess_lines(mf1) + 1;
        enl2 = xdl_guess_lines(mf2) + 1;
 
-       if (xdl_init_classifier(&cf, enl1 + enl2 + 1) < 0) {
+       if (xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0) {
 
                return -1;
        }
index f91b4034751df72996afbe6b4b04a9f05638d322..f7bdd395ad1f69067654a754b4d60fcc7c359275 100644 (file)
@@ -186,12 +186,61 @@ long xdl_guess_lines(mmfile_t *mf) {
        return nl + 1;
 }
 
+int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
+{
+       int i1, i2;
+
+       if (flags & XDF_IGNORE_WHITESPACE) {
+               for (i1 = i2 = 0; i1 < s1 && i2 < s2; i1++, i2++) {
+                       if (isspace(l1[i1]))
+                               while (isspace(l1[i1]) && i1 < s1)
+                                       i1++;
+                       else if (isspace(l2[i2]))
+                               while (isspace(l2[i2]) && i2 < s2)
+                                       i2++;
+                       else if (l1[i1] != l2[i2])
+                               return l2[i2] - l1[i1];
+               }
+               if (i1 >= s1)
+                       return 1;
+               else if (i2 >= s2)
+                       return -1;
+       } else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
+               for (i1 = i2 = 0; i1 < s1 && i2 < s2; i1++, i2++) {
+                       if (isspace(l1[i1])) {
+                               if (!isspace(l2[i2]))
+                                       return -1;
+                               while (isspace(l1[i1]) && i1 < s1)
+                                       i1++;
+                               while (isspace(l2[i2]) && i2 < s2)
+                                       i2++;
+                       } else if (l1[i1] != l2[i2])
+                               return l2[i2] - l1[i1];
+               }
+               if (i1 >= s1)
+                       return 1;
+               else if (i2 >= s2)
+                       return -1;
+       } else
+               return s1 == s2 && !memcmp(l1, l2, s1);
+
+       return 0;
+}
 
-unsigned long xdl_hash_record(char const **data, char const *top) {
+unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
        unsigned long ha = 5381;
        char const *ptr = *data;
 
        for (; ptr < top && *ptr != '\n'; ptr++) {
+               if (isspace(*ptr) && (flags & XDF_WHITESPACE_FLAGS)) {
+                       while (ptr < top && isspace(*ptr) && ptr[1] != '\n')
+                               ptr++;
+                       if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
+                               ha += (ha << 5);
+                               ha ^= (unsigned long) ' ';
+                       }
+                       continue;
+               }
                ha += (ha << 5);
                ha ^= (unsigned long) *ptr;
        }
index 08691a2447126a8a8f96bb8a0369f21524c58c39..70d8b9838a7333bc5a1edb93cf0e9abdbcf146cc 100644 (file)
@@ -34,7 +34,8 @@ void *xdl_cha_alloc(chastore_t *cha);
 void *xdl_cha_first(chastore_t *cha);
 void *xdl_cha_next(chastore_t *cha);
 long xdl_guess_lines(mmfile_t *mf);
-unsigned long xdl_hash_record(char const **data, char const *top);
+int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags);
+unsigned long xdl_hash_record(char const **data, char const *top, long flags);
 unsigned int xdl_hashbits(unsigned int size);
 int xdl_num_out(char *out, long val);
 long xdl_atol(char const *str, char const **next);