2 * ReactOS Win32 Applications
3 * Copyright (C) 2005 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * PROJECT: ReactOS Comp utility
21 * COPYRIGHT: See COPYING in the top level directory
22 * FILE: base/applications/cmdutils/comp/comp.c
23 * PURPOSE: Compares the contents of two files
24 * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
31 #define WIN32_NO_STATUS
41 /* getline: read a line, return length */
42 INT
GetBuff(PBYTE buff
, FILE* in
)
44 return fread(buff
, sizeof(BYTE
), STRBUF
, in
);
47 INT
FileSize(FILE* fd
)
50 if (fseek(fd
, 0, SEEK_END
) == 0 && (result
= ftell(fd
)) != -1)
52 /* Restoring file pointer */
59 int wmain(int argc
, WCHAR
* argv
[])
70 WCHAR File1
[_MAX_PATH
+ 1], // File paths
72 BOOL bAscii
= FALSE
, // /A switch
73 bLineNos
= FALSE
; // /L switch
78 INT NumberOfOptions
= 0;
80 INT Status
= EXIT_SUCCESS
;
82 /* Initialize the Console Standard Streams */
85 /* Parse command line for options */
86 for (i
= 1; i
< argc
; i
++)
88 if (argv
[i
][0] == L
'/')
90 switch (towlower(argv
[i
][1]))
103 ConResPuts(StdOut
, IDS_HELP
);
107 ConResPrintf(StdErr
, IDS_INVALIDSWITCH
, argv
[i
][1]);
108 ConResPuts(StdOut
, IDS_HELP
);
114 if (argc
- NumberOfOptions
== 3)
116 wcsncpy(File1
, argv
[1 + NumberOfOptions
], _MAX_PATH
);
117 wcsncpy(File2
, argv
[2 + NumberOfOptions
], _MAX_PATH
);
121 ConResPuts(StdErr
, IDS_BADSYNTAX
);
125 Buff1
= (PBYTE
)malloc(STRBUF
);
128 ConPuts(StdErr
, L
"Can't get free memory for Buff1\n");
129 Status
= EXIT_FAILURE
;
133 Buff2
= (PBYTE
)malloc(STRBUF
);
136 ConPuts(StdErr
, L
"Can't get free memory for Buff2\n");
137 Status
= EXIT_FAILURE
;
141 if ((fp1
= _wfopen(File1
, L
"rb")) == NULL
)
143 ConResPrintf(StdErr
, IDS_FILEERROR
, File1
);
144 Status
= EXIT_FAILURE
;
147 if ((fp2
= _wfopen(File2
, L
"rb")) == NULL
)
149 ConResPrintf(StdErr
, IDS_FILEERROR
, File2
);
150 Status
= EXIT_FAILURE
;
154 ConResPrintf(StdOut
, IDS_COMPARING
, File1
, File2
);
156 FileSizeFile1
= FileSize(fp1
);
157 if (FileSizeFile1
== -1)
159 ConResPrintf(StdErr
, IDS_FILESIZEERROR
, File1
);
160 Status
= EXIT_FAILURE
;
164 FileSizeFile2
= FileSize(fp2
);
165 if (FileSizeFile2
== -1)
167 ConResPrintf(StdErr
, IDS_FILESIZEERROR
, File2
);
168 Status
= EXIT_FAILURE
;
172 if (FileSizeFile1
!= FileSizeFile2
)
174 ConResPuts(StdOut
, IDS_SIZEDIFFERS
);
175 Status
= EXIT_FAILURE
;
183 BufLen1
= GetBuff(Buff1
, fp1
);
184 BufLen2
= GetBuff(Buff2
, fp2
);
186 if (ferror(fp1
) || ferror(fp2
))
188 ConResPuts(StdErr
, IDS_READERROR
);
189 Status
= EXIT_FAILURE
;
193 if (!BufLen1
&& !BufLen2
)
196 assert(BufLen1
== BufLen2
);
197 for (i
= 0; i
< BufLen1
; i
++)
199 if (Buff1
[i
] != Buff2
[i
])
203 /* Reporting here a mismatch */
205 ConResPrintf(StdOut
, IDS_MISMATCHLINE
, LineNumber
);
207 ConResPrintf(StdOut
, IDS_MISMATCHOFFSET
, Offset
);
211 ConResPrintf(StdOut
, IDS_ASCIIDIFF
, 1, Buff1
[i
]);
212 ConResPrintf(StdOut
, IDS_ASCIIDIFF
, 2, Buff2
[i
]);
216 ConResPrintf(StdOut
, IDS_HEXADECIMALDIFF
, 1, Buff1
[i
]);
217 ConResPrintf(StdOut
, IDS_HEXADECIMALDIFF
, 2, Buff2
[i
]);
223 if (Buff1
[i
] == '\n')
229 ConResPuts(StdOut
, IDS_MATCH
);