Bugfix for string literals and add support for printing patterns with
--verbose
This commit is contained in:
parent
8041d3047c
commit
5f49677d76
2
Makefile
2
Makefile
@ -3,7 +3,7 @@ CC=cc
|
||||
PREFIX=/usr/local
|
||||
SYSCONFDIR=/etc
|
||||
CFLAGS=-std=c99 -Werror -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -flto=auto
|
||||
CWARN=-Wall -Wextra
|
||||
CWARN=-Wall -Wextra -Wno-format
|
||||
# -Wpedantic -Wsign-conversion -Wtype-limits -Wunused-result -Wnull-dereference \
|
||||
# -Waggregate-return -Walloc-zero -Walloca -Warith-conversion -Wcast-align -Wcast-align=strict \
|
||||
# -Wdangling-else -Wdate-time -Wdisabled-optimization -Wdouble-promotion -Wduplicated-branches \
|
||||
|
7
bp.c
7
bp.c
@ -10,6 +10,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <glob.h>
|
||||
#include <limits.h>
|
||||
#include <printf.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
@ -558,6 +559,9 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
char *flag = NULL;
|
||||
|
||||
if (set_pattern_printf_specifier('P'))
|
||||
errx(1, "Couldn't set printf specifier");
|
||||
|
||||
pat_t *defs = NULL;
|
||||
file_t *loaded_files = NULL;
|
||||
pat_t *pattern = NULL;
|
||||
@ -678,6 +682,9 @@ int main(int argc, char *argv[])
|
||||
// Handle exit() calls gracefully:
|
||||
require(atexit(&cleanup), "Failed to set cleanup handler at exit");
|
||||
|
||||
if (options.verbose)
|
||||
printf("Matching pattern: %P\n", pattern);
|
||||
|
||||
int found = 0;
|
||||
if (options.mode == MODE_JSON) printf("[");
|
||||
if (options.git_mode) { // Get the list of files from `git --ls-files ...`
|
||||
|
66
pattern.c
66
pattern.c
@ -3,9 +3,11 @@
|
||||
//
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <printf.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -272,7 +274,7 @@ static pat_t *_bp_simplepattern(const char *str, const char *end, bool inside_st
|
||||
all = either_pat(all, pat);
|
||||
} else {
|
||||
size_t len = (size_t)(str - c1_loc);
|
||||
pat_t *pat = Pattern(BP_STRING, start, str, len, (ssize_t)len, .string=c1_loc);
|
||||
pat_t *pat = Pattern(BP_STRING, start, str, len, (ssize_t)len, .string=strndup(c1_loc, len));
|
||||
all = either_pat(all, pat);
|
||||
}
|
||||
} while (*str++ == ',');
|
||||
@ -338,7 +340,7 @@ static pat_t *_bp_simplepattern(const char *str, const char *end, bool inside_st
|
||||
str = next_char(str, end);
|
||||
size_t len = (size_t)(str - litstart);
|
||||
str = next_char(str, end);
|
||||
return Pattern(BP_STRING, start, str, len, (ssize_t)len, .string=litstart);
|
||||
return Pattern(BP_STRING, start, str, len, (ssize_t)len, .string=strndup(litstart, len));
|
||||
}
|
||||
// Not <pat>
|
||||
case '!': {
|
||||
@ -504,7 +506,7 @@ maybe_pat_t bp_stringpattern(const char *str, const char *end)
|
||||
while (str < end && *str != '{')
|
||||
str = next_char(str, end);
|
||||
size_t len = (size_t)(str - start);
|
||||
pat_t *pat = len > 0 ? Pattern(BP_STRING, start, str, len, (ssize_t)len, .string=start) : NULL;
|
||||
pat_t *pat = len > 0 ? Pattern(BP_STRING, start, str, len, (ssize_t)len, .string=strndup(start, len)) : NULL;
|
||||
str += 1;
|
||||
if (str < end) {
|
||||
pat_t *interp = bp_pattern_nl(str, end, true);
|
||||
@ -588,7 +590,7 @@ static pat_t *bp_pattern_nl(const char *str, const char *end, bool allow_nl)
|
||||
//
|
||||
pat_t *bp_raw_literal(const char *str, size_t len)
|
||||
{
|
||||
return Pattern(BP_STRING, str, &str[len], len, (ssize_t)len, .string=str);
|
||||
return Pattern(BP_STRING, str, &str[len], len, (ssize_t)len, .string=strndup(str, len));
|
||||
}
|
||||
|
||||
//
|
||||
@ -642,6 +644,7 @@ void delete_pat(pat_t **at_pat, bool recursive)
|
||||
T(BP_AFTER, F(pat))
|
||||
T(BP_BEFORE, F(pat))
|
||||
T(BP_LEFTRECURSION, F(fallback))
|
||||
T(BP_STRING, if (_data->string) { free((char*)_data->string); _data->string = NULL; })
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@ -653,4 +656,59 @@ void delete_pat(pat_t **at_pat, bool recursive)
|
||||
delete(at_pat);
|
||||
}
|
||||
|
||||
static int printf_pattern_size(const struct printf_info *info, size_t n, int argtypes[n], int sizes[n])
|
||||
{
|
||||
if (n < 1) return -1;
|
||||
(void)info;
|
||||
argtypes[0] = PA_POINTER;
|
||||
sizes[0] = sizeof(void*);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int printf_pattern(FILE *stream, const struct printf_info *info, const void *const args[])
|
||||
{
|
||||
(void)info;
|
||||
pat_t *pat = *(pat_t**)args[0];
|
||||
if (!pat) return fputs("(null)", stream);
|
||||
|
||||
switch (pat->type) {
|
||||
#define P(name, ...) case BP_ ## name: { __auto_type data = pat->__tagged.BP_##name; (void)data; return fprintf(stream, #name __VA_ARGS__); }
|
||||
P(ERROR)
|
||||
P(ANYCHAR)
|
||||
P(ID_START)
|
||||
P(ID_CONTINUE)
|
||||
P(STRING, "(\"%s\")", data.string)
|
||||
P(RANGE, "('%c'-'%c')", data.low, data.high)
|
||||
P(NOT, "(%P)", data.pat)
|
||||
P(UPTO, "(%P, skip=%P)", data.target, data.skip)
|
||||
P(UPTO_STRICT, "(%P, skip=%P)", data.target, data.skip)
|
||||
P(REPEAT, "(%u-%d, %P, sep=%P)", data.min, data.max, data.repeat_pat, data.sep)
|
||||
P(BEFORE, "(%P)", data.pat)
|
||||
P(AFTER, "(%P)", data.pat)
|
||||
P(CAPTURE, "(%P, name=%.*s, backref=%s)", data.pat, data.namelen, data.name, data.backreffable ? "yes" : "no")
|
||||
P(OTHERWISE, "(%P, %P)", data.first, data.second);
|
||||
P(CHAIN, "(%P, %P)", data.first, data.second);
|
||||
P(MATCH, "(%P, matches=%P)", data.pat, data.must_match);
|
||||
P(NOT_MATCH, "(%P, not_matches=%P)", data.pat, data.must_not_match);
|
||||
P(REPLACE, "(%P, \"%.*s\")", data.pat, data.len, data.text);
|
||||
P(REF, "(%.*s)", data.len, data.name);
|
||||
P(NODENT)
|
||||
P(CURDENT)
|
||||
P(START_OF_FILE)
|
||||
P(START_OF_LINE)
|
||||
P(END_OF_FILE)
|
||||
P(END_OF_LINE)
|
||||
P(WORD_BOUNDARY)
|
||||
P(DEFINITIONS, "(%.*s=%P); %P", data.namelen, data.name, data.meaning, data.next_def)
|
||||
P(TAGGED, "(%.*s=%P, backref=%s)", data.namelen, data.name, data.pat, data.backreffable ? "yes" : "no")
|
||||
#undef P
|
||||
default: return fputs("???", stream);
|
||||
}
|
||||
}
|
||||
|
||||
int set_pattern_printf_specifier(char specifier)
|
||||
{
|
||||
return register_printf_specifier(specifier, printf_pattern, printf_pattern_size);
|
||||
}
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -3,8 +3,10 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <printf.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
|
||||
@ -67,7 +69,7 @@ typedef struct pat_s {
|
||||
struct {} BP_ANYCHAR;
|
||||
struct {} BP_ID_START;
|
||||
struct {} BP_ID_CONTINUE;
|
||||
struct {const char *string;} BP_STRING;
|
||||
struct {const char *string; size_t len; } BP_STRING;
|
||||
struct {unsigned char low, high; } BP_RANGE;
|
||||
struct {struct pat_s *pat;} BP_NOT;
|
||||
struct {struct pat_s *target, *skip;} BP_UPTO;
|
||||
@ -163,5 +165,6 @@ maybe_pat_t bp_pattern(const char *str, const char *end);
|
||||
void free_all_pats(void);
|
||||
__attribute__((nonnull))
|
||||
void delete_pat(pat_t **at_pat, bool recursive);
|
||||
int set_pattern_printf_specifier(char specifier);
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
@ -277,5 +277,4 @@ int fprint_match(FILE *out, const char *file_start, match_t *m, print_options_t
|
||||
return printed;
|
||||
}
|
||||
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
Loading…
Reference in New Issue
Block a user