1248
return hit;
1249
}
1250
1251
-static int match_expr_eval(struct grep_expr *x, char *bol, char *eol,
1252
- enum grep_context ctx, int collect_hits)
1251
+static int match_expr_eval(struct grep_opt *opt, struct grep_expr *x, char *bol,
1252
+ char *eol, enum grep_context ctx, ssize_t *col,
1253
+ ssize_t *icol, int collect_hits)
1254
{
1255
int h = 0;
1255
- regmatch_t match;
1256
1257
if (!x)
1258
die("Not a valid grep expression");
1261
h = 1;
1262
break;
1263
case GREP_NODE_ATOM:
1264
- h = match_one_pattern(x->u.atom, bol, eol, ctx, &match, 0);
1264
+ {
1265
+ regmatch_t tmp;
1266
+ h = match_one_pattern(x->u.atom, bol, eol, ctx,
1267
+ &tmp, 0);
1268
+ if (h && (*col < 0 || tmp.rm_so < *col))
1269
+ *col = tmp.rm_so;
1270
+ }
1271
break;
1272
case GREP_NODE_NOT:
1267
- h = !match_expr_eval(x->u.unary, bol, eol, ctx, 0);
1273
+ /*
1274
+ * Upon visiting a GREP_NODE_NOT, col and icol become swapped.
1275
+ */
1276
+ h = !match_expr_eval(opt, x->u.unary, bol, eol, ctx, icol, col,
1277
+ 0);
1278
break;
1279
case GREP_NODE_AND:
1270
- if (!match_expr_eval(x->u.binary.left, bol, eol, ctx, 0))
1280
+ if (!match_expr_eval(opt, x->u.binary.left, bol, eol, ctx, col,
1281
+ icol, 0))
1282
return 0;
1272
- h = match_expr_eval(x->u.binary.right, bol, eol, ctx, 0);
1283
+ h = match_expr_eval(opt, x->u.binary.right, bol, eol, ctx, col,
1284
+ icol, 0);
1285
break;
1286
case GREP_NODE_OR:
1287
if (!collect_hits)
1276
- return (match_expr_eval(x->u.binary.left,
1277
- bol, eol, ctx, 0) ||
1278
- match_expr_eval(x->u.binary.right,
1279
- bol, eol, ctx, 0));
1280
- h = match_expr_eval(x->u.binary.left, bol, eol, ctx, 0);
1288
+ return (match_expr_eval(opt, x->u.binary.left, bol, eol,
1289
+ ctx, col, icol, 0) ||
1290
+ match_expr_eval(opt, x->u.binary.right, bol,
1291
+ eol, ctx, col, icol, 0));
1292
+ h = match_expr_eval(opt, x->u.binary.left, bol, eol, ctx, col,
1293
+ icol, 0);
1294
x->u.binary.left->hit |= h;
1282
- h |= match_expr_eval(x->u.binary.right, bol, eol, ctx, 1);
1295
+ h |= match_expr_eval(opt, x->u.binary.right, bol, eol, ctx, col,
1296
+ icol, 1);
1297
break;
1298
default:
1299
die("Unexpected node type (internal error) %d", x->node);
1304
}
1305
1306
static int match_expr(struct grep_opt *opt, char *bol, char *eol,
1293
- enum grep_context ctx, int collect_hits)
1307
+ enum grep_context ctx, ssize_t *col,
1308
+ ssize_t *icol, int collect_hits)
1309
{
1310
struct grep_expr *x = opt->pattern_expression;
1296
- return match_expr_eval(x, bol, eol, ctx, collect_hits);
1311
+ return match_expr_eval(opt, x, bol, eol, ctx, col, icol, collect_hits);
1312
}
1313
1314
static int match_line(struct grep_opt *opt, char *bol, char *eol,
1315
+ ssize_t *col, ssize_t *icol,
1316
enum grep_context ctx, int collect_hits)
1317
{
1318
struct grep_pat *p;
1303
- regmatch_t match;
1319
1320
if (opt->extended)
1306
- return match_expr(opt, bol, eol, ctx, collect_hits);
1321
+ return match_expr(opt, bol, eol, ctx, col, icol,
1322
+ collect_hits);
1323
1324
/* we do not call with collect_hits without being extended */
1325
for (p = opt->pattern_list; p; p = p->next) {
1310
- if (match_one_pattern(p, bol, eol, ctx, &match, 0))
1326
+ regmatch_t tmp;
1327
+ if (match_one_pattern(p, bol, eol, ctx, &tmp, 0)) {
1328
+ *col = tmp.rm_so;
1329
return 1;
1330
+ }
1331
}
1332
return 0;
1333
}
1782
while (left) {
1783
char *eol, ch;
1784
int hit;
1785
+ ssize_t col = -1, icol = -1;
1786
1787
/*
1788
* look_ahead() skips quickly to the line that possibly
1806
if ((ctx == GREP_CONTEXT_HEAD) && (eol == bol))
1807
ctx = GREP_CONTEXT_BODY;
1808
1789
- hit = match_line(opt, bol, eol, ctx, collect_hits);
1809
+ hit = match_line(opt, bol, eol, &col, &icol, ctx, collect_hits);
1810
*eol = ch;
1811
1812
if (collect_hits)