Merge branch 'jc/squash'
authorJunio C Hamano <junkio@cox.net>
Mon, 26 Jun 2006 21:36:10 +0000 (14:36 -0700)
committerJunio C Hamano <junkio@cox.net>
Mon, 26 Jun 2006 21:36:10 +0000 (14:36 -0700)
* jc/squash:
git-merge --squash

34 files changed:
Documentation/git-grep.txt
Documentation/git-rebase.txt
Makefile
builtin-apply.c
builtin-log.c
builtin-tar-tree.c
cache.h
compat/strlcpy.c [new file with mode: 0644]
config.c
connect.c
diff.c
diff.h
git-commit.sh
git-compat-util.h
git-cvsimport.perl [changed mode: 0644->0755]
git-rebase.sh
git-repack.sh
http-fetch.c
http-push.c
ident.c
merge-index.c
path.c
pkt-line.h
repo-config.c
sha1_name.c
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 e29e3fa381dd3b36bf235d304d99f254db702492..cde619c498da717ea665430f7d395358d0b1d06e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -26,6 +26,8 @@ all:
 #
 # Define NO_STRCASESTR if you don't have strcasestr.
 #
+# Define NO_STRLCPY if you don't have strlcpy.
+#
 # Define NO_SETENV if you don't have setenv in the C library.
 #
 # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
@@ -240,9 +242,13 @@ LIBS = $(GITLIBS) -lz
 # because maintaining the nesting to match is a pain.  If
 # we had "elif" things would have been much nicer...
 
+ifeq ($(uname_S),Linux)
+       NO_STRLCPY = YesPlease
+endif
 ifeq ($(uname_S),Darwin)
        NEEDS_SSL_WITH_CRYPTO = YesPlease
        NEEDS_LIBICONV = YesPlease
+       NO_STRLCPY = YesPlease
        ## fink
        ifeq ($(shell test -d /sw/lib && echo y),y)
                ALL_CFLAGS += -I/sw/include
@@ -259,6 +265,7 @@ ifeq ($(uname_S),SunOS)
        NEEDS_NSL = YesPlease
        SHELL_PATH = /bin/bash
        NO_STRCASESTR = YesPlease
+       NO_STRLCPY = YesPlease
        ifeq ($(uname_R),5.8)
                NEEDS_LIBICONV = YesPlease
                NO_UNSETENV = YesPlease
@@ -276,6 +283,7 @@ ifeq ($(uname_O),Cygwin)
        NO_D_TYPE_IN_DIRENT = YesPlease
        NO_D_INO_IN_DIRENT = YesPlease
        NO_STRCASESTR = YesPlease
+       NO_STRLCPY = YesPlease
        NO_SYMLINK_HEAD = YesPlease
        NEEDS_LIBICONV = YesPlease
        # There are conflicting reports about this.
@@ -305,12 +313,14 @@ ifeq ($(uname_S),NetBSD)
 endif
 ifeq ($(uname_S),AIX)
        NO_STRCASESTR=YesPlease
+       NO_STRLCPY = YesPlease
        NEEDS_LIBICONV=YesPlease
 endif
 ifeq ($(uname_S),IRIX64)
        NO_IPV6=YesPlease
        NO_SETENV=YesPlease
        NO_STRCASESTR=YesPlease
+       NO_STRLCPY = YesPlease
        NO_SOCKADDR_STORAGE=YesPlease
        SHELL_PATH=/usr/gnu/bin/bash
        ALL_CFLAGS += -DPATH_MAX=1024
@@ -403,6 +413,10 @@ ifdef NO_STRCASESTR
        COMPAT_CFLAGS += -DNO_STRCASESTR
        COMPAT_OBJS += compat/strcasestr.o
 endif
+ifdef NO_STRLCPY
+       COMPAT_CFLAGS += -DNO_STRLCPY
+       COMPAT_OBJS += compat/strlcpy.o
+endif
 ifdef NO_SETENV
        COMPAT_CFLAGS += -DNO_SETENV
        COMPAT_OBJS += compat/setenv.o
