Deprecate JSON output format

This commit is contained in:
Bruce Hill 2024-06-23 19:23:02 -04:00
parent faba716e87
commit 5a6d4e4b8b
7 changed files with 4 additions and 158 deletions

View File

@ -24,8 +24,8 @@ O=-O3
ALL_FLAGS=$(CFLAGS) $(OSFLAGS) -DBP_NAME="\"$(NAME)\"" $(EXTRA) $(CWARN) $(G) $(O)
LIBFILE=lib$(NAME).so
CFILES=pattern.c utils.c match.c files.c printmatch.c json.c utf8.c
HFILES=files.h json.h match.h pattern.h printmatch.h utf8.h utils.h
CFILES=pattern.c utils.c match.c files.c printmatch.c utf8.c
HFILES=files.h match.h pattern.h printmatch.h utf8.h utils.h
OBJFILES=$(CFILES:.c=.o)
$(NAME): $(OBJFILES) bp.c

View File

@ -29,7 +29,6 @@ to and including the next occurrence of "baz" on the same line).
* `-i` `--ignore-case` perform a case-insensitive match
* `-I` `--inplace` perform replacements or filtering in-place on files
* `-e` `--explain` print an explanation of the matches
* `-j` `--json` print matches as JSON objects
* `-l` `--list-files` print only filenames containing matches
* `-r` `--replace <replacement>` replace the input pattern with the given replacement
* `-s` `--skip <skip pattern>` skip over the given pattern when looking for matches
@ -150,7 +149,6 @@ File | Description
-------------------------------|-----------------------------------------------------
[bp.c](bp.c) | The main program.
[files.c](files.c) | Loading files into memory.
[json.c](json.c) | JSON output of matches.
[match.c](match.c) | Pattern matching code (find occurrences of a bp pattern within an input string).
[pattern.c](pattern.c) | Pattern compiling code (compile a bp pattern from an input string).
[printmatch.c](printmatch.c) | Printing a visual explanation of a match.

28
bp.1
View File

