1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.dumpviewer.utils;
17 
18 import androidx.core.os.BuildCompat;
19 
20 public abstract class GrepHelper {
GrepHelper()21     protected GrepHelper() {
22     }
23 
getHelper()24     public static GrepHelper getHelper() {
25         if (BuildCompat.isAtLeastQ()) {
26             return new PcreGrepHelper();
27         } else {
28             return new BsdGrepHelper();
29         }
30     }
31 
getCommandName()32     public abstract String getCommandName();
33 
getMetaCharacters()34     public abstract String[] getMetaCharacters();
35 
buildCommand(StringBuilder sb, String pattern, int before, int after, boolean ignoreCase)36     public abstract void buildCommand(StringBuilder sb, String pattern, int before, int after,
37             boolean ignoreCase);
38 
39     private static class PcreGrepHelper extends GrepHelper {
40         private static final String[] sRePickerPatterns = {
41                 "\\ (backslash / escape)",
42                 ". (any char)",
43                 "* (more than 0)",
44                 "+ (more than 1)",
45                 "^ (line start / negate char class)",
46                 "$ (line end)",
47                 "( (selection start)",
48                 "| (selection or)",
49                 ") (selection end)",
50                 "[ (char class start)",
51                 "] (char class end)",
52                 "{ (\"bound\" start)",
53                 ",",
54                 "} (\"bound\" end)",
55                 "\\s (whitespace)",
56                 "\\S (not whitespace)",
57                 "\\d (digit)",
58                 "\\D (not digit)",
59                 "\\w (word character)",
60                 "\\W (not word character)",
61                 "\\b (word boundary)",
62                 "\\B (not word boundary)",
63         };
64 
65         @Override
getCommandName()66         public String getCommandName() {
67             return "pcre2grep";
68         }
69 
70         @Override
getMetaCharacters()71         public String[] getMetaCharacters() {
72             return sRePickerPatterns;
73         }
74 
75         @Override
buildCommand(StringBuilder sb, String pattern, int before, int after, boolean ignoreCase)76         public void buildCommand(StringBuilder sb, String pattern, int before, int after,
77                 boolean ignoreCase) {
78             sb.append("grep");
79             if (ignoreCase) {
80                 sb.append(" -i");
81             }
82             if (before > 0) {
83                 sb.append(" -B");
84                 sb.append(before);
85             }
86             if (after > 0) {
87                 sb.append(" -A");
88                 sb.append(after);
89             }
90             sb.append(" -- ");
91             sb.append(Utils.shellEscape(pattern));
92         }
93     }
94 
95     private static class BsdGrepHelper extends GrepHelper {
96         private static final String[] sRePickerPatterns = {
97                 "\\ (backslash / escape)",
98                 ". (any char)",
99                 "* (more than 0)",
100                 "+ (more than 1)",
101                 "^ (line start / negate char class)",
102                 "$ (line end)",
103                 "( (selection start)",
104                 "| (selection or)",
105                 ") (selection end)",
106                 "[ (char class start)",
107                 "] (char class end)",
108                 "{ (\"bound\" start)",
109                 ",",
110                 "} (\"bound\" end)",
111                 "[[:alpha:]] ([a-zA-Z])",
112                 "[[:digit:]] ([0-9])",
113                 "[[:alnum:]] ([0-9a-zA-Z])",
114                 "[[:<:]] (start of word)",
115                 "[[:>:]] (end of word)",
116                 "[[:",
117                 ":]]",
118         };
119 
120         @Override
getCommandName()121         public String getCommandName() {
122             return "egrep";
123         }
124 
125         @Override
getMetaCharacters()126         public String[] getMetaCharacters() {
127             return sRePickerPatterns;
128         }
129 
130         @Override
buildCommand(StringBuilder sb, String pattern, int before, int after, boolean ignoreCase)131         public void buildCommand(StringBuilder sb, String pattern, int before, int after,
132                 boolean ignoreCase) {
133             sb.append("grep");
134             sb.append(" -E");
135             if (ignoreCase) {
136                 sb.append(" -i");
137             }
138             if (before > 0) {
139                 sb.append(" -B");
140                 sb.append(before);
141             }
142             if (after > 0) {
143                 sb.append(" -A");
144                 sb.append(after);
145             }
146             sb.append(" -- ");
147             sb.append(Utils.shellEscape(pattern));
148         }
149     }
150 }
151