12
int first_file_match = 1;
14
const char *color_reset = "\e[0m\e[K";
16
void print_path(const char* path, const char sep) {
17
log_debug("printing path");
18
path = normalize_path(path);
21
fprintf(out_fd, ":%s%c", path, sep);
24
fprintf(out_fd, "%s%s%s%c", opts.color_path, path, color_reset, sep);
26
fprintf(out_fd, "%s%c", path, sep);
31
void print_binary_file_matches(const char* path) {
32
path = normalize_path(path);
33
print_file_separator();
34
fprintf(out_fd, "Binary file %s matches.\n", path);
37
void print_file_matches(const char* path, const char* buf, const int buf_len, const match matches[], const int matches_len) {
39
char **context_prev_lines = NULL;
41
int last_prev_line = 0;
42
int prev_line_offset = 0;
44
/* TODO the line below contains a terrible hack */
45
int lines_since_last_match = 1000000; /* if I initialize this to INT_MAX it'll overflow */
46
int lines_to_print = 0;
47
int last_printed_match = 0;
50
int in_a_match = FALSE;
51
int printing_a_match = FALSE;
57
print_file_separator();
59
if (opts.print_heading == TRUE) {
60
print_path(path, '\n');
63
context_prev_lines = ag_calloc(sizeof(char*), (opts.before + 1));
65
for (i = 0; i <= buf_len && (cur_match < matches_len || lines_since_last_match <= opts.after); i++) {
66
if (cur_match < matches_len && i == matches[cur_match].end) {
67
/* We found the end of a match. */
72
if (cur_match < matches_len && i == matches[cur_match].start) {
74
/* We found the start of a match */
75
if (cur_match > 0 && opts.context && lines_since_last_match > (opts.before + opts.after + 1)) {
76
fprintf(out_fd, "--\n");
79
if (lines_since_last_match > 0 && opts.before > 0) {
80
/* TODO: better, but still needs work */
81
/* print the previous line(s) */
82
lines_to_print = lines_since_last_match - (opts.after + 1);
83
if (lines_to_print < 0) {
85
} else if (lines_to_print > opts.before) {
86
lines_to_print = opts.before;
89
for (j = (opts.before - lines_to_print); j < opts.before; j++) {
90
prev_line = (last_prev_line + j) % opts.before;
91
if (context_prev_lines[prev_line] != NULL) {
92
if (opts.print_heading == 0) {
93
print_path(path, ':');
95
print_line_number(line - (opts.before - j), sep);
96
fprintf(out_fd, "%s\n", context_prev_lines[prev_line]);
100
lines_since_last_match = 0;
103
/* We found the end of a line. */
104
if (buf[i] == '\n' && opts.before > 0) {
105
if (context_prev_lines[last_prev_line] != NULL) {
106
free(context_prev_lines[last_prev_line]);
108
/* We don't want to strcpy the \n */
109
context_prev_lines[last_prev_line] =
110
ag_strndup(&buf[prev_line_offset], i - prev_line_offset);
111
last_prev_line = (last_prev_line + 1) % opts.before;
114
if (buf[i] == '\n' || i == buf_len) {
115
if (lines_since_last_match == 0) {
116
if (opts.print_heading == 0 && !opts.search_stream) {
117
print_path(path, ':');
121
/* print headers for ackmate to parse */
122
print_line_number(line, ';');
123
for (; last_printed_match < cur_match; last_printed_match++) {
124
fprintf(out_fd, "%i %i",
125
(matches[last_printed_match].start - prev_line_offset),
126
(matches[last_printed_match].end - matches[last_printed_match].start)
128
last_printed_match == cur_match - 1 ? fputc(':', out_fd) : fputc(',', out_fd);
130
j = prev_line_offset;
131
/* print up to current char */
132
for (; j <= i; j++) {
133
fputc(buf[j], out_fd);
136
print_line_number(line, ':');
138
fprintf(out_fd, "%i:", (matches[last_printed_match].start - prev_line_offset) + 1);
141
if (printing_a_match && opts.color) {
142
fprintf(out_fd, "%s", opts.color_match);
144
for (j = prev_line_offset; j <= i; j++) {
145
if (j == matches[last_printed_match].end && last_printed_match < matches_len) {
147
fprintf(out_fd, "%s", color_reset);
149
printing_a_match = FALSE;
150
last_printed_match++;
152
if (j == matches[last_printed_match].start && last_printed_match < matches_len) {
154
fprintf(out_fd, "%s", opts.color_match);
156
printing_a_match = TRUE;
158
fputc(buf[j], out_fd);
160
if (printing_a_match && opts.color) {
161
fprintf(out_fd, "%s", color_reset);
164
} else if (lines_since_last_match <= opts.after) {
165
/* print context after matching line */
166
if (opts.print_heading == 0) {
167
print_path(path, ':');
169
print_line_number(line, sep);
171
for (j = prev_line_offset; j < i; j++) {
172
fputc(buf[j], out_fd);
177
prev_line_offset = i + 1; /* skip the newline */
180
lines_since_last_match++;
185
for (i = 0; i < opts.before; i++) {
186
if (context_prev_lines[i] != NULL) {
187
free(context_prev_lines[i]);
190
free(context_prev_lines);
193
void print_line_number(const int line, const char sep) {
194
if (!opts.print_line_numbers) {
197
log_debug("printing line number");
200
fprintf(out_fd, "%s%i%s%c", opts.color_line_number, line, color_reset, sep);
202
fprintf(out_fd, "%i%c", line, sep);
206
void print_file_separator() {
207
if (first_file_match == 0 && opts.print_break) {
208
log_debug("printing file separator");
209
fprintf(out_fd, "\n");
211
first_file_match = 0;
214
const char* normalize_path(const char* path) {
215
if (strlen(path) >= 3 && path[0] == '.' && path[1] == '/') {