@ -1,30 +1,12 @@
.\" Automatically generated by Pandoc 3.1.6
.\" Automatically generated by Pandoc 3.1.8
.\"
.\" Define V font for inline verbatim, using C font in formats
.\" that render this, and otherwise B font.
.ie "\f[CB]x\f[]"x" \{\
. ftr V B
. ftr VI BI
. ftr VB B
. ftr VBI BI
.\}
.el \{\
. ftr V CR
. ftr VI CI
. ftr VB CB
. ftr VBI CBI
.\}
.TH "BP" "1" "May 17 2021" "" ""
.hy
.SH NAME
.PP
bp - Bruce\[aq]s Parsing Expression Grammar tool
.SH SYNOPSIS
.PP
\f[B]bp\f[R] [\f[I]options\&...\f[R]] \f[I]pattern\f[R] [[\f[B]--\f[R]]
\f[I]files\&...\f[R]]
.SH DESCRIPTION
.PP
\f[B]bp\f[R] is a tool that matches parsing expression grammars using a
custom syntax.
.SH OPTIONS
@ -42,10 +24,6 @@ Surround a string pattern with word boundaries (equivalent to \f[B]bp
\f[B]-e\f[R], \f[B]--explain\f[R]
Print a visual explanation of the matches.
.TP
\f[B]-j\f[R], \f[B]--json\f[R]
Print a JSON list of the matches.
(Pairs with \f[B]--verbose\f[R] for more detail)
.TP
\f[B]-l\f[R], \f[B]--list-files\f[R]
Print only the names of files containing matches instead of the matches
themselves.
@ -115,7 +93,6 @@ used instead.
If neither are provided, \f[B]bp\f[R] will search through all files in
the current directory and its subdirectories (recursively).
.SH STRING PATTERNS
.PP
One of the most common use cases for pattern matching tools is matching
plain, literal strings, or strings that are primarily plain strings,
with one or two patterns.
@ -132,7 +109,6 @@ character literal: \f[B]{\[ga]{}\f[R], the string literal:
\f[B]{\[dq]{\[dq]}\f[R], or a pair of matching curly braces using the
\f[B]braces\f[R] rule: \f[B]{braces}\f[R].
.SH PATTERNS
.PP
\f[B]bp\f[R] patterns are based off of a combination of Parsing
Expression Grammars and regular expression syntax.
The syntax is designed to map closely to verbal descriptions of the
@ -377,7 +353,6 @@ that also attaches a metadata tag of the same name)
\f[B]#\f[R] \f[I]comment\f[R]
A line comment, ignored by BP
.SH GRAMMAR FILES
.PP
\f[B]bp\f[R] allows loading extra grammar files, which define patterns
which may be used for matching.
The \f[B]builtins\f[R] grammar file is loaded by default, and it defines
@ -430,7 +405,6 @@ following command:
\f[B]bp -g c++ \[aq]{comment \[ti] \[dq]TODO\[dq]}\[aq] *.cpp\f[R]
.RE
.SH EXAMPLES
.PP
Find files containing the literal string \[lq]foo.baz\[rq] (a string
pattern):
.RS

View File

@ -27,9 +27,6 @@ syntax.
`-e`, `--explain`
: Print a visual explanation of the matches.
`-j`, `--json`
: Print a JSON list of the matches. (Pairs with `--verbose` for more detail)
`-l`, `--list-files`
: Print only the names of files containing matches instead of the matches
themselves.

26
bp.c
View File

@ -22,7 +22,6 @@
#include <unistd.h>
#include "files.h"
#include "json.h"
#include "match.h"
#include "pattern.h"
#include "printmatch.h"
@ -40,7 +39,6 @@ static const char *usage = (
" -h --help print the usage and quit\n"
" -v --verbose print verbose debugging info\n"
" -e --explain explain the matches\n"
" -j --json print matches as a list of JSON objects\n"
" -c --case use case sensitivity\n"
" -i --ignore-case preform matching case-insensitively\n"
" -I --inplace modify a file in-place\n"
@ -65,7 +63,7 @@ static const char *usage = (
static struct {
int context_before, context_after;
bool ignorecase, verbose, git_mode, print_filenames;
enum { MODE_NORMAL, MODE_LISTFILES, MODE_INPLACE, MODE_JSON, MODE_EXPLAIN } mode;
enum { MODE_NORMAL, MODE_LISTFILES, MODE_INPLACE, MODE_EXPLAIN } mode;
enum { FORMAT_AUTO, FORMAT_FANCY, FORMAT_PLAIN, FORMAT_BARE, FORMAT_FILE_LINE } format;
bp_pat_t *skip;
} options = {
@ -205,22 +203,6 @@ static int is_text_file(const char *filename)
return 1;
}
//
// Print matches in JSON format.
//
static int print_matches_as_json(file_t *f, bp_pat_t *pattern, bp_pat_t *defs)
{
int nmatches = 0;
for (bp_match_t *m = NULL; next_match(&m, f->start, f->end, pattern, defs, options.skip, options.ignorecase); ) {
if (++nmatches > 1)
printf(",\n");
printf("{\"filename\":\"%s\",\"match\":", f->filename);
json_match(f->start, m, options.verbose);
printf("}");
}
return nmatches;
}
//
// Print matches in a visual explanation style
//
@ -418,8 +400,6 @@ static int process_file(const char *filename, bp_pat_t *pattern, bp_pat_t *defs)
matches += 1;
}
stop_matching(&m);
} else if (options.mode == MODE_JSON) {
matches += print_matches_as_json(f, pattern, defs);
} else if (options.mode == MODE_INPLACE) {
bp_match_t *m = NULL;
bool found = next_match(&m, f->start, f->end, pattern, defs, options.skip, options.ignorecase);
@ -586,8 +566,6 @@ int main(int argc, char *argv[])
options.verbose = true;
} else if (BOOLFLAG("-e") || BOOLFLAG("--explain")) {
options.mode = MODE_EXPLAIN;
} else if (BOOLFLAG("-j") || BOOLFLAG("--json")) {
options.mode = MODE_JSON;
} else if (BOOLFLAG("-I") || BOOLFLAG("--inplace")) {
options.mode = MODE_INPLACE;
options.print_filenames = false;
@ -686,7 +664,6 @@ int main(int argc, char *argv[])
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 ...`
found = process_git_files(pattern, defs, argc, argv);
} else if (argv[0]) {
@ -708,7 +685,6 @@ int main(int argc, char *argv[])
options.print_filenames = false; // Don't print filename on stdin
found += process_file("", pattern, defs);
}
if (options.mode == MODE_JSON) printf("]\n");
// This code frees up all residual heap-allocated memory. Since the program
// is about to exit, this step is unnecessary. However, it is useful for

86
json.c
View File

@ -1,86 +0,0 @@
//
// json.c - Code for printing JSON output of matches.
//
#include <stdio.h>
#include "json.h"
#include "utils.h"
__attribute__((nonnull))
static int _json_match(const char *text, bp_match_t *m, int comma, bool verbose);
//
// Helper function for json_match().
// `comma` is used to track whether a comma will need to be printed before the
// next object or not.
//
static int _json_match(const char *text, bp_match_t *m, int comma, bool verbose)
{
if (!verbose && m->pat->type != BP_TAGGED) {
if (m->children) {
for (int i = 0; m->children && m->children[i]; i++)
comma |= _json_match(text, m->children[i], comma, verbose);
}
return comma;
}
if (comma) printf(",\n");
comma = 0;
printf("{");
if (m->pat->type == BP_TAGGED) {
printf("\"tag\":\"%.*s\"", (int)When(m->pat, BP_TAGGED)->namelen, When(m->pat, BP_TAGGED)->name);
comma = 1;
}
if (verbose) {
if (comma) printf(",");
printf("\"rule\":\"");
for (const char *c = m->pat->start; c < m->pat->end; c++) {
switch (*c) {
case '"': printf("\\\""); break;
case '\\': printf("\\\\"); break;
case '\t': printf("\\t"); break;
case '\n': printf(""); break;
default: printf("%c", *c); break;
}
}
printf("\",");
printf("\"range\":[%zd,%zd]", m->start - text, m->end - text);
comma = 1;
} else {
if (comma) printf(",");
printf("\"text\":\"");
for (const char *c = m->start; c < m->end; c++) {
switch (*c) {
case '"': printf("\\\""); break;
case '\\': printf("\\\\"); break;
case '\t': printf("\\t"); break;
case '\n': printf(""); break;
default: printf("%c", *c); break;
}
}
printf("\"");
comma = 1;
}
if (m->children) {
if (comma) printf(",");
printf("\"children\":[");
comma = 0;
for (int i = 0; m->children && m->children[i]; i++)
comma |= _json_match(text, m->children[i], comma, verbose);
printf("]");
}
printf("}");
return 1;
}
//
// Print a match object as a JSON object.
//
public void json_match(const char *text, bp_match_t *m, bool verbose)
{
(void)_json_match(text, m, 0, verbose);
}
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0

13
json.h
View File

@ -1,13 +0,0 @@
//
// json.h - Header file for JSON output.
//
#pragma once
#include <stdbool.h>
#include "match.h"
__attribute__((nonnull))
void json_match(const char *text, bp_match_t *m, bool verbose);
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0