Add number of characters printed to fprint_match()
This commit is contained in:
parent
3ed2c19594
commit
0050a6fc06
21
bp.c
21
bp.c
@ -264,47 +264,52 @@ static void sig_handler(int sig)
|
||||
if (kill(0, sig)) _exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void fprint_linenum(FILE *out, file_t *f, int linenum, const char *normal_color)
|
||||
int fprint_linenum(FILE *out, file_t *f, int linenum, const char *normal_color)
|
||||
{
|
||||
int printed = 0;
|
||||
switch (options.format) {
|
||||
case FORMAT_FANCY: case FORMAT_PLAIN: {
|
||||
int space = 0;
|
||||
for (int i = (int)f->nlines; i > 0; i /= 10) ++space;
|
||||
if (options.format == FORMAT_FANCY)
|
||||
fprintf(out, "\033[0;2m%*d\033(0\x78\033(B%s", space, linenum, normal_color ? normal_color : "");
|
||||
else fprintf(out, "%*d|", space, linenum);
|
||||
printed += fprintf(out, "\033[0;2m%*d\033(0\x78\033(B%s", space, linenum, normal_color ? normal_color : "");
|
||||
else
|
||||
printed += fprintf(out, "%*d|", space, linenum);
|
||||
break;
|
||||
}
|
||||
case FORMAT_FILE_LINE: {
|
||||
fprintf(out, "%s:%d:", f->filename, linenum);
|
||||
printed += fprintf(out, "%s:%d:", f->filename, linenum);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
return printed;
|
||||
}
|
||||
|
||||
static file_t *printing_file = NULL;
|
||||
static int last_line_num = -1;
|
||||
static void _fprint_between(FILE *out, const char *start, const char *end, const char *normal_color)
|
||||
static int _fprint_between(FILE *out, const char *start, const char *end, const char *normal_color)
|
||||
{
|
||||
int printed = 0;
|
||||
do {
|
||||
// Cheeky lookbehind to see if line number should be printed
|
||||
if (start == printing_file->start || start[-1] == '\n') {
|
||||
int linenum = (int)get_line_number(printing_file, start);
|
||||
if (last_line_num != linenum) {
|
||||
fprint_linenum(out, printing_file, linenum, normal_color);
|
||||
printed += fprint_linenum(out, printing_file, linenum, normal_color);
|
||||
last_line_num = linenum;
|
||||
}
|
||||
}
|
||||
const char *line_end = memchr(start, '\n', (size_t)(end - start));
|
||||
if (line_end && line_end != end) {
|
||||
fwrite(start, sizeof(char), (size_t)(line_end - start + 1), out);
|
||||
printed += fwrite(start, sizeof(char), (size_t)(line_end - start + 1), out);
|
||||
start = line_end + 1;
|
||||
} else {
|
||||
if (end > start) fwrite(start, sizeof(char), (size_t)(end - start), out);
|
||||
if (end > start) printed += fwrite(start, sizeof(char), (size_t)(end - start), out);
|
||||
break;
|
||||
}
|
||||
} while (start < end);
|
||||
return printed;
|
||||
}
|
||||
|
||||
static void fprint_context(FILE *out, file_t *f, const char *prev, const char *next)
|
||||
|
39
printmatch.c
39
printmatch.c
@ -186,21 +186,23 @@ void explain_match(match_t *m)
|
||||
printf("\033[?7h"); // Re-enable line wrapping
|
||||
}
|
||||
|
||||
static inline void fputc_safe(FILE *out, char c, print_options_t *opts)
|
||||
static inline int fputc_safe(FILE *out, char c, print_options_t *opts)
|
||||
{
|
||||
(void)fputc(c, out);
|
||||
int printed = fputc(c, out);
|
||||
if (c == '\n' && opts && opts->on_nl) {
|
||||
opts->on_nl(out);
|
||||
if (opts->replace_color) fprintf(out, "%s", opts->replace_color);
|
||||
if (opts->replace_color) printed += fprintf(out, "%s", opts->replace_color);
|
||||
}
|
||||
return printed;
|
||||
}
|
||||
|
||||
void fprint_match(FILE *out, const char *file_start, match_t *m, print_options_t *opts)
|
||||
int fprint_match(FILE *out, const char *file_start, match_t *m, print_options_t *opts)
|
||||
{
|
||||
int printed = 0;
|
||||
if (m->pat->type == BP_REPLACE) {
|
||||
const char *text = m->pat->args.replace.text;
|
||||
const char *end = &text[m->pat->args.replace.len];
|
||||
if (opts && opts->replace_color) fprintf(out, "%s", opts->replace_color);
|
||||
if (opts && opts->replace_color) printed += fprintf(out, "%s", opts->replace_color);
|
||||
|
||||
// TODO: clean up the line numbering code
|
||||
for (const char *r = text; r < end; ) {
|
||||
@ -222,8 +224,8 @@ void fprint_match(FILE *out, const char *file_start, match_t *m, print_options_t
|
||||
}
|
||||
|
||||
if (cap != NULL) {
|
||||
fprint_match(out, file_start, cap, opts);
|
||||
if (opts && opts->replace_color) fprintf(out, "%s", opts->replace_color);
|
||||
printed += fprint_match(out, file_start, cap, opts);
|
||||
if (opts && opts->replace_color) printed += fprintf(out, "%s", opts->replace_color);
|
||||
r = next;
|
||||
continue;
|
||||
}
|
||||
@ -238,19 +240,19 @@ void fprint_match(FILE *out, const char *file_start, match_t *m, print_options_t
|
||||
// the replacement text contains newlines, this may get weird.
|
||||
const char *line_start = m->start;
|
||||
while (line_start > file_start && line_start[-1] != '\n') --line_start;
|
||||
fputc_safe(out, '\n', opts);
|
||||
printed += fputc_safe(out, '\n', opts);
|
||||
for (const char *p = line_start; p < m->start && (*p == ' ' || *p == '\t'); ++p)
|
||||
fputc(*p, out);
|
||||
printed += fputc(*p, out);
|
||||
continue;
|
||||
}
|
||||
fputc_safe(out, unescapechar(r, &r, end), opts);
|
||||
printed += fputc_safe(out, unescapechar(r, &r, end), opts);
|
||||
} else {
|
||||
fputc_safe(out, *r, opts);
|
||||
printed += fputc_safe(out, *r, opts);
|
||||
++r;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (opts && opts->match_color) fprintf(out, "%s", opts->match_color);
|
||||
if (opts && opts->match_color) printed += fprintf(out, "%s", opts->match_color);
|
||||
const char *prev = m->start;
|
||||
for (int i = 0; m->children && m->children[i]; i++) {
|
||||
match_t *child = m->children[i];
|
||||
@ -259,18 +261,19 @@ void fprint_match(FILE *out, const char *file_start, match_t *m, print_options_t
|
||||
prev <= child->end && child->end <= m->end))
|
||||
continue;
|
||||
if (child->start > prev) {
|
||||
if (opts && opts->fprint_between) opts->fprint_between(out, prev, child->start, opts->match_color);
|
||||
else fwrite(prev, sizeof(char), (size_t)(child->start - prev), out);
|
||||
if (opts && opts->fprint_between) printed += opts->fprint_between(out, prev, child->start, opts->match_color);
|
||||
else printed += fwrite(prev, sizeof(char), (size_t)(child->start - prev), out);
|
||||
}
|
||||
fprint_match(out, file_start, child, opts);
|
||||
if (opts && opts->match_color) fprintf(out, "%s", opts->match_color);
|
||||
printed += fprint_match(out, file_start, child, opts);
|
||||
if (opts && opts->match_color) printed += fprintf(out, "%s", opts->match_color);
|
||||
prev = child->end;
|
||||
}
|
||||
if (m->end > prev) {
|
||||
if (opts && opts->fprint_between) opts->fprint_between(out, prev, m->end, opts->match_color);
|
||||
else fwrite(prev, sizeof(char), (size_t)(m->end - prev), out);
|
||||
if (opts && opts->fprint_between) printed += opts->fprint_between(out, prev, m->end, opts->match_color);
|
||||
else printed += fwrite(prev, sizeof(char), (size_t)(m->end - prev), out);
|
||||
}
|
||||
}
|
||||
return printed;
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,12 +7,11 @@
|
||||
|
||||
typedef struct {
|
||||
const char *normal_color, *match_color, *replace_color;
|
||||
void (*fprint_between)(FILE *out, const char *start, const char *end, const char *normal_color);
|
||||
int (*fprint_between)(FILE *out, const char *start, const char *end, const char *normal_color);
|
||||
void (*on_nl)(FILE *out);
|
||||
} print_options_t;
|
||||
__attribute__((nonnull(1,2,3)))
|
||||
//void fprint_match(FILE *out, const char *file_start, match_t *m, const char *colors[3]);
|
||||
void fprint_match(FILE *out, const char *file_start, match_t *m, print_options_t *opts);
|
||||
int fprint_match(FILE *out, const char *file_start, match_t *m, print_options_t *opts);
|
||||
|
||||
__attribute__((nonnull))
|
||||
void explain_match(match_t *m);
|
||||
|
Loading…
Reference in New Issue
Block a user