| 1038 | |
| 1039 | |
| 1040 | static int match_expr_eval(struct grep_opt *opt, struct grep_expr *x, |
| 1041 | const char *bol, const char *eol, |
| 1042 | enum grep_context ctx, ssize_t *col, |
| 1043 | ssize_t *icol, int collect_hits) |
| 1044 | { |
| 1045 | int h = 0; |
| 1046 | |
| 1047 | switch (x->node) { |
| 1048 | case GREP_NODE_TRUE: |
| 1049 | h = 1; |
| 1050 | break; |
| 1051 | case GREP_NODE_ATOM: |
| 1052 | { |
| 1053 | regmatch_t tmp; |
| 1054 | h = match_one_pattern(x->u.atom, bol, eol, ctx, |
| 1055 | &tmp, 0); |
| 1056 | if (h && (*col < 0 || tmp.rm_so < *col)) |
| 1057 | *col = tmp.rm_so; |
| 1058 | } |
| 1059 | if (x->u.atom->token == GREP_PATTERN_BODY) |
| 1060 | opt->body_hit |= h; |
| 1061 | break; |
| 1062 | case GREP_NODE_NOT: |
| 1063 | /* |
| 1064 | * Upon visiting a GREP_NODE_NOT, col and icol become swapped. |
| 1065 | */ |
| 1066 | h = !match_expr_eval(opt, x->u.unary, bol, eol, ctx, icol, col, |
| 1067 | 0); |
| 1068 | break; |
| 1069 | case GREP_NODE_AND: |
| 1070 | h = match_expr_eval(opt, x->u.binary.left, bol, eol, ctx, col, |
| 1071 | icol, 0); |
| 1072 | if (h || opt->columnnum) { |
| 1073 | /* |
| 1074 | * Don't short-circuit AND when given --column, since a |
| 1075 | * NOT earlier in the tree may turn this into an OR. In |
| 1076 | * this case, see the below comment. |
| 1077 | */ |
| 1078 | h &= match_expr_eval(opt, x->u.binary.right, bol, eol, |
| 1079 | ctx, col, icol, 0); |
| 1080 | } |
| 1081 | break; |
| 1082 | case GREP_NODE_OR: |
| 1083 | if (!(collect_hits || opt->columnnum)) { |
| 1084 | /* |
| 1085 | * Don't short-circuit OR when given --column (or |
| 1086 | * collecting hits) to ensure we don't skip a later |
| 1087 | * child that would produce an earlier match. |
| 1088 | */ |
| 1089 | return (match_expr_eval(opt, x->u.binary.left, bol, eol, |
| 1090 | ctx, col, icol, 0) || |
| 1091 | match_expr_eval(opt, x->u.binary.right, bol, |
| 1092 | eol, ctx, col, icol, 0)); |
| 1093 | } |
| 1094 | h = match_expr_eval(opt, x->u.binary.left, bol, eol, ctx, col, |
| 1095 | icol, 0); |
| 1096 | if (collect_hits) |
| 1097 | x->u.binary.left->hit |= h; |
no test coverage detected