Skip to content

Commit 769706f

Browse files
committed
wc refactored
1 parent 5c64429 commit 769706f

1 file changed

Lines changed: 86 additions & 88 deletions

File tree

  • implement-shell-tools/wc

‎implement-shell-tools/wc/wc.js‎

Lines changed: 86 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,92 @@
11
const fs = require("fs");
22
const { allowedNodeEnvironmentFlags } = require("process");
33

4-
const arguments = process.argv;
5-
const userArguments = arguments.slice(2);
4+
const metrics = ["lineCount", "wordCount", "byteSize"];
5+
const displayedMetrics = [];
6+
7+
//
8+
// ===== wc Procedure =====
9+
function wc(args) {
10+
const userArgs = args.slice(2);
611

7-
const index = arguments[1].lastIndexOf("/");
8-
const currentWorkingDirectory = arguments[1].slice(0, index + 1);
12+
executeFlags(getFlags(userArgs));
913

10-
const flags = userArguments
11-
.filter((argument) => argument.startsWith("-"))
12-
.map((argument) => argument.slice(1))
13-
.join("");
14+
const currentWorkingDirectory = getCurrentWorkingDirectory(args);
15+
const fileNames = getFileNames(userArgs);
16+
17+
const allFilesData = addTotals(extractFilesData(fileNames, currentWorkingDirectory));
18+
printOutput(allFilesData);
19+
}
1420

21+
//
22+
// ===== Flag Handling =====
1523
const flagHandlers = {
1624
l: lFlag,
1725
w: wFlag,
1826
c: cFlag,
1927
};
2028

21-
const metrics = ["lineCount", "wordCount", "byteSize"];
22-
const fileNames = userArguments.filter((argument) => !argument.startsWith("-"));
23-
const allFilesData = [];
29+
function getFlags(userArgs) {
30+
return userArgs
31+
.filter((arg) => arg.startsWith("-"))
32+
.map((arg) => arg.slice(1))
33+
.join("");
34+
}
35+
36+
function executeFlags(flags) {
37+
for (const flag of flags) {
38+
if (flagHandlers[flag]) flagHandlers[flag]();
39+
else invalidFlagError();
40+
}
41+
}
42+
43+
function invalidFlagError() {
44+
console.error(`wc: illegal option -- ${flag}\nusage: wc [-Lclmw] [file ...]`);
45+
process.exit(1);
46+
}
47+
48+
function lFlag() {
49+
displayedMetrics.push("lineCount");
50+
}
51+
52+
function wFlag() {
53+
displayedMetrics.push("wordCount");
54+
}
55+
56+
function cFlag() {
57+
displayedMetrics.push("byteSize");
58+
}
59+
60+
//
61+
// ===== Extracting Data From Arguments =====
62+
function getCurrentWorkingDirectory(args) {
63+
const index = args[1].lastIndexOf("/");
64+
return args[1].slice(0, index + 1);
65+
}
2466

25-
extractFilesData();
26-
addTotals();
27-
const outputData = structuredClone(allFilesData);
67+
function getFileNames(userArgs) {
68+
return userArgs.filter((argument) => !argument.startsWith("-"));
69+
}
2870

