in gogo/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java [368:513]
protected void wc(CommandSession session, Process process, String[] argv) throws Exception {
String[] usage = {
"wc - word, line, character, and byte count",
"Usage: wc [OPTIONS] [FILES]",
" -? --help Show help",
" -l --lines Print line counts",
" -c --bytes Print byte counts",
" -m --chars Print character counts",
" -w --words Print word counts",
};
Options opt = parseOptions(session, usage, argv);
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 displayLines = opt.isSet("lines");
boolean displayWords = opt.isSet("words");
boolean displayChars = opt.isSet("chars");
boolean displayBytes = opt.isSet("bytes");
if (!displayLines && !displayWords && !displayChars && !displayBytes) {
displayLines = true;
displayWords = true;
displayBytes = true;
}
String format = "";
if (displayLines) {
if (!displayBytes && !displayChars && !displayWords) {
format = "%1$d";
} else {
format += "%1$8d";
}
}
if (displayWords) {
if (!displayLines && !displayBytes && !displayChars) {
format = "%2$d";
} else {
format += "%2$8d";
}
}
if (displayChars) {
if (!displayLines && !displayBytes && !displayWords) {
format = "%3$d";
} else {
format += "%3$8d";
}
}
if (displayBytes) {
if (!displayLines && !displayChars && !displayWords) {
format = "%4$d";
} else {
format += "%4$8d";
}
}
if (sources.size() > 1 || (sources.size() == 1 && sources.get(0).getName() != null)) {
format += " %5$8s";
}
int totalLines = 0;
int totalBytes = 0;
int totalChars = 0;
int totalWords = 0;
for (Source src : sources) {
try (InputStream is = src.read()) {
AtomicInteger lines = new AtomicInteger();
AtomicInteger bytes = new AtomicInteger();
AtomicInteger chars = new AtomicInteger();
AtomicInteger words = new AtomicInteger();
AtomicBoolean inWord = new AtomicBoolean();
AtomicBoolean lastNl = new AtomicBoolean(true);
InputStream isc = new FilterInputStream(is) {
@Override
public int read() throws IOException {
int b = super.read();
if (b >= 0) {
bytes.incrementAndGet();
}
return b;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int nb = super.read(b, off, len);
if (nb > 0) {
bytes.addAndGet(nb);
}
return nb;
}
};
IntConsumer consumer = cp -> {
chars.incrementAndGet();
boolean ws = Character.isWhitespace(cp);
if (inWord.getAndSet(!ws) && ws) {
words.incrementAndGet();
}
if (cp == '\n') {
lines.incrementAndGet();
lastNl.set(true);
} else {
lastNl.set(false);
}
};
Reader reader = new InputStreamReader(isc);
while (true) {
int h = reader.read();
if (Character.isHighSurrogate((char) h)) {
int l = reader.read();
if (Character.isLowSurrogate((char) l)) {
int cp = Character.toCodePoint((char) h, (char) l);
consumer.accept(cp);
} else {
consumer.accept(h);
if (l >= 0) {
consumer.accept(l);
} else {
break;
}
}
} else if (h >= 0) {
consumer.accept(h);
} else {
break;
}
}
if (inWord.get()) {
words.incrementAndGet();
}
if (!lastNl.get()) {
lines.incrementAndGet();
}
process.out().println(String.format(format, lines.get(), words.get(), chars.get(), bytes.get(), src.getName()));
totalBytes += bytes.get();
totalChars += chars.get();
totalWords += words.get();
totalLines += lines.get();
}
}
if (sources.size() > 1) {
process.out().println(String.format(format, totalLines, totalWords, totalChars, totalBytes, "total"));
}
}