]> git.ipfire.org Git - thirdparty/git.git/blobdiff - line-range.c
line-range: teach -L/RE/ to search relative to anchor point
[thirdparty/git.git] / line-range.c
index 69e8d6b6c02101b4243e1850aa52c377ccaa0a2b..bbf3c0f4481e9dd762d6a55e531cb983bbcbaff1 100644 (file)
@@ -6,6 +6,18 @@
 
 /*
  * Parse one item in the -L option
+ *
+ * 'begin' is applicable only to relative range anchors. Absolute anchors
+ * ignore this value.
+ *
+ * When parsing "-L A,B", parse_loc() is called once for A and once for B.
+ *
+ * When parsing A, 'begin' must be a negative number, the absolute value of
+ * which is the line at which relative start-of-range anchors should be
+ * based. Beginning of file is represented by -1.
+ *
+ * When parsing B, 'begin' must be the positive line number immediately
+ * following the line computed for 'A'.
  */
 static const char *parse_loc(const char *spec, nth_line_fn_t nth_line,
                             void *data, long lines, long begin, long *ret)
@@ -46,6 +58,10 @@ static const char *parse_loc(const char *spec, nth_line_fn_t nth_line,
                        *ret = num;
                return term;
        }
+
+       if (begin < 0)
+               begin = -begin;
+
        if (spec[0] != '/')
                return spec;
 
@@ -85,7 +101,8 @@ static const char *parse_loc(const char *spec, nth_line_fn_t nth_line,
        else {
                char errbuf[1024];
                regerror(reg_error, &regexp, errbuf, 1024);
-               die("-L parameter '%s': %s", spec + 1, errbuf);
+               die("-L parameter '%s' starting at line %ld: %s",
+                   spec + 1, begin + 1, errbuf);
        }
 }
 
@@ -210,11 +227,16 @@ 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 *begin, long *end,
-                   const char *path)
+                   void *cb_data, long lines, long anchor,
+                   long *begin, long *end, const char *path)
 {
        *begin = *end = 0;
 
+       if (anchor < 1)
+               anchor = 1;
+       if (anchor > lines)
+               anchor = lines + 1;
+
        if (*arg == ':') {
                arg = parse_range_funcname(arg, nth_line_cb, cb_data, lines, begin, end, path);
                if (!arg || *arg)
@@ -222,7 +244,7 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
                return 0;
        }
 
-       arg = parse_loc(arg, nth_line_cb, cb_data, lines, 1, begin);
+       arg = parse_loc(arg, nth_line_cb, cb_data, lines, -anchor, begin);
 
        if (*arg == ',')
                arg = parse_loc(arg + 1, nth_line_cb, cb_data, lines, *begin + 1, end);