protected void grep()

in gogo/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java [1535:1739]


    protected void grep(CommandSession session, Process process, String[] argv) throws Exception {
        final String[] usage = {
                "grep -  search for PATTERN in each FILE or standard input.",
                "Usage: grep [OPTIONS] PATTERN [FILES]",
                "  -? --help                Show help",
                "  -i --ignore-case         Ignore case distinctions",
                "  -n --line-number         Prefix each line with line number within its input file",
                "  -q --quiet, --silent     Suppress all normal output",
                "  -v --invert-match        Select non-matching lines",
                "  -w --word-regexp         Select only whole words",
                "  -x --line-regexp         Select only whole lines",
                "  -c --count               Only print a count of matching lines per file",
                "     --color=WHEN          Use markers to distinguish the matching string, may be `always', `never' or `auto'",
                "  -B --before-context=NUM  Print NUM lines of leading context before matching lines",
                "  -A --after-context=NUM   Print NUM lines of trailing context after matching lines",
                "  -C --context=NUM         Print NUM lines of output context",
                "     --pad-lines           Pad line numbers"
        };
        Options opt = parseOptions(session, usage, argv);
        List<String> args = opt.args();
        if (args.isEmpty()) {
            throw new IllegalArgumentException("no pattern supplied");
        }

        String regex = args.remove(0);
        String regexp = regex;
        if (opt.isSet("word-regexp")) {
            regexp = "\\b" + regexp + "\\b";
        }
        if (opt.isSet("line-regexp")) {
            regexp = "^" + regexp + "$";
        } else {
            regexp = ".*" + regexp + ".*";
        }
        Pattern p;
        Pattern p2;
        if (opt.isSet("ignore-case")) {
            p = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE);
            p2 = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        } else {
            p = Pattern.compile(regexp);
            p2 = Pattern.compile(regex);
        }
        int after = opt.isSet("after-context") ? opt.getNumber("after-context") : -1;
        int before = opt.isSet("before-context") ? opt.getNumber("before-context") : -1;
        int context = opt.isSet("context") ? opt.getNumber("context") : 0;
        String lineFmt = opt.isSet("pad-lines") ? "%6d" : "%d";
        if (after < 0) {
            after = context;
        }
        if (before < 0) {
            before = context;
        }
        List<String> lines = new ArrayList<>();
        boolean invertMatch = opt.isSet("invert-match");
        boolean lineNumber = opt.isSet("line-number");
        boolean count = opt.isSet("count");
        String color = opt.isSet("color") ? opt.get("color") : "auto";
        boolean colored;
        switch (color) {
            case "always":
            case "yes":
            case "force":
                colored = true;
                break;
            case "never":
            case "no":
            case "none":
                colored = false;
                break;
            case "auto":
            case "tty":
            case "if-tty":
                colored = process.isTty(1);
                break;
            default:
                throw new IllegalArgumentException("invalid argument ‘" + color + "’ for ‘--color’");
        }
        Map<String, String> colors = colored ? getColorMap(session, "GREP", DEFAULT_GREP_COLORS) : Collections.emptyMap();

        List<Source> sources = new ArrayList<>();
        if (opt.args().isEmpty()) {
            opt.args().add("-");
        }
        for (String arg : opt.args()) {
            if ("-".equals(arg)) {
                sources.add(new StdInSource(process));
            } else {
                sources.add(new PathSource(session.currentDir().resolve(arg), arg));
            }
        }
        boolean match = false;
        for (Source source : sources) {
            boolean firstPrint = true;
            int nb = 0;
            int lineno = 1;
            String line;
            int lineMatch = 0;
            try (BufferedReader r = new BufferedReader(new InputStreamReader(source.read()))) {
                while ((line = r.readLine()) != null) {
                    if (line.length() == 1 && line.charAt(0) == '\n') {
                        break;
                    }
                    boolean matches = p.matcher(line).matches();
                    AttributedStringBuilder sbl = new AttributedStringBuilder();
                    if (!count) {
                        if (sources.size() > 1) {
                            if (colored) {
                                applyStyle(sbl, colors, "fn");
                            }
                            sbl.append(source.getName());
                            if (colored) {
                                applyStyle(sbl, colors, "se");
                            }
                            sbl.append(":");
                        }
                        if (lineNumber) {
                            if (colored) {
                                applyStyle(sbl, colors, "ln");
                            }
                            sbl.append(String.format(lineFmt, lineno));
                            if (colored) {
                                applyStyle(sbl, colors, "se");
                            }
                            sbl.append((matches ^ invertMatch) ? ":" : "-");
                        }
                        String style = matches ^ invertMatch ^ (invertMatch && colors.containsKey("rv"))
                                ? "sl" : "cx";
                        if (colored) {
                            applyStyle(sbl, colors, style);
                        }
                        AttributedString aLine = AttributedString.fromAnsi(line);
                        Matcher matcher2 = p2.matcher(aLine.toString());
                        int cur = 0;
                        while (matcher2.find()) {
                            int index = matcher2.start(0);
                            AttributedString prefix = aLine.subSequence(cur, index);
                            sbl.append(prefix);
                            cur = matcher2.end();
                            if (colored) {
                                applyStyle(sbl, colors, invertMatch ? "mc" : "ms", "mt");
                            }
                            sbl.append(aLine.subSequence(index, cur));
                            if (colored) {
                                applyStyle(sbl, colors, style);
                            }
                            nb++;
                        }
                        sbl.append(aLine.subSequence(cur, aLine.length()));
                    }
                    if (matches ^ invertMatch) {
                        lines.add(sbl.toAnsi(Shell.getTerminal(session)));
                        lineMatch = lines.size();
                    } else {
                        if (lineMatch != 0 & lineMatch + after + before <= lines.size()) {
                            if (!count) {
                                if (!firstPrint && before + after > 0) {
                                    AttributedStringBuilder sbl2 = new AttributedStringBuilder();
                                    if (colored) {
                                        applyStyle(sbl2, colors, "se");
                                    }
                                    sbl2.append("--");
                                    process.out().println(sbl2.toAnsi(Shell.getTerminal(session)));
                                } else {
                                    firstPrint = false;
                                }
                                for (int i = 0; i < lineMatch + after; i++) {
                                    process.out().println(lines.get(i));
                                }
                            }
                            while (lines.size() > before) {
                                lines.remove(0);
                            }
                            lineMatch = 0;
                        }
                        lines.add(sbl.toAnsi(Shell.getTerminal(session)));
                        while (lineMatch == 0 && lines.size() > before) {
                            lines.remove(0);
                        }
                    }
                    lineno++;
                }
                if (!count && lineMatch > 0) {
                    if (!firstPrint && before + after > 0) {
                        AttributedStringBuilder sbl2 = new AttributedStringBuilder();
                        if (colored) {
                            applyStyle(sbl2, colors, "se");
                        }
                        sbl2.append("--");
                        process.out().println(sbl2.toAnsi(Shell.getTerminal(session)));
                    } else {
                        firstPrint = false;
                    }
                    for (int i = 0; i < lineMatch + after && i < lines.size(); i++) {
                        process.out().println(lines.get(i));
                    }
                }
                if (count) {
                    process.out().println(nb);
                }
                match |= nb > 0;
            }
        }
        Process.Utils.current().error(match ? 0 : 1);
    }