-/*\r
- * ReactOS Win32 Applications\r
- * Copyright (C) 2005 ReactOS Team\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
- */\r
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS comp utility\r
- * FILE: comp.c\r
- * PURPOSE: Compares the contents of two files\r
- * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)\r
- * REVISIONS:\r
- * GM 25/09/05 Created\r
- *\r
- */\r
-\r
-\r
-#include <windows.h>\r
-#include <tchar.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-#define STRBUF 1024\r
-\r
-/* getline: read a line, return length */\r
-INT GetLine(char *line, FILE *in)\r
-{\r
- if (fgets(line, STRBUF, in) == NULL)\r
- return 0;\r
- else\r
- return strlen(line);\r
-}\r
-\r
-/* print program usage */\r
-VOID Usage(VOID)\r
-{\r
- _tprintf(_T("\nCompares the contents of two files or sets of files.\n\n"\r
- "COMP [data1] [data2]\n\n"\r
- " data1 Specifies location and name of first file to compare.\n"\r
- " data2 Specifies location and name of second file to compare.\n"));\r
-}\r
-\r
-\r
-int _tmain (int argc, TCHAR *argv[])\r
-{\r
- INT i;\r
- FILE *fp1, *fp2; // file pointers\r
- PTCHAR Line1 = (TCHAR *)malloc(STRBUF * sizeof(TCHAR));\r
- PTCHAR Line2 = (TCHAR *)malloc(STRBUF * sizeof(TCHAR));\r
- TCHAR File1[_MAX_PATH], // file paths\r
- File2[_MAX_PATH];\r
- BOOL bMatch = TRUE, // files match\r
- bAscii = FALSE, // /A switch\r
- bLineNos = FALSE; // /L switch\r
-\r
- /* parse command line for options */\r
- for (i = 1; i < argc; i++)\r
- {\r
- if (argv[i][0] == '/')\r
- {\r
- --argc;\r
- switch (argv[i][1]) {\r
- case 'A': bAscii = TRUE;\r
- _tprintf(_T("/a not Supported\n")); (void)bAscii; /*FIXME: needs adding */\r
- break;\r
- case 'L': bLineNos = TRUE;\r
- _tprintf(_T("/l not supported\n")); (void)bLineNos; /*FIXME: needs adding */\r
- break;\r
- case '?': Usage();\r
- return EXIT_SUCCESS;\r
- default:\r
- _tprintf(_T("Invalid switch - /%c\n"), argv[i][1]);\r
- Usage();\r
- return EXIT_FAILURE;\r
- }\r
- }\r
- }\r
-\r
- switch (argc)\r
- {\r
- case 1 :\r
- _tprintf(_T("Name of first file to compare: "));\r
- fgets(File1, _MAX_PATH, stdin);\r
- for (i=0; i<_MAX_PATH; i++)\r
- {\r
- if (File1[i] == '\n')\r
- {\r
- File1[i] = '\0';\r
- break;\r
- }\r
- }\r
-\r
- _tprintf(_T("Name of second file to compare: "));\r
- fgets(File2, _MAX_PATH, stdin);\r
- for (i=0; i<_MAX_PATH; i++)\r
- {\r
- if (File2[i] == '\n')\r
- {\r
- File2[i] = '\0';\r
- break;\r
- }\r
- }\r
- break;\r
- case 2 :\r
- _tcsncpy(File1, argv[1], _MAX_PATH);\r
- _tprintf(_T("Name of second file to compare: "));\r
- fgets(File2, _MAX_PATH, stdin);\r
- for (i=0; i<_MAX_PATH; i++)\r
- {\r
- if (File2[i] == '\n')\r
- {\r
- File2[i] = '\0';\r
- break;\r
- }\r
- }\r
- break;\r
- case 3 :\r
- _tcsncpy(File1, argv[1], _MAX_PATH);\r
- _tcsncpy(File2, argv[2], _MAX_PATH);\r
- break;\r
- default :\r
- _tprintf(_T("Bad command line syntax\n"));\r
- return EXIT_FAILURE;\r
- break;\r
- }\r
-\r
-\r
-\r
- if ((fp1 = fopen(File1, "r")) == NULL)\r
- {\r
- _tprintf(_T("Can't find/open file: %s\n"), File1);\r
- return EXIT_FAILURE;\r
- }\r
- if ((fp2 = fopen(File2, "r")) == NULL)\r
- {\r
- _tprintf(_T("Can't find/open file: %s\n"), File2);\r
- fclose(fp1);\r
- return EXIT_FAILURE;\r
- }\r
-\r
-\r
- _tprintf(_T("Comparing %s and %s...\n"), File1, File2);\r
-\r
- while ((GetLine(Line1, fp1) != 0) &&\r
- (GetLine(Line2, fp2) != 0))\r
- {\r
- // LineCount++;\r
- while ((*Line1 != '\0') && (*Line2 != '\0'))\r
- {\r
- if (*Line1 != *Line2)\r
- {\r
- bMatch = FALSE;\r
- break;\r
- }\r
- Line1++, Line2++;\r
- }\r
- }\r
-\r
- bMatch ? _tprintf(_T("Files compare OK\n")) : _tprintf(_T("Files are different sizes.\n"));\r
-\r
- fclose(fp1);\r
- fclose(fp2);\r
-\r
-\r
- return EXIT_SUCCESS;\r
-}\r
-/* EOF */\r
+/*
+ * ReactOS Win32 Applications
+ * Copyright (C) 2005 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * PROJECT: ReactOS Comp utility
+ * COPYRIGHT: See COPYING in the top level directory
+ * FILE: base/applications/cmdutils/comp/comp.c
+ * PURPOSE: Compares the contents of two files
+ * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#define WIN32_NO_STATUS
+#include <windef.h>
+#include <winbase.h>
+
+#include <conutils.h>
+
+#include "resource.h"
+
+#define STRBUF 1024
+
+/* getline: read a line, return length */
+INT GetBuff(PBYTE buff, FILE* in)
+{
+ return fread(buff, sizeof(BYTE), STRBUF, in);
+}
+
+INT FileSize(FILE* fd)
+{
+ INT result = -1;
+ if (fseek(fd, 0, SEEK_END) == 0 && (result = ftell(fd)) != -1)
+ {
+ /* Restoring file pointer */
+ rewind(fd);
+ }
+ return result;
+}
+
+
+int wmain(int argc, WCHAR* argv[])
+{
+ INT i;
+
+ /* File pointers */
+ FILE *fp1 = NULL;
+ FILE *fp2 = NULL;
+
+ INT BufLen1, BufLen2;
+ PBYTE Buff1 = NULL;
+ PBYTE Buff2 = NULL;
+ WCHAR File1[_MAX_PATH + 1], // File paths
+ File2[_MAX_PATH + 1];
+ BOOL bAscii = FALSE, // /A switch
+ bLineNos = FALSE; // /L switch
+ UINT LineNumber;
+ UINT Offset;
+ INT FileSizeFile1;
+ INT FileSizeFile2;
+ INT NumberOfOptions = 0;
+ INT FilesOK = 1;
+ INT Status = EXIT_SUCCESS;
+
+ /* Initialize the Console Standard Streams */
+ ConInitStdStreams();
+
+ /* Parse command line for options */
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i][0] == L'/')
+ {
+ switch (towlower(argv[i][1]))
+ {
+ case L'a':
+ bAscii = TRUE;
+ NumberOfOptions++;
+ break;
+
+ case L'l':
+ bLineNos = TRUE;
+ NumberOfOptions++;
+ break;
+
+ case L'?':
+ ConResPuts(StdOut, IDS_HELP);
+ return EXIT_SUCCESS;
+
+ default:
+ ConResPrintf(StdErr, IDS_INVALIDSWITCH, argv[i][1]);
+ ConResPuts(StdOut, IDS_HELP);
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ if (argc - NumberOfOptions == 3)
+ {
+ wcsncpy(File1, argv[1 + NumberOfOptions], _MAX_PATH);
+ wcsncpy(File2, argv[2 + NumberOfOptions], _MAX_PATH);
+ }
+ else
+ {
+ ConResPuts(StdErr, IDS_BADSYNTAX);
+ return EXIT_FAILURE;
+ }
+
+ Buff1 = (PBYTE)malloc(STRBUF);
+ if (Buff1 == NULL)
+ {
+ ConPuts(StdErr, L"Can't get free memory for Buff1\n");
+ Status = EXIT_FAILURE;
+ goto Cleanup;
+ }
+
+ Buff2 = (PBYTE)malloc(STRBUF);
+ if (Buff2 == NULL)
+ {
+ ConPuts(StdErr, L"Can't get free memory for Buff2\n");
+ Status = EXIT_FAILURE;
+ goto Cleanup;
+ }
+
+ if ((fp1 = _wfopen(File1, L"rb")) == NULL)
+ {
+ ConResPrintf(StdErr, IDS_FILEERROR, File1);
+ Status = EXIT_FAILURE;
+ goto Cleanup;
+ }
+ if ((fp2 = _wfopen(File2, L"rb")) == NULL)
+ {
+ ConResPrintf(StdErr, IDS_FILEERROR, File2);
+ Status = EXIT_FAILURE;
+ goto Cleanup;
+ }
+
+ ConResPrintf(StdOut, IDS_COMPARING, File1, File2);
+
+ FileSizeFile1 = FileSize(fp1);
+ if (FileSizeFile1 == -1)
+ {
+ ConResPrintf(StdErr, IDS_FILESIZEERROR, File1);
+ Status = EXIT_FAILURE;
+ goto Cleanup;
+ }
+
+ FileSizeFile2 = FileSize(fp2);
+ if (FileSizeFile2 == -1)
+ {
+ ConResPrintf(StdErr, IDS_FILESIZEERROR, File2);
+ Status = EXIT_FAILURE;
+ goto Cleanup;
+ }
+
+ if (FileSizeFile1 != FileSizeFile2)
+ {
+ ConResPuts(StdOut, IDS_SIZEDIFFERS);
+ Status = EXIT_FAILURE;
+ goto Cleanup;
+ }
+
+ LineNumber = 1;
+ Offset = 0;
+ while (1)
+ {
+ BufLen1 = GetBuff(Buff1, fp1);
+ BufLen2 = GetBuff(Buff2, fp2);
+
+ if (ferror(fp1) || ferror(fp2))
+ {
+ ConResPuts(StdErr, IDS_READERROR);
+ Status = EXIT_FAILURE;
+ goto Cleanup;
+ }
+
+ if (!BufLen1 && !BufLen2)
+ break;
+
+ assert(BufLen1 == BufLen2);
+ for (i = 0; i < BufLen1; i++)
+ {
+ if (Buff1[i] != Buff2[i])
+ {
+ FilesOK = 0;
+
+ /* Reporting here a mismatch */
+ if (bLineNos)
+ ConResPrintf(StdOut, IDS_MISMATCHLINE, LineNumber);
+ else
+ ConResPrintf(StdOut, IDS_MISMATCHOFFSET, Offset);
+
+ if (bAscii)
+ {
+ ConResPrintf(StdOut, IDS_ASCIIDIFF, 1, Buff1[i]);
+ ConResPrintf(StdOut, IDS_ASCIIDIFF, 2, Buff2[i]);
+ }
+ else
+ {
+ ConResPrintf(StdOut, IDS_HEXADECIMALDIFF, 1, Buff1[i]);
+ ConResPrintf(StdOut, IDS_HEXADECIMALDIFF, 2, Buff2[i]);
+ }
+ }
+
+ Offset++;
+
+ if (Buff1[i] == '\n')
+ LineNumber++;
+ }
+ }
+
+ if (FilesOK)
+ ConResPuts(StdOut, IDS_MATCH);
+
+Cleanup:
+ if (fp2)
+ fclose(fp2);
+ if (fp1)
+ fclose(fp1);
+
+ if (Buff2)
+ free(Buff2);
+ if (Buff1)
+ free(Buff1);
+
+ return Status;
+}
+
+/* EOF */