Bugfix for string literals and add support for printing patterns with

--verbose
This commit is contained in:
Bruce Hill 2024-02-11 16:46:07 -05:00
parent 8041d3047c
commit 5f49677d76
5 changed files with 74 additions and 7 deletions

View File

@ -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
View File

@ -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 ...`

View File

@ -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

View File

@ -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

View File

@ -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