1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 | package Torello.Java;
import Torello.Java.Verbosity;
import Torello.Java.IOExceptionHandler;
import Torello.Java.FileNode;
import Torello.Java.FileRW;
import Torello.Java.StrIndexOf;
import Torello.Java.Q;
import Torello.Java.Additional.AppendableSafe;
import Torello.Java.Additional.BiAppendable;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import java.io.IOException;
class MultiLineStrMatch
{
// Re-Use the Pointer, I guess
private static final String I4 = Helper.I4;
static void CHECK_STRS(final String matchStr, final String replaceStr)
{
if (matchStr.equals(replaceStr)) throw new IllegalArgumentException(
"The String passed to parameter 'matcheStr' is identical to the String passed to " +
"parameter 'replaceStr'. There is nothing for SED to do."
);
}
// Only Method
static InternalSED.ResultsSED handleOneFile(
final String fileName,
final FileNode file,
final String fileAsStr,
final CONFIG_RECORD userConfig
)
throws IOException
{
// Retrieve the starting String-index of each and every match in the file
final int[] posArr = StrIndexOf.all(fileAsStr, userConfig.matchStr);
if (posArr.length == 0) return InternalSED.NO_CHANGES_RET;
// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
// For-Loop: Print the Matches to System.out
// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
// "Printing Stream" saves PrintingRecMultiLine instances.
final Stream.Builder<PrintingRecMultiLine> PRMLB = Stream.builder();
// Loop-Variable for retaining the previous PrintingRecMultiLine. It has the File
// Line-Number information for the previous match. The Previous-Line Number info is how
// Line-Number's are computed much more efficiently.
PrintingRecMultiLine prevSaverRecord = null;
for (int i=0; i < posArr.length; i++)
{
// Loop-Variable that represents the current match, indexing the 'posArr' Array
final int pos = posArr[i];
// Overlapping matches need to be skipped
if ((i > 0) && (pos < (posArr[i-1] + userConfig.MATCH_STR_LEN))) continue;
else PRMLB.accept(
prevSaverRecord = new PrintingRecMultiLine(
fileAsStr,
pos, // match Starting-Position
pos + userConfig.MATCH_STR_LEN, // match Ending-{osition
userConfig.replaceStr,
// NOTE: The "value" assigned to this reference is **NOT-UPDATED** until
// after it has been passed to this method's parameter.
prevSaverRecord,
userConfig.useUNIXColors
));
}
// All Printing-Records as an Array
final PrintingRecMultiLine[] prmlArr =
PRMLB.build().toArray(PrintingRecMultiLine[]::new);
if (prmlArr.length == 0) return InternalSED.NO_CHANGES_RET;
// unless Verbosity.Silent was requested, print the matches.
if (userConfig.verbosity.level > 0) PrintingRecMultiLine.printAll
(prmlArr, userConfig.appendable, userConfig.useUNIXColors, userConfig.verbosity);
// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
// Query the User, Write the Replacement
// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
if (userConfig.askFirst) if (! Q.YN("Re-Write the Updated File to Disk?"))
return InternalSED.NO_CHANGES_RET;
// Remember, this single line of code does the actual replacement!
String newFileAsStr = fileAsStr.replace(userConfig.matchStr, userConfig.replaceStr);
return new InternalSED.ResultsSED(newFileAsStr, prmlArr.length);
}
}
|