| 164 | } |
| 165 | |
| 166 | static const char *parse_range_funcname( |
| 167 | const char *arg, nth_line_fn_t nth_line_cb, |
| 168 | void *cb_data, long lines, long anchor, long *begin, long *end, |
| 169 | const char *path, struct index_state *istate) |
| 170 | { |
| 171 | char *pattern; |
| 172 | const char *term; |
| 173 | struct userdiff_driver *drv; |
| 174 | xdemitconf_t *xecfg = NULL; |
| 175 | const char *start; |
| 176 | const char *p; |
| 177 | int reg_error; |
| 178 | regex_t regexp; |
| 179 | |
| 180 | if (*arg == '^') { |
| 181 | anchor = 1; |
| 182 | arg++; |
| 183 | } |
| 184 | |
| 185 | assert(*arg == ':'); |
| 186 | term = arg+1; |
| 187 | while (*term && *term != ':') { |
| 188 | if (*term == '\\' && *(term+1)) |
| 189 | term++; |
| 190 | term++; |
| 191 | } |
| 192 | if (term == arg+1) |
| 193 | return NULL; |
| 194 | if (!begin) /* skip_range_arg case */ |
| 195 | return term; |
| 196 | |
| 197 | pattern = xstrndup(arg+1, term-(arg+1)); |
| 198 | |
| 199 | anchor--; /* input is in human terms */ |
| 200 | start = nth_line_cb(cb_data, anchor); |
| 201 | |
| 202 | drv = userdiff_find_by_path(istate, path); |
| 203 | if (drv && drv->funcname.pattern) { |
| 204 | const struct userdiff_funcname *pe = &drv->funcname; |
| 205 | CALLOC_ARRAY(xecfg, 1); |
| 206 | xdiff_set_find_func(xecfg, pe->pattern, pe->cflags); |
| 207 | } |
| 208 | |
| 209 | reg_error = regcomp(®exp, pattern, REG_NEWLINE); |
| 210 | if (reg_error) { |
| 211 | char errbuf[1024]; |
| 212 | regerror(reg_error, ®exp, errbuf, 1024); |
| 213 | die("-L parameter '%s': %s", pattern, errbuf); |
| 214 | } |
| 215 | |
| 216 | p = find_funcname_matching_regexp(xecfg, (char*) start, ®exp); |
| 217 | if (!p) |
| 218 | die("-L parameter '%s' starting at line %ld: no match", |
| 219 | pattern, anchor + 1); |
| 220 | *begin = 0; |
| 221 | while (p > nth_line_cb(cb_data, *begin)) |
| 222 | (*begin)++; |
| 223 |
no test coverage detected