Added --git/-G
This commit is contained in:
parent
05b9b0ff97
commit
58af933f4e
@ -17,9 +17,10 @@ It's written in pure C with no dependencies.
|
||||
* `-l` `--list-files` print only filenames containing matches
|
||||
* `-p` `--pattern <pat>` provide a pattern (equivalent to `bp '\(<pat>)'`)
|
||||
* `-P` `--pattern-string <pat>` provide a string pattern (equivalent to `bp '<pat>'`, but may be useful if `'<pat>'` begins with a '-')
|
||||
* `-r` `--replace <replacement>` replace the input pattern with the given replacement
|
||||
* `-r` `--replace <replacement>` replace the input pattern with the given replacement
|
||||
* `-c` `--context <N>` change how many lines of context are printed (`0`: no context, `all`: the whole file, `<N>` matching lines and `<N-1>` lines before/after)
|
||||
* `-g` `--grammar <grammar file>` use the specified file as a grammar
|
||||
* `-g` `--grammar <grammar file>` use the specified file as a grammar
|
||||
* `-G` `--git` get filenames from git
|
||||
|
||||
See `man ./bp.1` for more details.
|
||||
|
||||
|
5
bp.1
5
bp.1
@ -17,6 +17,7 @@ bp \- Bruce's Parsing Expression Grammar tool
|
||||
[\fI-P\fR|\fI--pattern-string\fR \fI<string-pattern>\fR]
|
||||
[\fI-r\fR|\fI--replace\fR \fI<replacement>\fR]
|
||||
[\fI-g\fR|\fI--grammar\fR \fI<grammar file>\fR]
|
||||
[\fI-G\fR|\fI--git\fR]
|
||||
[\fI-c\fR|\fI--conntext\fR \fI<N>\fR]
|
||||
\fI<pattern\fR
|
||||
[[--] \fI<input files...>\fR]
|
||||
@ -50,6 +51,10 @@ Replace all occurrences of the main pattern with the given string.
|
||||
.B \-g\fR, \fB--grammar \fI<grammar file>\fR
|
||||
Load the grammar from the given file.
|
||||
|
||||
.B \-G\fR, \fB--git\fR
|
||||
Use \fBgit\fR to get a list of files. Remaining file arguments (if any) are
|
||||
passed to \fBgit --ls-files\fR instead of treated as literal files.
|
||||
|
||||
.B \-c\fR, \fB--context \fI<N>\fR
|
||||
The number of lines of context to print. If \fI<N>\fR is 0, print only the
|
||||
exact text of the matches. If \fI<N>\fR is "all", print the entire file.
|
||||
|
39
bp.c
39
bp.c
@ -10,6 +10,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "definitions.h"
|
||||
@ -379,8 +381,8 @@ int main(int argc, char *argv[])
|
||||
file_t *local_file = load_file(&loaded_files, "%s/.config/"BP_NAME"/builtins.bp", getenv("HOME"));
|
||||
if (local_file) defs = load_grammar(defs, local_file);
|
||||
|
||||
int i, npatterns = 0;
|
||||
check(argc > 1, "%s", usage);
|
||||
int i, npatterns = 0, git = 0;
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (streq(argv[i], "--")) {
|
||||
++i;
|
||||
@ -399,6 +401,8 @@ int main(int argc, char *argv[])
|
||||
mode = MODE_INPLACE;
|
||||
} else if (streq(argv[i], "--confirm")) {
|
||||
confirm = CONFIRM_ASK;
|
||||
} else if (streq(argv[i], "--git")) {
|
||||
git = 1;
|
||||
} else if (streq(argv[i], "--ignore-case")) {
|
||||
ignorecase = 1;
|
||||
} else if (streq(argv[i], "--list-files")) {
|
||||
@ -460,6 +464,7 @@ int main(int argc, char *argv[])
|
||||
switch (*c) {
|
||||
case 'h': goto flag_help; // -h
|
||||
case 'v': verbose = 1; break; // -v
|
||||
case 'G': git = 1; break; // -G
|
||||
case 'e': mode = MODE_EXPLAIN; break; // -e
|
||||
case 'j': mode = MODE_JSON; break; // -j
|
||||
case 'I': mode = MODE_INPLACE; break; // -I
|
||||
@ -512,7 +517,37 @@ int main(int argc, char *argv[])
|
||||
|
||||
int found = 0;
|
||||
if (mode == MODE_JSON) printf("[");
|
||||
if (i < argc) {
|
||||
if (git) {
|
||||
int fds[2];
|
||||
check(pipe(fds) == 0, "Failed to create pipe");
|
||||
pid_t child = fork();
|
||||
check(child != -1, "Failed to fork");
|
||||
if (child == 0) {
|
||||
char **git_args = calloc((size_t)(2+(argc-i)+1), sizeof(char*));
|
||||
int g = 0;
|
||||
git_args[g++] = "git";
|
||||
git_args[g++] = "ls-files";
|
||||
while (i < argc) git_args[g++] = argv[i++];
|
||||
dup2(fds[STDOUT_FILENO], STDOUT_FILENO);
|
||||
close(fds[STDIN_FILENO]);
|
||||
execvp("git", git_args);
|
||||
_exit(1);
|
||||
}
|
||||
close(fds[STDOUT_FILENO]);
|
||||
char path[PATH_MAX+2] = {0}; // path + \n + \0
|
||||
while (read(fds[STDIN_FILENO], path, PATH_MAX+1) > 0) { // Iterate over chunks
|
||||
for (char *nl; (nl = strchr(path, '\n')); ) { // Iterate over nl-terminated lines
|
||||
*nl = '\0';
|
||||
found += process_file(defs, path, pattern);
|
||||
memmove(path, nl+1, sizeof(path)-(size_t)(nl+1-path));
|
||||
}
|
||||
}
|
||||
close(fds[STDIN_FILENO]);
|
||||
int status;
|
||||
waitpid(child, &status, 0);
|
||||
check(WIFEXITED(status) && WEXITSTATUS(status) == 0,
|
||||
"`git --ls-files` failed. Do you have git installed?");
|
||||
} else if (i < argc) {
|
||||
// Files pass in as command line args:
|
||||
for (int nfiles = 0; i < argc; nfiles++, i++) {
|
||||
found += process_file(defs, argv[i], pattern);
|
||||
|
Loading…
Reference in New Issue
Block a user