2121#include "parse-options.h"
2222#include "utf8.h"
2323#include "userdiff.h"
24+ #include "line-range.h"
2425
2526static char blame_usage [] = N_ ("git blame [options] [rev-opts] [rev] [--] file" );
2627
@@ -566,11 +567,16 @@ static void dup_entry(struct blame_entry *dst, struct blame_entry *src)
566567 dst -> score = 0 ;
567568}
568569
569- static const char * nth_line (struct scoreboard * sb , int lno )
570+ static const char * nth_line (struct scoreboard * sb , long lno )
570571{
571572 return sb -> final_buf + sb -> lineno [lno ];
572573}
573574
575+ static const char * nth_line_cb (void * data , long lno )
576+ {
577+ return nth_line ((struct scoreboard * )data , lno );
578+ }
579+
574580/*
575581 * It is known that lines between tlno to same came from parent, and e
576582 * has an overlap with that range. it also is known that parent's
@@ -1931,83 +1937,6 @@ static const char *add_prefix(const char *prefix, const char *path)
19311937 return prefix_path (prefix , prefix ? strlen (prefix ) : 0 , path );
19321938}
19331939
1934- /*
1935- * Parsing of (comma separated) one item in the -L option
1936- */
1937- static const char * parse_loc (const char * spec ,
1938- struct scoreboard * sb , long lno ,
1939- long begin , long * ret )
1940- {
1941- char * term ;
1942- const char * line ;
1943- long num ;
1944- int reg_error ;
1945- regex_t regexp ;
1946- regmatch_t match [1 ];
1947-
1948- /* Allow "-L <something>,+20" to mean starting at <something>
1949- * for 20 lines, or "-L <something>,-5" for 5 lines ending at
1950- * <something>.
1951- */
1952- if (1 < begin && (spec [0 ] == '+' || spec [0 ] == '-' )) {
1953- num = strtol (spec + 1 , & term , 10 );
1954- if (term != spec + 1 ) {
1955- if (spec [0 ] == '-' )
1956- num = 0 - num ;
1957- if (0 < num )
1958- * ret = begin + num - 2 ;
1959- else if (!num )
1960- * ret = begin ;
1961- else
1962- * ret = begin + num ;
1963- return term ;
1964- }
1965- return spec ;
1966- }
1967- num = strtol (spec , & term , 10 );
1968- if (term != spec ) {
1969- * ret = num ;
1970- return term ;
1971- }
1972- if (spec [0 ] != '/' )
1973- return spec ;
1974-
1975- /* it could be a regexp of form /.../ */
1976- for (term = (char * ) spec + 1 ; * term && * term != '/' ; term ++ ) {
1977- if (* term == '\\' )
1978- term ++ ;
1979- }
1980- if (* term != '/' )
1981- return spec ;
1982-
1983- /* try [spec+1 .. term-1] as regexp */
1984- * term = 0 ;
1985- begin -- ; /* input is in human terms */
1986- line = nth_line (sb , begin );
1987-
1988- if (!(reg_error = regcomp (& regexp , spec + 1 , REG_NEWLINE )) &&
1989- !(reg_error = regexec (& regexp , line , 1 , match , 0 ))) {
1990- const char * cp = line + match [0 ].rm_so ;
1991- const char * nline ;
1992-
1993- while (begin ++ < lno ) {
1994- nline = nth_line (sb , begin );
1995- if (line <= cp && cp < nline )
1996- break ;
1997- line = nline ;
1998- }
1999- * ret = begin ;
2000- regfree (& regexp );
2001- * term ++ = '/' ;
2002- return term ;
2003- }
2004- else {
2005- char errbuf [1024 ];
2006- regerror (reg_error , & regexp , errbuf , 1024 );
2007- die ("-L parameter '%s': %s" , spec + 1 , errbuf );
2008- }
2009- }
2010-
20111940/*
20121941 * Parsing of -L option
20131942 */
@@ -2016,15 +1945,7 @@ static void prepare_blame_range(struct scoreboard *sb,
20161945 long lno ,
20171946 long * bottom , long * top )
20181947{
2019- const char * term ;
2020-
2021- term = parse_loc (bottomtop , sb , lno , 1 , bottom );
2022- if (* term == ',' ) {
2023- term = parse_loc (term + 1 , sb , lno , * bottom + 1 , top );
2024- if (* term )
2025- usage (blame_usage );
2026- }
2027- if (* term )
1948+ if (parse_range_arg (bottomtop , nth_line_cb , sb , lno , bottom , top , sb -> path ))
20281949 usage (blame_usage );
20291950}
20301951
@@ -2574,10 +2495,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
25742495 bottom = top = 0 ;
25752496 if (bottomtop )
25762497 prepare_blame_range (& sb , bottomtop , lno , & bottom , & top );
2577- if (bottom && top && top < bottom ) {
2578- long tmp ;
2579- tmp = top ; top = bottom ; bottom = tmp ;
2580- }
25812498 if (bottom < 1 )
25822499 bottom = 1 ;
25832500 if (top < 1 )
0 commit comments