index 6dd0472ae07cac291d26b9e547a92c7c51d569df..e9ead002d38368f6de6ba75f25542fe61258cfb9 100644 (file)
@@ -125,6 +125,7 @@ struct patch {
        unsigned long deflate_origlen;
        int lines_added, lines_deleted;
        int score;
+       int inaccurate_eof:1;
        struct fragment *fragments;
        char *result;
        unsigned long resultsize;
@@ -1333,7 +1334,8 @@ static int apply_line(char *output, const char *patch, int plen)
        return plen;
 }
 
-static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
+static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag,
+       int inaccurate_eof)
 {
        int match_beginning, match_end;
        char *buf = desc->buffer;
@@ -1386,13 +1388,11 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
                size -= len;
        }
 
-#ifdef NO_ACCURATE_DIFF
-       if (oldsize > 0 && old[oldsize - 1] == '\n' &&
+       if (inaccurate_eof && oldsize > 0 && old[oldsize - 1] == '\n' &&
                        newsize > 0 && new[newsize - 1] == '\n') {
                oldsize--;
                newsize--;
        }
-#endif
 
        oldlines = old;
        newlines = new;
@@ -1614,7 +1614,7 @@ static int apply_fragments(struct buffer_desc *desc, struct patch *patch)
                return apply_binary(desc, patch);
 
        while (frag) {
-               if (apply_one_fragment(desc, frag) < 0)
+               if (apply_one_fragment(desc, frag, patch->inaccurate_eof) < 0)
                        return error("patch failed: %s:%ld",
                                     name, frag->oldpos);
                frag = frag->next;
@@ -2097,7 +2097,7 @@ static int use_patch(struct patch *p)
        return 1;
 }
 
-static int apply_patch(int fd, const char *filename)
+static int apply_patch(int fd, const char *filename, int inaccurate_eof)
 {
        unsigned long offset, size;
        char *buffer = read_patch_file(fd, &size);
@@ -2113,6 +2113,7 @@ static int apply_patch(int fd, const char *filename)
                int nr;
 
                patch = xcalloc(1, sizeof(*patch));
+               patch->inaccurate_eof = inaccurate_eof;
                nr = parse_chunk(buffer + offset, size, patch);
                if (nr < 0)
                        break;
@@ -2180,6 +2181,8 @@ int cmd_apply(int argc, const char **argv, char **envp)
 {
        int i;
        int read_stdin = 1;
+       int inaccurate_eof = 0;
+
        const char *whitespace_option = NULL;
 
        for (i = 1; i < argc; i++) {
@@ -2188,7 +2191,7 @@ int cmd_apply(int argc, const char **argv, char **envp)
                int fd;
 
                if (!strcmp(arg, "-")) {
-                       apply_patch(0, "<stdin>");
+                       apply_patch(0, "<stdin>", inaccurate_eof);
                        read_stdin = 0;
                        continue;
                }
@@ -2265,6 +2268,10 @@ int cmd_apply(int argc, const char **argv, char **envp)
                        parse_whitespace_option(arg + 13);
                        continue;
                }
+               if (!strcmp(arg, "--inaccurate-eof")) {
+                       inaccurate_eof = 1;
+                       continue;
+               }
 
                if (check_index && prefix_length < 0) {
                        prefix = setup_git_directory();
@@ -2281,12 +2288,12 @@ int cmd_apply(int argc, const char **argv, char **envp)
                        usage(apply_usage);
                read_stdin = 0;
                set_default_whitespace_mode(whitespace_option);
-               apply_patch(fd, arg);
+               apply_patch(fd, arg, inaccurate_eof);
                close(fd);
        }
        set_default_whitespace_mode(whitespace_option);
        if (read_stdin)
-               apply_patch(0, "<stdin>");
+               apply_patch(0, "<stdin>", inaccurate_eof);
        if (whitespace_error) {
                if (squelch_whitespace_errors &&
                    squelch_whitespace_errors < whitespace_error) {
index 5a8a50b81dabea4ccd9b0ba0fcb5d925a00560d0..44d2d136f585a74e462556a4f756c7a297cadd51 100644 (file)
@@ -115,7 +115,7 @@ static void reopen_stdout(struct commit *commit, int nr, int keep_subject)
        int len = 0;
 
        if (output_directory) {
-               safe_strncpy(filename, output_directory, 1010);
+               strlcpy(filename, output_directory, 1010);
                len = strlen(filename);
                if (filename[len - 1] != '/')
                        filename[len++] = '/';
index 39a61b629367df9dd274acf5fa310b45dd06f126..f2e48aae2a04822d26d255dddf36002f58f2093c 100644 (file)
@@ -233,8 +233,8 @@ static void write_entry(const unsigned char *sha1, struct strbuf *path,
        /* XXX: should we provide more meaningful info here? */
        sprintf(header.uid, "%07o", 0);
        sprintf(header.gid, "%07o", 0);
-       safe_strncpy(header.uname, "git", sizeof(header.uname));
-       safe_strncpy(header.gname, "git", sizeof(header.gname));
+       strlcpy(header.uname, "git", sizeof(header.uname));
+       strlcpy(header.gname, "git", sizeof(header.gname));
        sprintf(header.devmajor, "%07o", 0);
        sprintf(header.devminor, "%07o", 0);
 
diff --git a/cache.h b/cache.h
index efeafea70f61a8496cfd6fd6405793459d3df7a9..87199396a05fbbbb695379119535eb9eefae2514 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -181,7 +181,6 @@ extern int assume_unchanged;
 extern int prefer_symlink_refs;
 extern int log_all_ref_updates;
 extern int warn_ambiguous_refs;
-extern int diff_rename_limit_default;
 extern int shared_repository;
 extern const char *apply_default_whitespace;
 
@@ -216,7 +215,6 @@ enum sharedrepo {
 int git_config_perm(const char *var, const char *value);
 int adjust_shared_perm(const char *path);
 int safe_create_leading_directories(char *path);
-size_t safe_strncpy(char *, const char *, size_t);
 char *enter_repo(char *path, int strict);
 
 /* Read and unpack a sha1 file into memory, write memory to a sha1 file */
diff --git a/compat/strlcpy.c b/compat/strlcpy.c
new file mode 100644 (file)
index 0000000..b66856a
--- /dev/null
@@ -0,0 +1,13 @@
+#include <string.h>
+
+size_t gitstrlcpy(char *dest, const char *src, size_t size)
+{
+       size_t ret = strlen(src);
+
+       if (size) {
+               size_t len = (ret >= size) ? size - 1 : ret;
+               memcpy(dest, src, len);
+               dest[len] = '\0';
+       }
+       return ret;
+}
index 3e077d4c6ca4f7162e3a3254e1b3e90db33270ff..ec44827da4afbcf89a5eed37c7f557a7ffdce35d 100644 (file)
--- a/config.c
+++ b/config.c
@@ -280,17 +280,17 @@ int git_default_config(const char *var, const char *value)
        }
 
        if (!strcmp(var, "user.name")) {
-               safe_strncpy(git_default_name, value, sizeof(git_default_name));
+               strlcpy(git_default_name, value, sizeof(git_default_name));
                return 0;
        }
 
        if (!strcmp(var, "user.email")) {
-               safe_strncpy(git_default_email, value, sizeof(git_default_email));
+               strlcpy(git_default_email, value, sizeof(git_default_email));
                return 0;
        }
 
        if (!strcmp(var, "i18n.commitencoding")) {
-               safe_strncpy(git_commit_encoding, value, sizeof(git_commit_encoding));
+               strlcpy(git_commit_encoding, value, sizeof(git_commit_encoding));
                return 0;
        }
 
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 1db0285cd740da87b1c0f9d3a32ba429f19cad74..fbb6c26cd9266e0ae453bb6c321f52d4996446a6 100644 (file)
--- a/diff.c
+++ b/diff.c
 
 static int use_size_cache;
 
-int diff_rename_limit_default = -1;
-
-int git_diff_config(const char *var, const char *value)
-{
-       if (!strcmp(var, "diff.renamelimit")) {
-               diff_rename_limit_default = git_config_int(var, value);
-               return 0;
-       }
-
-       return git_default_config(var, value);
-}
+static int diff_rename_limit_default = -1;
+static int diff_use_color_default = 0;
 
 enum color_diff {
        DIFF_RESET = 0,
@@ -51,9 +42,6 @@ enum color_diff {
 #define COLOR_CYAN    "\033[36m"
 #define COLOR_WHITE   "\033[37m"
 
-#define COLOR_CYANBG  "\033[46m"
-#define COLOR_GRAYBG  "\033[47m"       // Good for xterm
-
 static const char *diff_colors[] = {
        [DIFF_RESET]    = COLOR_RESET,
        [DIFF_PLAIN]    = COLOR_NORMAL,
@@ -63,6 +51,83 @@ static const char *diff_colors[] = {
        [DIFF_FILE_NEW] = COLOR_GREEN,
 };
 
+static int parse_diff_color_slot(const char *var, int ofs)
+{
+       if (!strcasecmp(var+ofs, "plain"))
+               return DIFF_PLAIN;
+       if (!strcasecmp(var+ofs, "meta"))
+               return DIFF_METAINFO;
+       if (!strcasecmp(var+ofs, "frag"))
+               return DIFF_FRAGINFO;
+       if (!strcasecmp(var+ofs, "old"))
+               return DIFF_FILE_OLD;
+       if (!strcasecmp(var+ofs, "new"))
+               return DIFF_FILE_NEW;
+       die("bad config variable '%s'", var);
+}
+
+static const char *parse_diff_color_value(const char *value, const char *var)
+{
+       if (!strcasecmp(value, "normal"))
+               return COLOR_NORMAL;
+       if (!strcasecmp(value, "bold"))
+               return COLOR_BOLD;
+       if (!strcasecmp(value, "dim"))
+               return COLOR_DIM;
+       if (!strcasecmp(value, "ul"))
+               return COLOR_UL;
+       if (!strcasecmp(value, "blink"))
+               return COLOR_BLINK;
+       if (!strcasecmp(value, "reverse"))
+               return COLOR_REVERSE;
+       if (!strcasecmp(value, "reset"))
+               return COLOR_RESET;
+       if (!strcasecmp(value, "black"))
+               return COLOR_BLACK;
+       if (!strcasecmp(value, "red"))
+               return COLOR_RED;
+       if (!strcasecmp(value, "green"))
+               return COLOR_GREEN;
+       if (!strcasecmp(value, "yellow"))
+               return COLOR_YELLOW;
+       if (!strcasecmp(value, "blue"))
+               return COLOR_BLUE;
+       if (!strcasecmp(value, "magenta"))
+               return COLOR_MAGENTA;
+       if (!strcasecmp(value, "cyan"))
+               return COLOR_CYAN;
+       if (!strcasecmp(value, "white"))
+               return COLOR_WHITE;
+       die("bad config value '%s' for variable '%s'", value, var);
+}
+
+int git_diff_config(const char *var, const char *value)
+{
+       if (!strcmp(var, "diff.renamelimit")) {
+               diff_rename_limit_default = git_config_int(var, value);
+               return 0;
+       }
+       if (!strcmp(var, "diff.color")) {
+               if (!value)
+                       diff_use_color_default = 1; /* bool */
+               else if (!strcasecmp(value, "auto"))
+                       diff_use_color_default = isatty(1);
+               else if (!strcasecmp(value, "never"))
+                       diff_use_color_default = 0;
+               else if (!strcasecmp(value, "always"))
+                       diff_use_color_default = 1;
+               else
+                       diff_use_color_default = git_config_bool(var, value);
+               return 0;
+       }
+       if (!strncmp(var, "diff.color.", 11)) {
+               int slot = parse_diff_color_slot(var, 11);
+               diff_colors[slot] = parse_diff_color_value(value, var);
+               return 0;
+       }
+       return git_default_config(var, value);
+}
+
 static char *quote_one(const char *str)
 {
        int needlen;
@@ -203,7 +268,7 @@ static void emit_rewrite_diff(const char *name_a,
 static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
 {
        if (!DIFF_FILE_VALID(one)) {
-               mf->ptr = ""; /* does not matter */
+               mf->ptr = (char *)""; /* does not matter */
                mf->size = 0;
                return 0;
        }
@@ -395,7 +460,7 @@ static void show_stats(struct diffstat_t* data)
        }
 
        for (i = 0; i < data->nr; i++) {
-               char *prefix = "";
+               const char *prefix = "";
                char *name = data->files[i]->name;
                int added = data->files[i]->added;
                int deleted = data->files[i]->deleted;
@@ -616,7 +681,7 @@ static void builtin_diff(const char *name_a,
        const char *lbl[2];
        char *a_one, *b_two;
        const char *set = get_color(o->color_diff, DIFF_METAINFO);
-       const char *reset = get_color(o->color_diff, DIFF_PLAIN);
+       const char *reset = get_color(o->color_diff, DIFF_RESET);
 
        a_one = quote_two("a/", name_a);
        b_two = quote_two("b/", name_b);
@@ -678,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)
@@ -703,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;
@@ -732,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;
@@ -917,7 +983,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
                        err_empty:
                                err = -1;
                        empty:
-                               s->data = "";
+                               s->data = (char *)"";
                                s->size = 0;
                                return err;
                        }
@@ -1317,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;
        }
 
@@ -1329,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)
@@ -1362,6 +1428,7 @@ void diff_setup(struct diff_options *options)
 
        options->change = diff_change;
        options->add_remove = diff_addremove;
+       options->color_diff = diff_use_color_default;
 }
 
 int diff_setup_done(struct diff_options *options)
@@ -1408,7 +1475,7 @@ int diff_setup_done(struct diff_options *options)
        return 0;
 }
 
-int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
+static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
 {
        char c, *eq;
        int len;
@@ -1534,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;
@@ -1720,16 +1791,12 @@ static void diff_flush_raw(struct diff_filepair *p,
                free((void*)path_two);
 }
 
-static void diff_flush_name(struct diff_filepair *p,
-                           int inter_name_termination,
-                           int line_termination)
+static void diff_flush_name(struct diff_filepair *p, int line_termination)
 {
        char *path = p->two->path;
 
        if (line_termination)
                path = quote_one(p->two->path);
-       else
-               path = p->two->path;
        printf("%s%c", path, line_termination);
        if (p->two->path != path)
                free(path);
@@ -1950,9 +2017,7 @@ static void flush_one_pair(struct diff_filepair *p,
                                       options, diff_output_format);
                        break;
                case DIFF_FORMAT_NAME:
-                       diff_flush_name(p,
-                                       inter_name_termination,
-                                       line_termination);
+                       diff_flush_name(p, line_termination);
                        break;
                case DIFF_FORMAT_NO_OUTPUT:
                        break;
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;
index 9f49651cfdce101af3ba2c1980121d9ccea8a194..d7f3ade493762140c9a5a888ac67f8435e737f10 100755 (executable)
@@ -696,13 +696,18 @@ t)
        fi
 esac
 
-sed -e '
-    /^diff --git a\/.*/{
-       s///
-       q
-    }
-    /^#/d
-' "$GIT_DIR"/COMMIT_EDITMSG |
+if test -z "$no_edit"
+then
+    sed -e '
+        /^diff --git a\/.*/{
+           s///
+           q
+       }
+       /^#/d
+    ' "$GIT_DIR"/COMMIT_EDITMSG
+else
+    cat "$GIT_DIR"/COMMIT_EDITMSG
+fi |
 git-stripspace >"$GIT_DIR"/COMMIT_MSG
 
 if cnt=`grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
index b3d4cf532e5728e6b962d0d65789f6e8e4bd7fe5..93f558056dec457570bf2867dc6c75cd5891d2f2 100644 (file)
@@ -79,6 +79,11 @@ extern void gitunsetenv(const char *);
 extern char *gitstrcasestr(const char *haystack, const char *needle);
 #endif
 
+#ifdef NO_STRLCPY
+#define strlcpy gitstrlcpy
+extern size_t gitstrlcpy(char *, const char *, size_t);
+#endif
+
 static inline void *xmalloc(size_t size)
 {
        void *ret = malloc(size);
old mode 100644 (file)
new mode 100755 (executable)
index f3daa6c..50f5d96
@@ -17,7 +17,7 @@
 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 @@ ($$)
 $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 @@ ($$)
 
        # 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 @@ sub commit {
                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 4fb3f26e834f78d40ea629dcd6732d390a129d58..eb75c8cda95dabe190cfe9ddba0c6bd7072615f2 100755 (executable)
@@ -49,8 +49,9 @@ name=$(git-rev-list --objects --all $rev_list 2>&1 |
 if [ -z "$name" ]; then
        echo Nothing new to pack.
 else
-       echo "Pack pack-$name created."
-
+       if test "$quiet" != '-q'; then
+           echo "Pack pack-$name created."
+       fi
        mkdir -p "$PACKDIR" || exit
 
        mv .tmp-pack-$name.pack "$PACKDIR/pack-$name.pack" &&
index 2b63d89501cc8838cca96506b3532d33fc452a15..44eba5fd0df292255dce056ec5aa700186096b39 100644 (file)
@@ -584,8 +584,8 @@ static void process_alternates_response(void *callback_data)
                        // skip 'objects' at end
                        if (okay) {
                                target = xmalloc(serverlen + posn - i - 6);
-                               safe_strncpy(target, base, serverlen);
-                               safe_strncpy(target + serverlen, data + i, posn - i - 6);
+                               strlcpy(target, base, serverlen);
+                               strlcpy(target + serverlen, data + i, posn - i - 6);
                                if (get_verbosely)
                                        fprintf(stderr,
                                                "Also look at %s\n", target);
@@ -727,7 +727,7 @@ xml_cdata(void *userData, const XML_Char *s, int len)
        if (ctx->cdata)
                free(ctx->cdata);
        ctx->cdata = xmalloc(len + 1);
-       safe_strncpy(ctx->cdata, s, len + 1);
+       strlcpy(ctx->cdata, s, len + 1);
 }
 
 static int remote_ls(struct alt_base *repo, const char *path, int flags,
index 8d472f0202827db726ede451be3fd63940c38c96..3c89a17496dcc72fa8773a0308281364bbf647a8 100644 (file)
@@ -1271,7 +1271,7 @@ xml_cdata(void *userData, const XML_Char *s, int len)
        if (ctx->cdata)
                free(ctx->cdata);
        ctx->cdata = xmalloc(len + 1);
-       safe_strncpy(ctx->cdata, s, len + 1);
+       strlcpy(ctx->cdata, s, len + 1);
 }
 
 static struct remote_lock *lock_remote(char *path, long timeout)
@@ -1473,7 +1473,7 @@ static void process_ls_object(struct remote_ls_ctx *ls)
                return;
        path += 8;
        obj_hex = xmalloc(strlen(path));
-       safe_strncpy(obj_hex, path, 3);
+       strlcpy(obj_hex, path, 3);
        strcpy(obj_hex + 2, path + 3);
        one_remote_object(obj_hex);
        free(obj_hex);
@@ -2172,7 +2172,7 @@ static void fetch_symref(char *path, char **symref, unsigned char *sha1)
        /* If it's a symref, set the refname; otherwise try for a sha1 */
        if (!strncmp((char *)buffer.buffer, "ref: ", 5)) {
                *symref = xmalloc(buffer.posn - 5);
-               safe_strncpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 5);
+               strlcpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 5);
        } else {
                get_sha1_hex(buffer.buffer, sha1);
        }
diff --git a/ident.c b/ident.c
index 7b44cbd2cc54c049518b9fb1cb681a88c7aaa6c4..efec97ffd0a9f3aa6573f3476c749d38d6fc388c 100644 (file)
--- a/ident.c
+++ b/ident.c
@@ -71,9 +71,9 @@ int setup_ident(void)
                len = strlen(git_default_email);
                git_default_email[len++] = '.';
                if (he && (domainname = strchr(he->h_name, '.')))
-                       safe_strncpy(git_default_email + len, domainname + 1, sizeof(git_default_email) - len);
+                       strlcpy(git_default_email + len, domainname + 1, sizeof(git_default_email) - len);
                else
-                       safe_strncpy(git_default_email + len, "(none)", sizeof(git_default_email) - len);
+                       strlcpy(git_default_email + len, "(none)", sizeof(git_default_email) - len);
        }
        /* And set the default date */
        datestamp(git_default_date, sizeof(git_default_date));
index 190e12fb7ceeb012a063f8c97b574e9650d95cc1..0498a6f45e53947e356c6a390869d3f8194f05b7 100644 (file)
@@ -1,5 +1,6 @@
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <signal.h>
 
 #include "cache.h"
 
diff --git a/path.c b/path.c
index 36972fd6df63b3c4eebdcf89238df8ade60d53c3..db8905f3c352592124b2f0bda18fc0ccd048528e 100644 (file)
--- a/path.c
+++ b/path.c
@@ -77,25 +77,12 @@ int git_mkstemp(char *path, size_t len, const char *template)
                pch += n;
        }
 
-       safe_strncpy(pch, template, len);
+       strlcpy(pch, template, len);
 
        return mkstemp(path);
 }
 
 
-size_t safe_strncpy(char *dest, const char *src, size_t size)
-{
-       size_t ret = strlen(src);
-
-       if (size) {
-               size_t len = (ret >= size) ? size - 1 : ret;
-               memcpy(dest, src, len);
-               dest[len] = '\0';
-       }
-       return ret;
-}
-
-
 int validate_symref(const char *path)
 {
        struct stat st;
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 ab8f1afeea0cbff7707e313af1c18ff56363ae09..743f02b7de7b3b819d3db29ddfcdcf8ebacaccc4 100644 (file)
@@ -29,16 +29,13 @@ static int show_config(const char* key_, const char* value_)
        const char *vptr = value;
        int dup_error = 0;
 
-       if (value_ == NULL)
-               value_ = "";
-
        if (!use_key_regexp && strcmp(key_, key))
                return 0;
        if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
                return 0;
        if (regexp != NULL &&
                         (do_not_match ^
-                         regexec(regexp, value_, 0, NULL, 0)))
+                         regexec(regexp, (value_?value_:""), 0, NULL, 0)))
                return 0;
 
        if (show_keys)
@@ -46,11 +43,11 @@ static int show_config(const char* key_, const char* value_)
        if (seen && !do_all)
                dup_error = 1;
        if (type == T_INT)
-               sprintf(value, "%d", git_config_int(key_, value_));
+               sprintf(value, "%d", git_config_int(key_, value_?value_:""));
        else if (type == T_BOOL)
                vptr = git_config_bool(key_, value_) ? "true" : "false";
        else
-               vptr = value_;
+               vptr = value_?value_:"";
        seen++;
        if (dup_error) {
                error("More than one value for the key %s: %s",
index cd85d1fa0f9f2afb4e159cb635db435e75ef3e58..f2cbafa496231e7a9cdbbea2ab4e7d4c4ed761ab 100644 (file)
@@ -262,7 +262,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
                if (str[am] == '@' && str[am+1] == '{' && str[len-1] == '}') {
                        int date_len = len - am - 3;
                        char *date_spec = xmalloc(date_len + 1);
-                       safe_strncpy(date_spec, str + am + 2, date_len + 1);
+                       strlcpy(date_spec, str + am + 2, date_len + 1);
                        at_time = approxidate(date_spec);
                        free(date_spec);
                        len = am;
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);