@@ -837,13 +837,13 @@ pthread_mutex_t grep_read_mutex;
837
837
#define grep_attr_unlock ()
838
838
#endif
839
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
841
{
842
842
xdemitconf_t * xecfg = opt -> priv ;
843
843
if (xecfg && !xecfg -> find_func ) {
844
844
struct userdiff_driver * drv ;
845
845
grep_attr_lock ();
846
- drv = userdiff_find_by_path (name );
846
+ drv = userdiff_find_by_path (gs -> name );
847
847
grep_attr_unlock ();
848
848
if (drv && drv -> funcname .pattern ) {
849
849
const struct userdiff_funcname * pe = & drv -> funcname ;
@@ -866,33 +866,33 @@ static int match_funcname(struct grep_opt *opt, const char *name, char *bol, cha
866
866
return 0 ;
867
867
}
868
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
871
{
872
- while (bol > buf ) {
872
+ while (bol > gs -> buf ) {
873
873
char * eol = -- bol ;
874
874
875
- while (bol > buf && bol [-1 ] != '\n' )
875
+ while (bol > gs -> buf && bol [-1 ] != '\n' )
876
876
bol -- ;
877
877
lno -- ;
878
878
879
879
if (lno <= opt -> last_shown )
880
880
break ;
881
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
884
break ;
885
885
}
886
886
}
887
887
}
888
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
890
char * bol , char * end , unsigned lno )
891
891
{
892
892
unsigned cur = lno , from = 1 , funcname_lno = 0 ;
893
893
int funcname_needed = !!opt -> funcname ;
894
894
895
- if (opt -> funcbody && !match_funcname (opt , name , bol , end ))
895
+ if (opt -> funcbody && !match_funcname (opt , gs , bol , end ))
896
896
funcname_needed = 2 ;
897
897
898
898
if (opt -> pre_context < lno )
@@ -901,30 +901,30 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
901
901
from = opt -> last_shown + 1 ;
902
902
903
903
/* Rewind. */
904
- while (bol > buf &&
904
+ while (bol > gs -> buf &&
905
905
cur > (funcname_needed == 2 ? opt -> last_shown + 1 : from )) {
906
906
char * eol = -- bol ;
907
907
908
- while (bol > buf && bol [-1 ] != '\n' )
908
+ while (bol > gs -> buf && bol [-1 ] != '\n' )
909
909
bol -- ;
910
910
cur -- ;
911
- if (funcname_needed && match_funcname (opt , name , bol , eol )) {
911
+ if (funcname_needed && match_funcname (opt , gs , bol , eol )) {
912
912
funcname_lno = cur ;
913
913
funcname_needed = 0 ;
914
914
}
915
915
}
916
916
917
917
/* We need to look even further back to find a function signature. */
918
918
if (opt -> funcname && funcname_needed )
919
- show_funcname_line (opt , name , buf , bol , cur );
919
+ show_funcname_line (opt , gs , bol , cur );
920
920
921
921
/* Back forward. */
922
922
while (cur < lno ) {
923
923
char * eol = bol , sign = (cur == funcname_lno ) ? '=' : '-' ;
924
924
925
925
while (* eol != '\n' )
926
926
eol ++ ;
927
- show_line (opt , bol , eol , name , cur , sign );
927
+ show_line (opt , bol , eol , gs -> name , cur , sign );
928
928
bol = eol + 1 ;
929
929
cur ++ ;
930
930
}
@@ -991,11 +991,10 @@ static void std_output(struct grep_opt *opt, const void *buf, size_t size)
991
991
fwrite (buf , size , 1 , stdout );
992
992
}
993
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 )
996
995
{
997
- char * bol = buf ;
998
- unsigned long left = size ;
996
+ char * bol ;
997
+ unsigned long left ;
999
998
unsigned lno = 1 ;
1000
999
unsigned last_hit = 0 ;
1001
1000
int binary_match_only = 0 ;
@@ -1023,13 +1022,16 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
1023
1022
}
1024
1023
opt -> last_shown = 0 ;
1025
1024
1025
+ if (grep_source_load (gs ) < 0 )
1026
+ return 0 ;
1027
+
1026
1028
switch (opt -> binary ) {
1027
1029
case GREP_BINARY_DEFAULT :
1028
- if (buffer_is_binary (buf , size ))
1030
+ if (buffer_is_binary (gs -> buf , gs -> size ))
1029
1031
binary_match_only = 1 ;
1030
1032
break ;
1031
1033
case GREP_BINARY_NOMATCH :
1032
- if (buffer_is_binary (buf , size ))
1034
+ if (buffer_is_binary (gs -> buf , gs -> size ))
1033
1035
return 0 ; /* Assume unmatch */
1034
1036
break ;
1035
1037
case GREP_BINARY_TEXT :
@@ -1043,6 +1045,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
1043
1045
1044
1046
try_lookahead = should_lookahead (opt );
1045
1047
1048
+ bol = gs -> buf ;
1049
+ left = gs -> size ;
1046
1050
while (left ) {
1047
1051
char * eol , ch ;
1048
1052
int hit ;
@@ -1091,14 +1095,14 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
1091
1095
if (opt -> status_only )
1092
1096
return 1 ;
1093
1097
if (opt -> name_only ) {
1094
- show_name (opt , name );
1098
+ show_name (opt , gs -> name );
1095
1099
return 1 ;
1096
1100
}
1097
1101
if (opt -> count )
1098
1102
goto next_line ;
1099
1103
if (binary_match_only ) {
1100
1104
opt -> output (opt , "Binary file " , 12 );
1101
- output_color (opt , name , strlen (name ),
1105
+ output_color (opt , gs -> name , strlen (gs -> name ),
1102
1106
opt -> color_filename );
1103
1107
opt -> output (opt , " matches\n" , 9 );
1104
1108
return 1 ;
@@ -1107,23 +1111,23 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
1107
1111
* pre-context lines, we would need to show them.
1108
1112
*/
1109
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 );
1111
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 , ':' );
1114
1118
last_hit = lno ;
1115
1119
if (opt -> funcbody )
1116
1120
show_function = 1 ;
1117
1121
goto next_line ;
1118
1122
}
1119
- if (show_function && match_funcname (opt , name , bol , eol ))
1123
+ if (show_function && match_funcname (opt , gs , bol , eol ))
1120
1124
show_function = 0 ;
1121
1125
if (show_function ||
1122
1126
(last_hit && lno <= last_hit + opt -> post_context )) {
1123
1127
/* If the last hit is within the post context,
1124
1128
* we need to show this line.
1125
1129
*/
1126
- show_line (opt , bol , eol , name , lno , '-' );
1130
+ show_line (opt , bol , eol , gs -> name , lno , '-' );
1127
1131
}
1128
1132
1129
1133
next_line :
@@ -1141,7 +1145,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
1141
1145
return 0 ;
1142
1146
if (opt -> unmatch_name_only ) {
1143
1147
/* We did not see any hit, so we want to show this */
1144
- show_name (opt , name );
1148
+ show_name (opt , gs -> name );
1145
1149
return 1 ;
1146
1150
}
1147
1151
@@ -1155,7 +1159,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
1155
1159
*/
1156
1160
if (opt -> count && count ) {
1157
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 );
1159
1163
output_sep (opt , ':' );
1160
1164
snprintf (buf , sizeof (buf ), "%u\n" , count );
1161
1165
opt -> output (opt , buf , strlen (buf ));
@@ -1190,23 +1194,149 @@ static int chk_hit_marker(struct grep_expr *x)
1190
1194
}
1191
1195
}
1192
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 )
1194
1198
{
1195
1199
/*
1196
1200
* we do not have to do the two-pass grep when we do not check
1197
1201
* buffer-wide "all-match".
1198
1202
*/
1199
1203
if (!opt -> all_match )
1200
- return grep_buffer_1 (opt , name , buf , size , 0 );
1204
+ return grep_source_1 (opt , gs , 0 );
1201
1205
1202
1206
/* Otherwise the toplevel "or" terms hit a bit differently.
1203
1207
* We first clear hit markers from them.
1204
1208
*/
1205
1209
clr_hit_marker (opt -> pattern_expression );
1206
- grep_buffer_1 (opt , name , buf , size , 1 );
1210
+ grep_source_1 (opt , gs , 1 );
1207
1211
1208
1212
if (!chk_hit_marker (opt -> pattern_expression ))
1209
1213
return 0 ;
1210
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" );
1212
1342
}
0 commit comments