837
#define grep_attr_unlock()
838
#endif
839
840
-static int match_funcname(struct grep_opt *opt, const char *name, char *bol, char *eol)
840
+static int match_funcname(struct grep_opt *opt, struct grep_source *gs, char *bol, char *eol)
841
{
842
xdemitconf_t *xecfg = opt->priv;
843
if (xecfg && !xecfg->find_func) {
844
struct userdiff_driver *drv;
845
grep_attr_lock();
846
- drv = userdiff_find_by_path(name);
846
+ drv = userdiff_find_by_path(gs->name);
847
grep_attr_unlock();
848
if (drv && drv->funcname.pattern) {
849
const struct userdiff_funcname *pe = &drv->funcname;
866
return 0;
867
}
868
869
-static void show_funcname_line(struct grep_opt *opt, const char *name,
870
- char *buf, char *bol, unsigned lno)
869
+static void show_funcname_line(struct grep_opt *opt, struct grep_source *gs,
870
+ char *bol, unsigned lno)
871
{
872
- while (bol > buf) {
872
+ while (bol > gs->buf) {
873
char *eol = --bol;
874
875
- while (bol > buf && bol[-1] != '\n')
875
+ while (bol > gs->buf && bol[-1] != '\n')
876
bol--;
877
lno--;
878
879
if (lno <= opt->last_shown)
880
break;
881
882
- if (match_funcname(opt, name, bol, eol)) {
883
- show_line(opt, bol, eol, name, lno, '=');
882
+ if (match_funcname(opt, gs, bol, eol)) {
883
+ show_line(opt, bol, eol, gs->name, lno, '=');
884
break;
885
}
886
}
887
}
888
889
-static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
889
+static void show_pre_context(struct grep_opt *opt, struct grep_source *gs,
890
char *bol, char *end, unsigned lno)
891
{
892
unsigned cur = lno, from = 1, funcname_lno = 0;
893
int funcname_needed = !!opt->funcname;
894
895
- if (opt->funcbody && !match_funcname(opt, name, bol, end))
895
+ if (opt->funcbody && !match_funcname(opt, gs, bol, end))
896
funcname_needed = 2;
897
898
if (opt->pre_context < lno)
901
from = opt->last_shown + 1;
902
903
/* Rewind. */
904
- while (bol > buf &&
904
+ while (bol > gs->buf &&
905
cur > (funcname_needed == 2 ? opt->last_shown + 1 : from)) {
906
char *eol = --bol;
907
908
- while (bol > buf && bol[-1] != '\n')
908
+ while (bol > gs->buf && bol[-1] != '\n')
909
bol--;
910
cur--;
911
- if (funcname_needed && match_funcname(opt, name, bol, eol)) {
911
+ if (funcname_needed && match_funcname(opt, gs, bol, eol)) {
912
funcname_lno = cur;
913
funcname_needed = 0;
914
}
916
917
/* We need to look even further back to find a function signature. */
918
if (opt->funcname && funcname_needed)
919
- show_funcname_line(opt, name, buf, bol, cur);
919
+ show_funcname_line(opt, gs, bol, cur);
920
921
/* Back forward. */
922
while (cur < lno) {
924
925
while (*eol != '\n')
926
eol++;
927
- show_line(opt, bol, eol, name, cur, sign);
927
+ show_line(opt, bol, eol, gs->name, cur, sign);
928
bol = eol + 1;
929
cur++;
930
}
991
fwrite(buf, size, 1, stdout);
992
}
993
994
-static int grep_buffer_1(struct grep_opt *opt, const char *name,
995
- char *buf, unsigned long size, int collect_hits)
994
+static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int collect_hits)
995
{
997
- char *bol = buf;
998
- unsigned long left = size;
996
+ char *bol;
997
+ unsigned long left;
998
unsigned lno = 1;
999
unsigned last_hit = 0;
1000
int binary_match_only = 0;
1022
}
1023
opt->last_shown = 0;
1024
1025
+ if (grep_source_load(gs) < 0)
1026
+ return 0;
1027
+
1028
switch (opt->binary) {
1029
case GREP_BINARY_DEFAULT:
1028
- if (buffer_is_binary(buf, size))
1030
+ if (buffer_is_binary(gs->buf, gs->size))
1031
binary_match_only = 1;
1032
break;
1033
case GREP_BINARY_NOMATCH:
1032
- if (buffer_is_binary(buf, size))
1034
+ if (buffer_is_binary(gs->buf, gs->size))
1035
return 0; /* Assume unmatch */
1036
break;
1037
case GREP_BINARY_TEXT:
1045
1046
try_lookahead = should_lookahead(opt);
1047
1048
+ bol = gs->buf;
1049
+ left = gs->size;
1050
while (left) {
1051
char *eol, ch;
1052
int hit;
1095
if (opt->status_only)
1096
return 1;
1097
if (opt->name_only) {
1094
- show_name(opt, name);
1098
+ show_name(opt, gs->name);
1099
return 1;
1100
}
1101
if (opt->count)
1102
goto next_line;
1103
if (binary_match_only) {
1104
opt->output(opt, "Binary file ", 12);
1101
- output_color(opt, name, strlen(name),
1105
+ output_color(opt, gs->name, strlen(gs->name),
1106
opt->color_filename);
1107
opt->output(opt, " matches\n", 9);
1108
return 1;
1111
* pre-context lines, we would need to show them.
1112
*/
1113
if (opt->pre_context || opt->funcbody)
1110
- show_pre_context(opt, name, buf, bol, eol, lno);
1114
+ show_pre_context(opt, gs, bol, eol, lno);
1115
else if (opt->funcname)
1112
- show_funcname_line(opt, name, buf, bol, lno);
1113
- show_line(opt, bol, eol, name, lno, ':');
1116
+ show_funcname_line(opt, gs, bol, lno);
1117
+ show_line(opt, bol, eol, gs->name, lno, ':');
1118
last_hit = lno;
1119
if (opt->funcbody)
1120
show_function = 1;
1121
goto next_line;
1122
}
1119
- if (show_function && match_funcname(opt, name, bol, eol))
1123
+ if (show_function && match_funcname(opt, gs, bol, eol))
1124
show_function = 0;
1125
if (show_function ||
1126
(last_hit && lno <= last_hit + opt->post_context)) {
1127
/* If the last hit is within the post context,
1128
* we need to show this line.
1129
*/
1126
- show_line(opt, bol, eol, name, lno, '-');
1130
+ show_line(opt, bol, eol, gs->name, lno, '-');
1131
}
1132
1133
next_line:
1145
return 0;
1146
if (opt->unmatch_name_only) {
1147
/* We did not see any hit, so we want to show this */
1144
- show_name(opt, name);
1148
+ show_name(opt, gs->name);
1149
return 1;
1150
}
1151
1159
*/
1160
if (opt->count && count) {
1161
char buf[32];
1158
- output_color(opt, name, strlen(name), opt->color_filename);
1162
+ output_color(opt, gs->name, strlen(gs->name), opt->color_filename);
1163
output_sep(opt, ':');
1164
snprintf(buf, sizeof(buf), "%u\n", count);
1165
opt->output(opt, buf, strlen(buf));
1194
}
1195
}
1196
1193
-int grep_buffer(struct grep_opt *opt, const char *name, char *buf, unsigned long size)
1197
+int grep_source(struct grep_opt *opt, struct grep_source *gs)
1198
{
1199
/*
1200
* we do not have to do the two-pass grep when we do not check
1201
* buffer-wide "all-match".
1202
*/
1203
if (!opt->all_match)
1200
- return grep_buffer_1(opt, name, buf, size, 0);
1204
+ return grep_source_1(opt, gs, 0);
1205
1206
/* Otherwise the toplevel "or" terms hit a bit differently.
1207
* We first clear hit markers from them.
1208
*/
1209
clr_hit_marker(opt->pattern_expression);
1206
- grep_buffer_1(opt, name, buf, size, 1);
1210
+ grep_source_1(opt, gs, 1);
1211
1212
if (!chk_hit_marker(opt->pattern_expression))
1213
return 0;
1214
1211
- return grep_buffer_1(opt, name, buf, size, 0);
1215
+ return grep_source_1(opt, gs, 0);
1216
+}
1217
+
1218
+int grep_buffer(struct grep_opt *opt, const char *name, char *buf, unsigned long size)
1219
+{
1220
+ struct grep_source gs;
1221
+ int r;
1222
+
1223
+ grep_source_init(&gs, GREP_SOURCE_BUF, name, NULL);
1224
+ gs.buf = buf;
1225
+ gs.size = size;
1226
+
1227
+ r = grep_source(opt, &gs);
1228
+
1229
+ grep_source_clear(&gs);
1230
+ return r;
1231
+}
1232
+
1233
+void grep_source_init(struct grep_source *gs, enum grep_source_type type,
1234
+ const char *name, const void *identifier)
1235
+{
1236
+ gs->type = type;
1237
+ gs->name = name ? xstrdup(name) : NULL;
1238
+ gs->buf = NULL;
1239
+ gs->size = 0;
1240
+
1241
+ switch (type) {
1242
+ case GREP_SOURCE_FILE:
1243
+ gs->identifier = xstrdup(identifier);
1244
+ break;
1245
+ case GREP_SOURCE_SHA1:
1246
+ gs->identifier = xmalloc(20);
1247
+ memcpy(gs->identifier, identifier, 20);
1248
+ break;
1249
+ case GREP_SOURCE_BUF:
1250
+ gs->identifier = NULL;
1251
+ }
1252
+}
1253
+
1254
+void grep_source_clear(struct grep_source *gs)
1255
+{
1256
+ free(gs->name);
1257
+ gs->name = NULL;
1258
+ free(gs->identifier);
1259
+ gs->identifier = NULL;
1260
+ grep_source_clear_data(gs);
1261
+}
1262
+
1263
+void grep_source_clear_data(struct grep_source *gs)
1264
+{
1265
+ switch (gs->type) {
1266
+ case GREP_SOURCE_FILE:
1267
+ case GREP_SOURCE_SHA1:
1268
+ free(gs->buf);
1269
+ gs->buf = NULL;
1270
+ gs->size = 0;
1271
+ break;
1272
+ case GREP_SOURCE_BUF:
1273
+ /* leave user-provided buf intact */
1274
+ break;
1275
+ }
1276
+}
1277
+
1278
+static int grep_source_load_sha1(struct grep_source *gs)
1279
+{
1280
+ enum object_type type;
1281
+
1282
+ grep_read_lock();
1283
+ gs->buf = read_sha1_file(gs->identifier, &type, &gs->size);
1284
+ grep_read_unlock();
1285
+
1286
+ if (!gs->buf)
1287
+ return error(_("'%s': unable to read %s"),
1288
+ gs->name,
1289
+ sha1_to_hex(gs->identifier));
1290
+ return 0;
1291
+}
1292
+
1293
+static int grep_source_load_file(struct grep_source *gs)
1294
+{
1295
+ const char *filename = gs->identifier;
1296
+ struct stat st;
1297
+ char *data;
1298
+ size_t size;
1299
+ int i;
1300
+
1301
+ if (lstat(filename, &st) < 0) {
1302
+ err_ret:
1303
+ if (errno != ENOENT)
1304
+ error(_("'%s': %s"), filename, strerror(errno));
1305
+ return -1;
1306
+ }
1307
+ if (!S_ISREG(st.st_mode))
1308
+ return -1;
1309
+ size = xsize_t(st.st_size);
1310
+ i = open(filename, O_RDONLY);
1311
+ if (i < 0)
1312
+ goto err_ret;
1313
+ data = xmalloc(size + 1);
1314
+ if (st.st_size != read_in_full(i, data, size)) {
1315
+ error(_("'%s': short read %s"), filename, strerror(errno));
1316
+ close(i);
1317
+ free(data);
1318
+ return -1;
1319
+ }
1320
+ close(i);
1321
+ data[size] = 0;
1322
+
1323
+ gs->buf = data;
1324
+ gs->size = size;
1325
+ return 0;
1326
+}
1327
+
1328
+int grep_source_load(struct grep_source *gs)
1329
+{
1330
+ if (gs->buf)
1331
+ return 0;
1332
+
1333
+ switch (gs->type) {
1334
+ case GREP_SOURCE_FILE:
1335
+ return grep_source_load_file(gs);
1336
+ case GREP_SOURCE_SHA1:
1337
+ return grep_source_load_sha1(gs);
1338
+ case GREP_SOURCE_BUF:
1339
+ return gs->buf ? 0 : -1;
1340
+ }
1341
+ die("BUG: invalid grep_source type");
1342
}