Index: rosapps/applications/cmdutils/comp/comp.c =================================================================== --- rosapps/applications/cmdutils/comp/comp.c (revision 51078) +++ rosapps/applications/cmdutils/comp/comp.c (working copy) @@ -45,13 +45,25 @@ return strlen(line); } +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; +} + /* print program usage */ VOID Usage(VOID) { _tprintf(_T("\nCompares the contents of two files or sets of files.\n\n" - "COMP [data1] [data2]\n\n" + "COMP [/L] [/A] [data1] [data2]\n\n" " data1 Specifies location and name of first file to compare.\n" - " data2 Specifies location and name of second file to compare.\n")); + " data2 Specifies location and name of second file to compare.\n" + " /A Display differences in ASCII characters.\n" + " /L Display line numbers for differences.\n")); } @@ -64,22 +76,25 @@ PTCHAR Line2 = (TCHAR *)malloc(STRBUF * sizeof(TCHAR)); TCHAR File1[_MAX_PATH], // file paths File2[_MAX_PATH]; - BOOL bMatch = TRUE, // files match - bAscii = FALSE, // /A switch + BOOL bAscii = FALSE, // /A switch bLineNos = FALSE; // /L switch + INT LineNumber; + INT Offset; + INT FileSizeFile1; + INT FileSizeFile2; + INT NumberOfOptions = 0; /* parse command line for options */ for (i = 1; i < argc; i++) { if (argv[i][0] == '/') { - --argc; switch (argv[i][1]) { case 'A': bAscii = TRUE; - _tprintf(_T("/a not Supported\n")); /*FIXME: needs adding */ + NumberOfOptions++; break; case 'L': bLineNos = TRUE; - _tprintf(_T("/l not supported\n")); /*FIXME: needs adding */ + NumberOfOptions++; break; case '?': Usage(); return EXIT_SUCCESS; @@ -91,7 +106,7 @@ } } - switch (argc) + switch (argc - NumberOfOptions) { case 1 : _tprintf(_T("Name of first file to compare: ")); @@ -117,7 +132,7 @@ } break; case 2 : - _tcsncpy(File1, argv[1], _MAX_PATH); + _tcsncpy(File1, argv[1 + NumberOfOptions], _MAX_PATH); _tprintf(_T("Name of second file to compare: ")); fgets(File2, _MAX_PATH, stdin); for (i=0; i<_MAX_PATH; i++) @@ -130,8 +145,8 @@ } break; case 3 : - _tcsncpy(File1, argv[1], _MAX_PATH); - _tcsncpy(File2, argv[2], _MAX_PATH); + _tcsncpy(File1, argv[1 + NumberOfOptions], _MAX_PATH); + _tcsncpy(File2, argv[2 + NumberOfOptions], _MAX_PATH); break; default : _tprintf(_T("Bad command line syntax\n")); @@ -155,26 +170,80 @@ _tprintf(_T("Comparing %s and %s...\n"), File1, File2); - while ((LineLen1 = GetLine(Line1, fp1) != 0) && - (LineLen2 = GetLine(Line2, fp2) != 0)) - { - // LineCount++; - while ((*Line1 != '\0') && (*Line2 != '\0')) - { - if (*Line1 != *Line2) - { - bMatch = FALSE; - break; - } - Line1++, Line2++; + FileSizeFile1 = FileSize(fp1); + if (FileSizeFile1 == -1) { + _tprintf(_T("Can't determine size of file: %s\n"), File1); + return EXIT_FAILURE; + } + + FileSizeFile2 = FileSize(fp2); + if (FileSizeFile2 == -1) { + _tprintf(_T("Can't determine size of file: %s\n"), File2); + return EXIT_FAILURE; + } + + if (FileSizeFile1 != FileSizeFile2) + goto DIFFERENT_SIZES; + + LineNumber = 1; + Offset = 0; + while (1) { + LineLen1 = GetLine(Line1, fp1); + LineLen2 = GetLine(Line2, fp2); + + //we are at the end + if (!LineLen1 && !LineLen2) + goto SUCCESS; + + if (LineLen1 != LineLen2) + goto DIFFERENT_SIZES; + + for (i = 0; i < LineLen1; i++) { + if (Line1[i] != Line2[i]) + goto REPORTING_MISMATCH; + Offset++; + + if (Line1[i] == '\n') + LineNumber++; } } - bMatch ? _tprintf(_T("Files compare OK\n")) : _tprintf(_T("Files are different sizes.\n")); +SUCCESS: + _tprintf(_T("Files compare OK\n")); + goto COMMON_END; +DIFFERENT_SIZES: + _tprintf(_T("Files are different sizes.\n")); + goto COMMON_END; + +REPORTING_MISMATCH: + if (bLineNos) + { + _tprintf(_T("Compare error at LINE %d\n"), LineNumber); + } + else + { + _tprintf(_T("Compare error at OFFSET %d\n"), Offset); + } + if (bAscii) + { + _tprintf(_T("file1 = %c\n"), Line1[i]); + _tprintf(_T("file2 = %c\n"), Line2[i]); + } + else + { + _tprintf(_T("file1 = %2X\n"), Line1[i]); + _tprintf(_T("file2 = %2X\n"), Line2[i]); + } + + +COMMON_END: + fclose(fp1); fclose(fp2); + free(Line1); + free(Line2); return EXIT_SUCCESS; }