29-
let deleted = false;
30-
executeFlags();
31-
printOutput();
71+
//
72+
// ===== Extracting Files Data =====
73+
function extractFilesData(fileNames, currentWorkingDirectory) {
74+
const allFilesData = [];
3275

33-
function extractFilesData() {
3476
fileNames.forEach((fileName) => {
3577
const fileData = {};
3678
fileData.name = fileName;
37-
fileData.text = readFile(fileName);
79+
fileData.text = readFile(fileName, currentWorkingDirectory);
3880
fileData.lineCount = calculateLineCount(fileData.text);
3981
fileData.wordCount = calculateWordCount(fileData.text);
40-
fileData.byteSize = readByteSize(fileName);
82+
fileData.byteSize = readByteSize(fileName, currentWorkingDirectory);
4183

4284
allFilesData.push(fileData);
4385
});
86+
return allFilesData;
4487
}
4588

46-
function addTotals() {
47-
if (allFilesData.length == 1) {
48-
return;
49-
}
50-
const totalsData = { name: "total" };
51-
metrics.forEach((metric) => {
52-
let sum = 0;
53-
allFilesData.forEach((file) => {
54-
sum += file[metric];
55-
});
56-
totalsData[metric] = sum;
57-
});
58-
allFilesData.push(totalsData);
59-
}
60-
61-
function readFile(fileName) {
89+
function readFile(fileName, currentWorkingDirectory) {
6290
const filePath = currentWorkingDirectory + fileName;
6391
return fs.readFileSync(filePath, "utf8").trimEnd();
6492
}
@@ -71,71 +99,41 @@ function calculateWordCount(text) {
7199
return text.split(/\s+/).length;
72100
}
73101

74-
function readByteSize(fileName) {
102+
function readByteSize(fileName, currentWorkingDirectory) {
75103
return fs.statSync(currentWorkingDirectory + fileName).size;
76104
}
77105

78-
function executeFlags() {
79-
for (const flag of flags) {
80-
if (flagHandlers[flag]) {
81-
allFilesContents = flagHandlers[flag]();
82-
} else {
83-
console.error(`wc: illegal option -- ${flag}\nusage: wc [-Lclmw] [file ...]`);
84-
process.exit(1);
85-
}
86-
}
87-
}
88-
89-
function lFlag() {
90-
deleteOutputs();
91-
allFilesData.forEach((sourceFile) => {
92-
const targetFile = outputData.find((file) => file.name === sourceFile.name);
93-
targetFile.lineCount = getIfTrue(sourceFile, "lineCount");
94-
});
95-
}
96-
97-
function wFlag() {
98-
deleteOutputs();
99-
allFilesData.forEach((sourceFile) => {
100-
const targetFile = outputData.find((file) => file.name === sourceFile.name);
101-
targetFile.wordCount = getIfTrue(sourceFile, "wordCount");
102-
});
103-
}
106+
function addTotals(allFilesData) {
107+
if (allFilesData.length == 1) return allFilesData;
104108

105-
function cFlag() {
106-
deleteOutputs();
107-
allFilesData.forEach((sourceFile) => {
108-
const targetFile = outputData.find((file) => file.name === sourceFile.name);
109-
targetFile.byteSize = getIfTrue(sourceFile, "byteSize");
110-
});
111-
}
112-
113-
function deleteOutputs() {
114-
if (!deleted) {
115-
outputData.forEach((file) => {
116-
metrics.forEach((metric) => {
117-
delete file[metric];
118-
});
109+
const totalsData = { name: "total" };
110+
metrics.forEach((metric) => {
111+
let sum = 0;
112+
allFilesData.forEach((file) => {
113+
sum += file[metric];
119114
});
120-
}
121-
deleted = true;
115+
totalsData[metric] = sum;
116+
});
117+
allFilesData.push(totalsData);
118+
return allFilesData;
122119
}
123120

124-
function printOutput() {
125-
outputs = [];
121+
//
122+
// ===== Outputting Data =====
123+
function printOutput(outputData) {
126124
outputData.forEach((file) => {
127125
let outputString = "";
128126
metrics.forEach((metric) => {
129-
outputString += getIfTrue(file, metric);
127+
if (displayedMetrics.length === 0 || displayedMetrics.includes(metric)) {
128+
outputString += String(file[metric]).padStart(8, " ");
129+
}
130130
});
131+
131132
outputString += ` ${file.name}`;
132133
console.log(outputString);
133134
});
134135
}
135136

136-
function getIfTrue(file, metric) {
137-
if (file[metric]) {
138-
return String(file[metric]).padStart(8, " ");
139-
}
140-
return "";
141-
}
137+
//
138+
// ===== Run wc =====
139+
wc(process.argv);

0 commit comments

Comments
 (0)