21
#include "parse-options.h"
22
#include "utf8.h"
23
#include "userdiff.h"
24
+#include "line-range.h"
25
26
static char blame_usage[] = N_("git blame [options] [rev-opts] [rev] [--] file");
27
567
dst->score = 0;
568
}
569
569
-static const char *nth_line(struct scoreboard *sb, int lno)
570
+static const char *nth_line(struct scoreboard *sb, long lno)
571
{
572
return sb->final_buf + sb->lineno[lno];
573
}
574
575
+static const char *nth_line_cb(void *data, long lno)
576
+{
577
+ return nth_line((struct scoreboard *)data, lno);
578
+}
579
+
580
/*
581
* It is known that lines between tlno to same came from parent, and e
582
* has an overlap with that range. it also is known that parent's
1932
return prefix_path(prefix, prefix ? strlen(prefix) : 0, path);
1933
}
1934
1929
-/*
1930
- * Parsing of (comma separated) one item in the -L option
1931
- */
1932
-static const char *parse_loc(const char *spec,
1933
- struct scoreboard *sb, long lno,
1934
- long begin, long *ret)
1935
-{
1936
- char *term;
1937
- const char *line;
1938
- long num;
1939
- int reg_error;
1940
- regex_t regexp;
1941
- regmatch_t match[1];
1942
-
1943
- /* Allow "-L <something>,+20" to mean starting at <something>
1944
- * for 20 lines, or "-L <something>,-5" for 5 lines ending at
1945
- * <something>.
1946
- */
1947
- if (1 < begin && (spec[0] == '+' || spec[0] == '-')) {
1948
- num = strtol(spec + 1, &term, 10);
1949
- if (term != spec + 1) {
1950
- if (spec[0] == '-')
1951
- num = 0 - num;
1952
- if (0 < num)
1953
- *ret = begin + num - 2;
1954
- else if (!num)
1955
- *ret = begin;
1956
- else
1957
- *ret = begin + num;
1958
- return term;
1959
- }
1960
- return spec;
1961
- }
1962
- num = strtol(spec, &term, 10);
1963
- if (term != spec) {
1964
- *ret = num;
1965
- return term;
1966
- }
1967
- if (spec[0] != '/')
1968
- return spec;
1969
-
1970
- /* it could be a regexp of form /.../ */
1971
- for (term = (char *) spec + 1; *term && *term != '/'; term++) {
1972
- if (*term == '\\')
1973
- term++;
1974
- }
1975
- if (*term != '/')
1976
- return spec;
1977
-
1978
- /* try [spec+1 .. term-1] as regexp */
1979
- *term = 0;
1980
- begin--; /* input is in human terms */
1981
- line = nth_line(sb, begin);
1982
-
1983
- if (!(reg_error = regcomp(®exp, spec + 1, REG_NEWLINE)) &&
1984
- !(reg_error = regexec(®exp, line, 1, match, 0))) {
1985
- const char *cp = line + match[0].rm_so;
1986
- const char *nline;
1987
-
1988
- while (begin++ < lno) {
1989
- nline = nth_line(sb, begin);
1990
- if (line <= cp && cp < nline)
1991
- break;
1992
- line = nline;
1993
- }
1994
- *ret = begin;
1995
- regfree(®exp);
1996
- *term++ = '/';
1997
- return term;
1998
- }
1999
- else {
2000
- char errbuf[1024];
2001
- regerror(reg_error, ®exp, errbuf, 1024);
2002
- die("-L parameter '%s': %s", spec + 1, errbuf);
2003
- }
2004
-}
2005
-
1935
/*
1936
* Parsing of -L option
1937
*/
1940
long lno,
1941
long *bottom, long *top)
1942
{
2014
- const char *term;
2015
-
2016
- term = parse_loc(bottomtop, sb, lno, 1, bottom);
2017
- if (*term == ',') {
2018
- term = parse_loc(term + 1, sb, lno, *bottom + 1, top);
2019
- if (*term)
2020
- usage(blame_usage);
2021
- }
2022
- if (*term)
1943
+ if (parse_range_arg(bottomtop, nth_line_cb, sb, lno, bottom, top))
1944
usage(blame_usage);
1945
}
1946
2490
bottom = top = 0;
2491
if (bottomtop)
2492
prepare_blame_range(&sb, bottomtop, lno, &bottom, &top);
2572
- if (bottom && top && top < bottom) {
2573
- long tmp;
2574
- tmp = top; top = bottom; bottom = tmp;
2575
- }
2493
if (bottom < 1)
2494
bottom = 1;
2495
if (top < 1)