11const fs = require ( "fs" ) ;
22const { 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 =====
1523const 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