diff: allow --no-color-moved-ws
[gitweb.git] / line-range.c
index 4bae4bff212817a443f1cc6c0b124fb1bcd263b1..9b50583dc05147fb6940c1d551ba274702704f07 100644 (file)
@@ -47,15 +47,18 @@ static const char *parse_loc(const char *spec, nth_line_fn_t nth_line,
                        else if (!num)
                                *ret = begin;
                        else
-                               *ret = begin + num;
+                               *ret = begin + num > 0 ? begin + num : 1;
                        return term;
                }
                return spec;
        }
        num = strtol(spec, &term, 10);
        if (term != spec) {
-               if (ret)
+               if (ret) {
+                       if (num <= 0)
+                               die("-L invalid line number: %ld", num);
                        *ret = num;
+               }
                return term;
        }
 
@@ -160,9 +163,10 @@ static const char *find_funcname_matching_regexp(xdemitconf_t *xecfg, const char
        }
 }
 
-static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_cb,
-                                       void *cb_data, long lines, long anchor, long *begin, long *end,
-                                       const char *path)
+static const char *parse_range_funcname(
+       const char *arg, nth_line_fn_t nth_line_cb,
+       void *cb_data, long lines, long anchor, long *begin, long *end,
+       const char *path, struct index_state *istate)
 {
        char *pattern;
        const char *term;
@@ -173,6 +177,11 @@ static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_
        int reg_error;
        regex_t regexp;
 
+       if (*arg == '^') {
+               anchor = 1;
+               arg++;
+       }
+
        assert(*arg == ':');
        term = arg+1;
        while (*term && *term != ':') {
@@ -190,7 +199,7 @@ static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_
        anchor--; /* input is in human terms */
        start = nth_line_cb(cb_data, anchor);
 
-       drv = userdiff_find_by_path(path);
+       drv = userdiff_find_by_path(istate, path);
        if (drv && drv->funcname.pattern) {
                const struct userdiff_funcname *pe = &drv->funcname;
                xecfg = xcalloc(1, sizeof(*xecfg));
@@ -236,7 +245,8 @@ static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_
 
 int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
                    void *cb_data, long lines, long anchor,
-                   long *begin, long *end, const char *path)
+                   long *begin, long *end,
+                   const char *path, struct index_state *istate)
 {
        *begin = *end = 0;
 
@@ -245,8 +255,10 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
        if (anchor > lines)
                anchor = lines + 1;
 
-       if (*arg == ':') {
-               arg = parse_range_funcname(arg, nth_line_cb, cb_data, lines, anchor, begin, end, path);
+       if (*arg == ':' || (*arg == '^' && *(arg + 1) == ':')) {
+               arg = parse_range_funcname(arg, nth_line_cb, cb_data,
+                                          lines, anchor, begin, end,
+                                          path, istate);
                if (!arg || *arg)
                        return -1;
                return 0;
@@ -261,17 +273,18 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
                return -1;
 
        if (*begin && *end && *end < *begin) {
-               long tmp;
-               tmp = *end; *end = *begin; *begin = tmp;
+               SWAP(*end, *begin);
        }
 
        return 0;
 }
 
-const char *skip_range_arg(const char *arg)
+const char *skip_range_arg(const char *arg, struct index_state *istate)
 {
-       if (*arg == ':')
-               return parse_range_funcname(arg, NULL, NULL, 0, 0, NULL, NULL, NULL);
+       if (*arg == ':' || (*arg == '^' && *(arg + 1) == ':'))
+               return parse_range_funcname(arg, NULL, NULL,
+                                           0, 0, NULL, NULL,
+                                           NULL, istate);
 
        arg = parse_loc(arg, NULL, NULL, 0, -1, NULL);