summaryrefslogtreecommitdiffstatshomepage
path: root/src/tools/romcmp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/romcmp.cpp')
-rw-r--r--src/tools/romcmp.cpp743
1 files changed, 365 insertions, 378 deletions
diff --git a/src/tools/romcmp.cpp b/src/tools/romcmp.cpp
index 4862f74a769..b65889c70a1 100644
--- a/src/tools/romcmp.cpp
+++ b/src/tools/romcmp.cpp
@@ -8,25 +8,20 @@
***************************************************************************/
+#include "hash.h"
+#include "path.h"
#include "unzip.h"
+
#include "osdfile.h"
#include "osdcomm.h"
-#include "hash.h"
#include <cstdarg>
#include <cstdlib>
+#include <memory>
#define MAX_FILES 1000
-#ifndef MAX_FILENAME_LEN
-#define MAX_FILENAME_LEN 255
-#endif
-
-#ifndef PATH_DELIM
-#define PATH_DELIM '/'
-#endif
-
/* compare modes when one file is twice as long as the other */
@@ -105,382 +100,383 @@ static void compatiblemodes(int mode,int *start,int *end)
struct fileinfo
{
- char name[MAX_FILENAME_LEN+1];
+ std::string name;
int size;
- unsigned char *buf; /* file is read in here */
+ std::unique_ptr<unsigned char []> buf; // file is read in here
int listed;
-};
-
-static fileinfo files[2][MAX_FILES];
-static float matchscore[MAX_FILES][MAX_FILES][TOTAL_MODES][TOTAL_MODES];
-static bool is_ascii_char(int ch)
-{
- return (ch >= 0x20 && ch < 0x7f) || (ch == '\n') || (ch == '\r') || (ch == '\t');
-}
-
-static void checkintegrity(const fileinfo *file, int side, bool all_hashes)
-{
- if (file->buf == nullptr) return;
-
- if (all_hashes)
+ static constexpr bool is_ascii_char(int ch)
{
- util::crc32_creator crc32;
- util::sha1_creator sha1;
- util::sum16_creator sum16;
- crc32.append(file->buf, file->size);
- sha1.append(file->buf, file->size);
- sum16.append(file->buf, file->size);
- printf("%-23s %-23s [0x%x] CRC(%s) SHA1(%s) SUM(%s)\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "", file->size,
- crc32.finish().as_string().c_str(), sha1.finish().as_string().c_str(), sum16.finish().as_string().c_str());
- side = 0;
+ return (ch >= 0x20 && ch < 0x7f) || (ch == '\n') || (ch == '\r') || (ch == '\t');
}
- /* check for bad data lines */
- unsigned mask0 = 0x0000;
- unsigned mask1 = 0xffff;
- bool is_ascii = true;
- for (unsigned i = 0; i < file->size; i += 2)
+ void checkintegrity(int side, bool all_hashes) const
{
- is_ascii = is_ascii && is_ascii_char(file->buf[i]);
- mask0 |= file->buf[i] << 8;
- mask1 &= (file->buf[i] << 8) | 0x00ff;
- if (i < file->size - 1)
+ if (!buf)
+ return;
+
+ if (all_hashes)
{
- is_ascii = is_ascii && is_ascii_char(file->buf[i+1]);
- mask0 |= file->buf[i+1];
- mask1 &= file->buf[i+1] | 0xff00;
+ util::crc32_creator crc32;
+ util::sha1_creator sha1;
+ util::sum16_creator sum16;
+ crc32.append(buf.get(), size);
+ sha1.append(buf.get(), size);
+ sum16.append(buf.get(), size);
+ printf("%-23s %-23s [0x%x] CRC(%s) SHA1(%s) SUM(%s)\n",
+ (side & 1) ? name.c_str() : "",
+ (side & 2) ? name.c_str() : "",
+ size,
+ crc32.finish().as_string().c_str(),
+ sha1.finish().as_string().c_str(),
+ sum16.finish().as_string().c_str());
+ side = 0;
}
- if (mask0 == 0xffff && mask1 == 0x0000) break;
- }
-
- if (is_ascii && mask0 == 0x7f7f && mask1 == 0)
- {
- printf("%-23s %-23s ASCII TEXT FILE\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- return;
- }
- if (mask0 != 0xffff || mask1 != 0x0000)
- {
- int fixedmask;
- int bits;
+ // check for bad data lines
+ unsigned mask0 = 0x0000;
+ unsigned mask1 = 0xffff;
- fixedmask = (~mask0 | mask1) & 0xffff;
+ bool is_ascii = true;
+ for (unsigned i = 0; i < size; i += 2)
+ {
+ is_ascii = is_ascii && is_ascii_char(buf[i]);
+ mask0 |= buf[i] << 8;
+ mask1 &= (buf[i] << 8) | 0x00ff;
+ if (i < size - 1)
+ {
+ is_ascii = is_ascii && is_ascii_char(buf[i+1]);
+ mask0 |= buf[i+1];
+ mask1 &= buf[i+1] | 0xff00;
+ }
+ if (mask0 == 0xffff && mask1 == 0x0000) break;
+ }
- if (((mask0 >> 8) & 0xff) == (mask0 & 0xff) && ((mask1 >> 8) & 0xff) == (mask1 & 0xff))
- bits = 8;
- else bits = 16;
+ if (is_ascii && mask0 == 0x7f7f && mask1 == 0)
+ {
+ printf("%-23s %-23s ASCII TEXT FILE\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ return;
+ }
- printf("%-23s %-23s FIXED BITS (", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- for (int i = 0; i < bits; i++)
+ if (mask0 != 0xffff || mask1 != 0x0000)
{
- if (~mask0 & 0x8000) printf("0");
- else if (mask1 & 0x8000) printf("1");
- else printf("x");
+ int fixedmask;
+ int bits;
- mask0 <<= 1;
- mask1 <<= 1;
- }
- printf(")\n");
+ fixedmask = (~mask0 | mask1) & 0xffff;
- /* if the file contains a fixed value, we don't need to do the other */
- /* validity checks */
- if (fixedmask == 0xffff || fixedmask == 0x00ff || fixedmask == 0xff00)
- return;
- }
+ if (((mask0 >> 8) & 0xff) == (mask0 & 0xff) && ((mask1 >> 8) & 0xff) == (mask1 & 0xff))
+ bits = 8;
+ else bits = 16;
- unsigned addrbit = 1;
- unsigned addrmirror = 0;
- while (addrbit <= file->size/2)
- {
- unsigned i = 0;
- for (i = 0; i < file->size; i++)
+ printf("%-23s %-23s FIXED BITS (", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ for (int i = 0; i < bits; i++)
+ {
+ if (~mask0 & 0x8000) printf("0");
+ else if (mask1 & 0x8000) printf("1");
+ else printf("x");
+
+ mask0 <<= 1;
+ mask1 <<= 1;
+ }
+ printf(")\n");
+
+ /* if the file contains a fixed value, we don't need to do the other */
+ /* validity checks */
+ if (fixedmask == 0xffff || fixedmask == 0x00ff || fixedmask == 0xff00)
+ return;
+ }
+
+ unsigned addrbit = 1;
+ unsigned addrmirror = 0;
+ while (addrbit <= size/2)
{
- if ((i ^ addrbit) < file->size && file->buf[i] != file->buf[i ^ addrbit]) break;
+ unsigned i = 0;
+ for (i = 0; i < size; i++)
+ {
+ if ((i ^ addrbit) < size && buf[i] != buf[i ^ addrbit]) break;
+ }
+
+ if (i == size)
+ addrmirror |= addrbit;
+
+ addrbit <<= 1;
}
- if (i == file->size)
- addrmirror |= addrbit;
+ if (addrmirror != 0)
+ {
+ if (addrmirror == size/2)
+ {
+ printf("%-23s %-23s 1ST AND 2ND HALF IDENTICAL\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ util::hash_collection hash;
+ hash.begin();
+ hash.buffer(buf.get(), size / 2);
+ hash.end();
+ printf("%-23s %-23s %s\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "", hash.attribute_string().c_str());
+ }
+ else
+ {
+ printf("%-23s %-23s BADADDR", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ for (int i = 0; i < 24; i++)
+ {
+ if (size <= (1<<(23-i))) printf(" ");
+ else if (addrmirror & 0x800000) printf("-");
+ else printf("x");
+ addrmirror <<= 1;
+ }
+ printf("\n");
+ }
+ return;
+ }
- addrbit <<= 1;
- }
+ unsigned sizemask = 1;
+ while (sizemask < size - 1)
+ sizemask = (sizemask << 1) | 1;
- if (addrmirror != 0)
- {
- if (addrmirror == file->size/2)
+ mask0 = 0x000000;
+ mask1 = sizemask;
+ for (unsigned i = 0; i < size; i++)
{
- printf("%-23s %-23s 1ST AND 2ND HALF IDENTICAL\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- util::hash_collection hash;
- hash.begin();
- hash.buffer(file->buf, file->size / 2);
- hash.end();
- printf("%-23s %-23s %s\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "", hash.attribute_string().c_str());
+ if (buf[i] != 0xff)
+ {
+ mask0 |= i;
+ mask1 &= i;
+ if (mask0 == sizemask && mask1 == 0x00) break;
+ }
}
- else
+
+ if (mask0 != sizemask || mask1 != 0x00)
{
- printf("%-23s %-23s BADADDR", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
+ printf("%-23s %-23s ", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
for (int i = 0; i < 24; i++)
{
- if (file->size <= (1<<(23-i))) printf(" ");
- else if (addrmirror & 0x800000) printf("-");
+ if (size <= (1<<(23-i))) printf(" ");
+ else if (~mask0 & 0x800000) printf("1");
+ else if (mask1 & 0x800000) printf("0");
else printf("x");
- addrmirror <<= 1;
+ mask0 <<= 1;
+ mask1 <<= 1;
}
- printf("\n");
+ printf(" = 0xFF\n");
+
+ return;
}
- return;
- }
- unsigned sizemask = 1;
- while (sizemask < file->size - 1)
- sizemask = (sizemask << 1) | 1;
- mask0 = 0x000000;
- mask1 = sizemask;
- for (unsigned i = 0; i < file->size; i++)
- {
- if (file->buf[i] != 0xff)
+ mask0 = 0x000000;
+ mask1 = sizemask;
+ for (unsigned i = 0; i < size; i++)
{
- mask0 |= i;
- mask1 &= i;
- if (mask0 == sizemask && mask1 == 0x00) break;
+ if (buf[i] != 0x00)
+ {
+ mask0 |= i;
+ mask1 &= i;
+ if (mask0 == sizemask && mask1 == 0x00) break;
+ }
}
- }
- if (mask0 != sizemask || mask1 != 0x00)
- {
- printf("%-23s %-23s ", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- for (int i = 0; i < 24; i++)
+ if (mask0 != sizemask || mask1 != 0x00)
{
- if (file->size <= (1<<(23-i))) printf(" ");
- else if (~mask0 & 0x800000) printf("1");
- else if (mask1 & 0x800000) printf("0");
- else printf("x");
- mask0 <<= 1;
- mask1 <<= 1;
- }
- printf(" = 0xFF\n");
-
- return;
- }
+ printf("%-23s %-23s ", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ for (int i = 0; i < 24; i++)
+ {
+ if (size <= (1<<(23-i))) printf(" ");
+ else if ((mask0 & 0x800000) == 0) printf("1");
+ else if (mask1 & 0x800000) printf("0");
+ else printf("x");
+ mask0 <<= 1;
+ mask1 <<= 1;
+ }
+ printf(" = 0x00\n");
+ return;
+ }
- mask0 = 0x000000;
- mask1 = sizemask;
- for (unsigned i = 0; i < file->size; i++)
- {
- if (file->buf[i] != 0x00)
+ mask0 = 0xff;
+ for (unsigned i = 0; i < size/4 && mask0 != 0x00; i++)
{
- mask0 |= i;
- mask1 &= i;
- if (mask0 == sizemask && mask1 == 0x00) break;
+ if (buf[ 2*i ] != 0x00) mask0 &= ~0x01;
+ if (buf[ 2*i ] != 0xff) mask0 &= ~0x02;
+ if (buf[ 2*i+1] != 0x00) mask0 &= ~0x04;
+ if (buf[ 2*i+1] != 0xff) mask0 &= ~0x08;
+ if (buf[size/2 + 2*i ] != 0x00) mask0 &= ~0x10;
+ if (buf[size/2 + 2*i ] != 0xff) mask0 &= ~0x20;
+ if (buf[size/2 + 2*i+1] != 0x00) mask0 &= ~0x40;
+ if (buf[size/2 + 2*i+1] != 0xff) mask0 &= ~0x80;
}
+
+ if (mask0 & 0x01) printf("%-23s %-23s 1ST HALF = 00xx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x02) printf("%-23s %-23s 1ST HALF = FFxx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x04) printf("%-23s %-23s 1ST HALF = xx00\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x08) printf("%-23s %-23s 1ST HALF = xxFF\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x10) printf("%-23s %-23s 2ND HALF = 00xx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x20) printf("%-23s %-23s 2ND HALF = FFxx\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x40) printf("%-23s %-23s 2ND HALF = xx00\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
+ if (mask0 & 0x80) printf("%-23s %-23s 2ND HALF = xxFF\n", (side & 1) ? name.c_str() : "", (side & 2) ? name.c_str() : "");
}
- if (mask0 != sizemask || mask1 != 0x00)
+ int usedbytes(int mode) const
{
- printf("%-23s %-23s ", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- for (int i = 0; i < 24; i++)
+ switch (mode)
{
- if (file->size <= (1<<(23-i))) printf(" ");
- else if ((mask0 & 0x800000) == 0) printf("1");
- else if (mask1 & 0x800000) printf("0");
- else printf("x");
- mask0 <<= 1;
- mask1 <<= 1;
+ case MODE_A:
+ case MODE_NIB1:
+ case MODE_NIB2:
+ return size;
+ case MODE_12:
+ case MODE_22:
+ case MODE_E:
+ case MODE_O:
+ return size / 2;
+ case MODE_14:
+ case MODE_24:
+ case MODE_34:
+ case MODE_44:
+ case MODE_E12:
+ case MODE_O12:
+ case MODE_E22:
+ case MODE_O22:
+ return size / 4;
+ default:
+ return 0;
}
- printf(" = 0x00\n");
-
- return;
}
- mask0 = 0xff;
- for (unsigned i = 0; i < file->size/4 && mask0 != 0x00; i++)
+ void basemultmask(int mode, int &base, int &mult, int &mask) const
{
- if (file->buf[ 2*i ] != 0x00) mask0 &= ~0x01;
- if (file->buf[ 2*i ] != 0xff) mask0 &= ~0x02;
- if (file->buf[ 2*i+1] != 0x00) mask0 &= ~0x04;
- if (file->buf[ 2*i+1] != 0xff) mask0 &= ~0x08;
- if (file->buf[file->size/2 + 2*i ] != 0x00) mask0 &= ~0x10;
- if (file->buf[file->size/2 + 2*i ] != 0xff) mask0 &= ~0x20;
- if (file->buf[file->size/2 + 2*i+1] != 0x00) mask0 &= ~0x40;
- if (file->buf[file->size/2 + 2*i+1] != 0xff) mask0 &= ~0x80;
- }
+ mult = 1;
+ if (mode >= MODE_E)
+ mult = 2;
- if (mask0 & 0x01) printf("%-23s %-23s 1ST HALF = 00xx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x02) printf("%-23s %-23s 1ST HALF = FFxx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x04) printf("%-23s %-23s 1ST HALF = xx00\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x08) printf("%-23s %-23s 1ST HALF = xxFF\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x10) printf("%-23s %-23s 2ND HALF = 00xx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x20) printf("%-23s %-23s 2ND HALF = FFxx\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x40) printf("%-23s %-23s 2ND HALF = xx00\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
- if (mask0 & 0x80) printf("%-23s %-23s 2ND HALF = xxFF\n", (side & 1) ? file->name : "", (side & 2) ? file->name : "");
-}
-
-
-static int usedbytes(const fileinfo *file,int mode)
-{
- switch (mode)
- {
- case MODE_A:
- case MODE_NIB1:
- case MODE_NIB2:
- return file->size;
- case MODE_12:
- case MODE_22:
- case MODE_E:
- case MODE_O:
- return file->size / 2;
- case MODE_14:
- case MODE_24:
- case MODE_34:
- case MODE_44:
- case MODE_E12:
- case MODE_O12:
- case MODE_E22:
- case MODE_O22:
- return file->size / 4;
- default:
- return 0;
+ switch (mode)
+ {
+ case MODE_A:
+ case MODE_12:
+ case MODE_14:
+ case MODE_E:
+ case MODE_E12:
+ base = 0; mask = 0xff; break;
+ case MODE_NIB1:
+ base = 0; mask = 0x0f; break;
+ case MODE_NIB2:
+ base = 0; mask = 0xf0; break;
+ case MODE_O:
+ case MODE_O12:
+ base = 1; mask = 0xff; break;
+ case MODE_22:
+ case MODE_E22:
+ base = size / 2; mask = 0xff; break;
+ case MODE_O22:
+ base = 1 + size / 2; mask = 0xff; break;
+ case MODE_24:
+ base = size / 4; mask = 0xff; break;
+ case MODE_34:
+ base = 2*size / 4; mask = 0xff; break;
+ case MODE_44:
+ base = 3*size / 4; mask = 0xff; break;
+ }
}
-}
-
-static void basemultmask(const fileinfo *file,int mode,int *base,int *mult,int *mask)
-{
- *mult = 1;
- if (mode >= MODE_E) *mult = 2;
- switch (mode)
+ float compare(const fileinfo &file2, int mode1, int mode2) const
{
- case MODE_A:
- case MODE_12:
- case MODE_14:
- case MODE_E:
- case MODE_E12:
- *base = 0; *mask = 0xff; break;
- case MODE_NIB1:
- *base = 0; *mask = 0x0f; break;
- case MODE_NIB2:
- *base = 0; *mask = 0xf0; break;
- case MODE_O:
- case MODE_O12:
- *base = 1; *mask = 0xff; break;
- case MODE_22:
- case MODE_E22:
- *base = file->size / 2; *mask = 0xff; break;
- case MODE_O22:
- *base = 1 + file->size / 2; *mask = 0xff; break;
- case MODE_24:
- *base = file->size / 4; *mask = 0xff; break;
- case MODE_34:
- *base = 2*file->size / 4; *mask = 0xff; break;
- case MODE_44:
- *base = 3*file->size / 4; *mask = 0xff; break;
- }
-}
-
-static float filecompare(const fileinfo *file1,const fileinfo *file2,int mode1,int mode2)
-{
- int i;
- int match = 0;
- int size1,size2;
- int base1=0,base2=0,mult1=0,mult2=0,mask1=0,mask2=0;
+ if (!buf || !file2.buf)
+ return 0.0;
+ int const size1 = usedbytes(mode1);
+ int const size2 = file2.usedbytes(mode2);
- if (file1->buf == nullptr || file2->buf == nullptr) return 0.0;
+ if (size1 != size2)
+ return 0.0;
- size1 = usedbytes(file1,mode1);
- size2 = usedbytes(file2,mode2);
+ int base1=0, base2=0, mult1=0, mult2=0, mask1=0, mask2=0;
+ basemultmask(mode1, base1, mult1, mask1);
+ file2.basemultmask(mode2, base2, mult2, mask2);
- if (size1 != size2) return 0.0;
-
- basemultmask(file1,mode1,&base1,&mult1,&mask1);
- basemultmask(file2,mode2,&base2,&mult2,&mask2);
-
- if (mask1 == mask2)
- {
- if (mask1 == 0xff)
- {
- /* normal compare */
- for (i = 0;i < size1;i++)
- if (file1->buf[base1 + mult1 * i] == file2->buf[base2 + mult2 * i]) match++;
- }
- else
+ int match = 0;
+ if (mask1 == mask2)
{
- /* nibble compare, abort if other half is not empty */
- for (i = 0;i < size1;i++)
+ if (mask1 == 0xff)
+ {
+ // normal compare
+ for (int i = 0; i < size1; i++)
+ if (buf[base1 + mult1 * i] == file2.buf[base2 + mult2 * i]) match++;
+ }
+ else
{
- if (((file1->buf[base1 + mult1 * i] & ~mask1) != (0x00 & ~mask1) &&
- (file1->buf[base1 + mult1 * i] & ~mask1) != (0xff & ~mask1)) ||
- ((file2->buf[base1 + mult1 * i] & ~mask2) != (0x00 & ~mask2) &&
- (file2->buf[base1 + mult1 * i] & ~mask2) != (0xff & ~mask2)))
+ // nibble compare, abort if other half is not empty
+ for (int i = 0; i < size1; i++)
{
- match = 0;
- break;
+ if (((buf[base1 + mult1 * i] & ~mask1) != (0x00 & ~mask1) &&
+ (buf[base1 + mult1 * i] & ~mask1) != (0xff & ~mask1)) ||
+ ((file2.buf[base1 + mult1 * i] & ~mask2) != (0x00 & ~mask2) &&
+ (file2.buf[base1 + mult1 * i] & ~mask2) != (0xff & ~mask2)))
+ {
+ match = 0;
+ break;
+ }
+ if ((buf[base1 + mult1 * i] & mask1) == (file2.buf[base2 + mult2 * i] & mask2)) match++;
}
- if ((file1->buf[base1 + mult1 * i] & mask1) == (file2->buf[base2 + mult2 * i] & mask2)) match++;
}
}
- }
- return (float)match / size1;
-}
+ return float(match) / size1;
+ }
+ void readfile(const char *path)
+ {
+ std::string fullname(path ? path : "");
+ util::path_append(fullname, name);
-static void readfile(const char *path,fileinfo *file)
-{
- osd_file::error filerr;
- uint64_t filesize;
- uint32_t actual;
- char fullname[256];
- osd_file::ptr f;
+ buf.reset(new (std::nothrow) unsigned char [size]);
+ if (!buf)
+ {
+ printf("%s: out of memory!\n", name.c_str());
+ return;
+ }
- if (path)
- {
- char delim[2] = { PATH_DELIM, '\0' };
- strcpy(fullname,path);
- strcat(fullname,delim);
- }
- else fullname[0] = 0;
- strcat(fullname,file->name);
+ std::error_condition filerr;
+ osd_file::ptr f;
+ uint64_t filesize;
- if ((file->buf = (unsigned char *)malloc(file->size)) == nullptr)
- {
- printf("%s: out of memory!\n",file->name);
- return;
- }
+ filerr = osd_file::open(fullname, OPEN_FLAG_READ, f, filesize);
+ if (filerr)
+ {
+ printf("%s: error %s\n", fullname.c_str(), filerr.message().c_str());
+ return;
+ }
- filerr = osd_file::open(fullname, OPEN_FLAG_READ, f, filesize);
- if (filerr != osd_file::error::NONE)
- {
- printf("%s: error %d\n", fullname, int(filerr));
- return;
+ uint32_t actual;
+ filerr = f->read(buf.get(), 0, size, actual);
+ if (filerr)
+ {
+ printf("%s: error %s\n", fullname.c_str(), filerr.message().c_str());
+ return;
+ }
}
- filerr = f->read(file->buf, 0, file->size, actual);
- if (filerr != osd_file::error::NONE)
+ void free()
{
- printf("%s: error %d\n", fullname, int(filerr));
- return;
+ buf.reset();
}
-}
-
+};
-static void freefile(fileinfo *file)
-{
- free(file->buf);
- file->buf = nullptr;
-}
+static fileinfo files[2][MAX_FILES];
+static float matchscore[MAX_FILES][MAX_FILES][TOTAL_MODES][TOTAL_MODES];
-static void printname(const fileinfo *file1,const fileinfo *file2,float score,int mode1,int mode2)
+static void printname(const fileinfo *file1, const fileinfo *file2, float score, int mode1, int mode2)
{
- printf("%-12s %s %-12s %s ",file1 ? file1->name : "",modenames[mode1],file2 ? file2->name : "",modenames[mode2]);
+ printf(
+ "%-12s %s %-12s %s ",
+ file1 ? file1->name.c_str() : "",
+ modenames[mode1],
+ file2 ? file2->name.c_str() : "",
+ modenames[mode2]);
if (score == 0.0f) printf("NO MATCH\n");
else if (score == 1.0f) printf("IDENTICAL\n");
- else printf("%3.6f%%\n",(double) (score*100));
+ else printf("%3.6f%%\n", double(score*100));
}
@@ -496,24 +492,23 @@ static int load_files(int i, int *found, const char *path)
while ((d = dir->read()) != nullptr)
{
const char *d_name = d->name;
- char buf[255+1];
+ const std::string buf(util::path_concat(path, d_name)); // FIXME: is this even used for anything?
- sprintf(buf, "%s%c%s", path, PATH_DELIM, d_name);
if (d->type == osd::directory::entry::entry_type::FILE)
{
uint64_t size = d->size;
while (size && (size & 1) == 0) size >>= 1;
//if (size & ~1)
- // printf("%-23s %-23s ignored (not a ROM)\n",i ? "" : d_name,i ? d_name : "");
+ // printf("%-23s %-23s ignored (not a ROM)\n", i ? "" : d_name, i ? d_name : "");
//else
{
- strcpy(files[i][found[i]].name,d_name);
+ files[i][found[i]].name = d_name;
files[i][found[i]].size = d->size;
- readfile(path,&files[i][found[i]]);
+ files[i][found[i]].readfile(path);
files[i][found[i]].listed = 0;
if (found[i] >= MAX_FILES)
{
- printf("%s: max of %d files exceeded\n",path,MAX_FILES);
+ printf("%s: max of %d files exceeded\n", path, MAX_FILES);
break;
}
found[i]++;
@@ -522,15 +517,13 @@ static int load_files(int i, int *found, const char *path)
}
dir.reset();
}
-
- /* if not, try to open as a ZIP file */
else
{
+ /* if not, try to open as a ZIP file */
util::archive_file::ptr zip;
/* wasn't a directory, so try to open it as a zip file */
- if ((util::archive_file::open_zip(path, zip) != util::archive_file::error::NONE) &&
- (util::archive_file::open_7z(path, zip) != util::archive_file::error::NONE))
+ if (util::archive_file::open_zip(path, zip) && util::archive_file::open_7z(path, zip))
{
printf("Error, cannot open zip file '%s' !\n", path);
return 1;
@@ -552,26 +545,26 @@ static int load_files(int i, int *found, const char *path)
}
else
{
- fileinfo *file = &files[i][found[i]];
+ fileinfo &file = files[i][found[i]];
const char *delim = strrchr(zip->current_name().c_str(), '/');
if (delim)
- strcpy (file->name,delim+1);
+ file.name = delim + 1;
else
- strcpy(file->name,zip->current_name().c_str());
- file->size = zip->current_uncompressed_length();
- if ((file->buf = (unsigned char *)malloc(file->size)) == nullptr)
- printf("%s: out of memory!\n",file->name);
+ file.name = zip->current_name();
+ file.size = zip->current_uncompressed_length();
+ file.buf.reset(new (std::nothrow) unsigned char [file.size]);
+ if (!file.buf)
+ {
+ printf("%s: out of memory!\n", file.name.c_str());
+ }
else
{
- if (zip->decompress(file->buf, file->size) != util::archive_file::error::NONE)
- {
- free(file->buf);
- file->buf = nullptr;
- }
+ if (zip->decompress(file.buf.get(), file.size))
+ file.free();
}
- file->listed = 0;
+ file.listed = 0;
if (found[i] >= MAX_FILES)
{
printf("%s: max of %d files exceeded\n",path,MAX_FILES);
@@ -612,13 +605,8 @@ int CLIB_DECL main(int argc,char *argv[])
}
{
- int found[2];
- int i,j,mode1,mode2;
- int besti,bestj;
-
-
- found[0] = found[1] = 0;
- for (i = 0;i < 2;i++)
+ int found[2] = { 0, 0 };
+ for (int i = 0; i < 2; i++)
{
if (argc > i+1)
{
@@ -633,26 +621,26 @@ int CLIB_DECL main(int argc,char *argv[])
else
printf("%d files\n",found[0]);
- for (i = 0; i < 2; i++)
+ for (int i = 0; i < 2; i++)
{
- for (j = 0; j < found[i]; j++)
+ for (int j = 0; j < found[i]; j++)
{
- checkintegrity(&files[i][j], 1 << i, all_hashes);
+ files[i][j].checkintegrity(1 << i, all_hashes);
}
}
if (argc < 3)
{
- /* find duplicates in one dir */
- for (i = 0;i < found[0];i++)
+ // find duplicates in one dir
+ for (int i = 0;i < found[0];i++)
{
- for (j = i+1;j < found[0];j++)
+ for (int j = i+1;j < found[0];j++)
{
- for (mode1 = 0;mode1 < total_modes;mode1++)
+ for (int mode1 = 0;mode1 < total_modes;mode1++)
{
- for (mode2 = 0;mode2 < total_modes;mode2++)
+ for (int mode2 = 0;mode2 < total_modes;mode2++)
{
- if (filecompare(&files[0][i],&files[0][j],mode1,mode2) == 1.0f)
+ if (files[0][i].compare(files[0][j],mode1,mode2) == 1.0f)
printname(&files[0][i],&files[0][j],1.0,mode1,mode2);
}
}
@@ -661,40 +649,38 @@ int CLIB_DECL main(int argc,char *argv[])
}
else
{
- /* compare two dirs */
- for (i = 0;i < found[0];i++)
+ // compare two dirs
+ for (int i = 0;i < found[0];i++)
{
- for (j = 0;j < found[1];j++)
+ for (int j = 0;j < found[1];j++)
{
fprintf(stderr,"%2d%%\r",100*(i*found[1]+j)/(found[0]*found[1]));
- for (mode1 = 0;mode1 < total_modes;mode1++)
+ for (int mode1 = 0;mode1 < total_modes;mode1++)
{
- for (mode2 = 0;mode2 < total_modes;mode2++)
+ for (int mode2 = 0;mode2 < total_modes;mode2++)
{
- matchscore[i][j][mode1][mode2] = filecompare(&files[0][i],&files[1][j],mode1,mode2);
+ matchscore[i][j][mode1][mode2] = files[0][i].compare(files[1][j],mode1,mode2);
}
}
}
}
fprintf(stderr," \r");
+ int besti;
do
{
- float bestscore;
- int bestmode1,bestmode2;
-
besti = -1;
- bestj = -1;
- bestscore = 0.0;
- bestmode1 = bestmode2 = -1;
+ int bestj = -1;
+ float bestscore = 0.0;
+ int bestmode1 = -1, bestmode2 = -1;
- for (mode1 = 0;mode1 < total_modes;mode1++)
+ for (int mode1 = 0;mode1 < total_modes;mode1++)
{
- for (mode2 = 0;mode2 < total_modes;mode2++)
+ for (int mode2 = 0;mode2 < total_modes;mode2++)
{
- for (i = 0;i < found[0];i++)
+ for (int i = 0;i < found[0];i++)
{
- for (j = 0;j < found[1];j++)
+ for (int j = 0;j < found[1];j++)
{
if (matchscore[i][j][mode1][mode2] > bestscore
|| (matchscore[i][j][mode1][mode2] == 1.0f && mode2 == 0 && bestmode2 > 0))
@@ -721,17 +707,17 @@ int CLIB_DECL main(int argc,char *argv[])
matchscore[besti][bestj][bestmode1][bestmode2] = 0.0;
/* remove all matches using the same sections with a worse score */
- for (j = 0;j < found[1];j++)
+ for (int j = 0;j < found[1];j++)
{
- for (mode2 = 0;mode2 < total_modes;mode2++)
+ for (int mode2 = 0;mode2 < total_modes;mode2++)
{
if (matchscore[besti][j][bestmode1][mode2] < bestscore)
matchscore[besti][j][bestmode1][mode2] = 0.0;
}
}
- for (i = 0;i < found[0];i++)
+ for (int i = 0;i < found[0];i++)
{
- for (mode1 = 0;mode1 < total_modes;mode1++)
+ for (int mode1 = 0;mode1 < total_modes;mode1++)
{
if (matchscore[i][bestj][mode1][bestmode2] < bestscore)
matchscore[i][bestj][mode1][bestmode2] = 0.0;
@@ -740,49 +726,50 @@ int CLIB_DECL main(int argc,char *argv[])
/* remove all matches using incompatible sections */
compatiblemodes(bestmode1,&start,&end);
- for (j = 0;j < found[1];j++)
+ for (int j = 0;j < found[1];j++)
{
- for (mode2 = 0;mode2 < total_modes;mode2++)
+ for (int mode2 = 0;mode2 < total_modes;mode2++)
{
- for (mode1 = 0;mode1 < start;mode1++)
+ for (int mode1 = 0;mode1 < start;mode1++)
matchscore[besti][j][mode1][mode2] = 0.0;
- for (mode1 = end+1;mode1 < total_modes;mode1++)
+ for (int mode1 = end+1;mode1 < total_modes;mode1++)
matchscore[besti][j][mode1][mode2] = 0.0;
}
}
compatiblemodes(bestmode2,&start,&end);
- for (i = 0;i < found[0];i++)
+ for (int i = 0;i < found[0];i++)
{
- for (mode1 = 0;mode1 < total_modes;mode1++)
+ for (int mode1 = 0;mode1 < total_modes;mode1++)
{
- for (mode2 = 0;mode2 < start;mode2++)
+ for (int mode2 = 0;mode2 < start;mode2++)
matchscore[i][bestj][mode1][mode2] = 0.0;
- for (mode2 = end+1;mode2 < total_modes;mode2++)
+ for (int mode2 = end+1;mode2 < total_modes;mode2++)
matchscore[i][bestj][mode1][mode2] = 0.0;
}
}
}
- } while (besti != -1);
+ }
+ while (besti != -1);
- for (i = 0;i < found[0];i++)
+ for (int i = 0;i < found[0];i++)
{
if (files[0][i].listed == 0) printname(&files[0][i],nullptr,0.0,0,0);
}
- for (i = 0;i < found[1];i++)
+ for (int i = 0;i < found[1];i++)
{
if (files[1][i].listed == 0) printname(nullptr,&files[1][i],0.0,0,0);
}
}
- for (i = 0;i < found[0];i++)
+ for (int i = 0;i < found[0];i++)
{
- freefile(&files[0][i]);
+ files[0][i].free();
}
- for (i = 0;i < found[1];i++)
+ for (int i = 0;i < found[1];i++)
{
- freefile(&files[1][i]);
+ files[1][i].free();
}
}