home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-05-07 | 42.3 KB | 1,399 lines | [TEXT/MPS ] |
- //*********************************************************************************************
- //
- // File: RCompare.cp
- // Project: MPW Tool
- // Description: Compares resources between two files
- // History: v. 1.0.0 - Rajko Furlan
- //
- // Copyright © 1994 by Creative Synergies
- // All Rights Reserved.
- //
- //*********************************************************************************************
-
- #include <CType.h>
- #include <Dialogs.h>
- #include <Errors.h>
- #include <Files.h>
- #include <Memory.h>
- #include <Menus.h>
- #include <Resources.h>
- #include <Stdio.h>
- #include <String.h>
- #include <Strings.h>
-
- //=============================================================================================
- // CONSTANTS
-
- char* Usage1 = "\
- ### Usage: %s -options file1 file2\n\
- \n\
- By default compares resource types and IDs, but not contents.\n\
- It also compares number of items in 'CMNU', 'MENU', 'STR#', & 'DITL' resources.\n\
- \n\
- Following options are available:\n\
- -a compares contents of all resources\n\
- -d compares 'DITL' bounding rects & items\n";
-
- char* Usage2 = "\
- -dd compares 'DITL' data only (i.e. without strings)\n\
- -m compares 'MENU' & 'CMNU' header, title, items & attrs\n\
- -md compares 'MENU' & 'CMNU' data only (i.e. without strings)\n\
- -s compares 'STR ' & 'STR#' strings\n\
- -v compares 'View' contents\n\
- -o compares contents of all other resources except those above\n\
- -nt no extra types are reported\n\
- -ni no extra IDs are reported\n\
- -nc don't compare 'CODE' resources (used with -a or -o)\n";
-
- char* OpenError = "### %s - Unable to open file %s.\n";
- char* FilesMatch = "*** Files match ***\n";
- char* FilePathStr = "File #%d: %s\n";
- char* File1Str = "1st";
- char* File2Str = "2nd";
- char* ExtraTypes = "Extra types in %s:\n";
- char* ExtraResIDs = "Extra resources in %s:\n";
- char* ExtraStrings = "Extra strings in 'STR#' resources in %s:\n";
- char* ExtraDItems = "Extra items in 'DITL' resources in %s:\n";
- char* ExtraCMItems = "Extra items in 'CMNU' resources in %s:\n";
- char* ExtraMItems = "Extra items in 'MENU' resources in %s:\n";
- char* BadResources = "Nonmatching resources:\n";
- char* BadDItems = "Nonmatching items in 'DITL' resources:\n";
- char* BadCMItems = "Nonmatching items in 'CMNU' resources:\n";
- char* BadMItems = "Nonmatching items in 'MENU' resources:\n";
- char* BadLStrings = "Nonmatching strings in 'STR#' resources:\n";
- char* BadStrings = "Nonmatching strings in 'STR ' resources:\n";
- char* BadViews = "Nonmatching views:\n";
-
- char* TypeStr = " '%s'\n";
- char* TypeIDStr = " '%s' (%d)\n";
- char* TypeIDExtraSStr= " '%s' (%d) - %d extra string(s)\n";
- char* TypeIDExtraIStr= " '%s' (%d) - %d extra items(s)\n";
- char* TypeIDMenuStr = " '%s' (%d, title)\n";
- char* ItemStr = " item %d\n";
- char* HeaderStr = " header\n";
- char* TitleStr = " title\n";
- char* DItemsMismatch = " items are of different kinds - following items ignored!\n";
- char* DRectStateStr = " \"%s\" - (rect = %4d,%4d,%4d,%4d; %8s)\n";
- char* DRectStateIDStr= " \"%s\" - (rect = %4d,%4d,%4d,%4d; %8s; resID = %5d)\n";
- char* StringStr = " \"%s\"\n";
- char* MenuHeaderStr = " menuID = %5d, menuProc = %5d, enableFlags = %#8x;\n";
- char* MenuCmdStr = " \"%s\" - (cmd = %5d)\n";
- char* MenuAttrsStr = " \"%s\" - (icon = %3d, key = %3d, mark = %3d, style = %3d)\n";
- char* MenuCmdAttrsStr= " \"%s\" - (cmd = %5d, icon = %3d, key = %3d, mark = %3d, style = %3d)\n";
- char* EnabledStr = "enabled";
- char* DisabledStr = "disabled";
-
- enum {
- kCompareResIDs1,
- kCompareResIDs2,
- kCompareDITLs,
- kCompareMenus,
- kCompareStrings,
- kCompareViews,
- kCompareOther
- };
-
- //=============================================================================================
- // TYPES
-
- typedef short ResID;
- typedef void (*DoCompare) (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile);
-
- //=============================================================================================
- // EXTERNALS
-
- extern pascal void RotateCursor (long);
-
- //=============================================================================================
- // DECLARATIONS
-
- static void DoTheJob (short ref1Num, short ref2Num, Boolean compareDITLs, Boolean compareMenus,
- Boolean compareStrings, Boolean compareViews, Boolean compareOther,
- Boolean extraTypes, Boolean extraIDs);
- static void CompareTypes (ResType** types1TableH, ResType** types2TableH,
- short types1Count, short types2Count, short firstFile);
- static void CompareResIDs (ResType resType, ResID** res1TableH, ResID** res2TableH,
- short res1Count, short res2Count, short firstFile,
- Boolean& headerWritten);
- static void CompareDITLs (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile);
- static void CompareDITLItems (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile);
- static void WriteDITLTypeIDItemStr (char* resTypeStr, ResID resID, short item,
- Boolean& headerWritten, Boolean& idWritten);
- static void CompareMenus (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile);
- static void CompareMenuItems (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile);
- static void CompareStringLists (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile);
- static void CompareStrings (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile);
- static void CompareViews (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile);
- static void CompareGeneric (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile);
- static void IterateResIDs (short ref1Num, short ref2Num, ResType resType,
- ResID** res1TableH, ResID** res2TableH,
- short res1Count, short res2Count, short firstFile,
- DoCompare doCompare, Boolean& headerWritten);
- static ResType** BuildTypesTable (short refNum);
- static ResID** BuildResIDsTable (short refNum, ResType resType);
- static void BuildResIDsTables (short ref1Num, short ref2Num, ResType resType,
- ResID**& res1TableH, ResID**& res2TableH,
- short& res1Count, short& res2Count);
- static Handle GetTheResource (short refNum, ResType resType, ResID resID);
- static short SetResourceFile (short refNum);
- static void ResType2str (char* resTypeStr, ResType resType);
- static short RCCountMenuItems (Handle menuH, ResType resType);
-
- //=============================================================================================
- // GLOBALS
-
- Boolean gFilesMatch = TRUE;
- Boolean gMenuStrings = TRUE;
- Boolean gDITLStrings = TRUE;
- Boolean gCompareCODE = TRUE;
- long gCursorCounter = 0;
-
- //=============================================================================================
- // CODE
-
- //---------------------------------------------------------------------------------------------
- // main:
- //---------------------------------------------------------------------------------------------
-
- main (int argc, char* argv []) {
- long status = 0;
-
- if (argc >= 3) {
- Str255 file1Name = "";
- Str255 file2Name = "";
- Boolean compareDITLs = FALSE;
- Boolean compareMenus = FALSE;
- Boolean compareStrings = FALSE;
- Boolean compareViews = FALSE;
- Boolean compareOther = FALSE;
- Boolean extraTypes = TRUE;
- Boolean extraIDs = TRUE;
- Boolean file1NameOK = FALSE;
- short ref1Num;
- short ref2Num;
- Ptr argFile1NamePtr;
- Ptr argFile2NamePtr;
-
- RotateCursor (0);
-
- for (short i = 1; i < argc; i ++) {
- short argLen = strlen (argv [i]);
- Ptr argPtr = argv [i];
-
- if (*argPtr == '-') {
- char ch = tolower (*(argPtr + 1));
- char ch2 = tolower (*(argPtr + 2));
-
- if (ch == 'a') {
- compareDITLs = TRUE;
- compareMenus = TRUE;
- compareStrings = TRUE;
- compareViews = TRUE;
- compareOther = TRUE;
- }
- else if (ch == 'd') {
- compareDITLs = TRUE;
-
- if (ch2 == 'd')
- gDITLStrings = FALSE;
- }
- else if (ch == 'm') {
- compareMenus = TRUE;
-
- if (ch2 == 'd')
- gMenuStrings = FALSE;
- }
- else if (ch == 'o')
- compareOther = TRUE;
- else if (ch == 's')
- compareStrings = TRUE;
- else if (ch == 'v')
- compareViews = TRUE;
- else if (ch == 'n') {
- if (ch2 == 't')
- extraTypes = FALSE;
- else if (ch2 == 'i')
- extraIDs = FALSE;
- else if (ch2 == 'c')
- gCompareCODE = FALSE;
- else
- goto ShowUsage;
- }
- else
- goto ShowUsage;
- }
- else {
- if (! file1NameOK) {
- argFile1NamePtr = argPtr;
- memcpy (file1Name, argPtr, argLen + 1);
- c2pstr ((char*) &file1Name [0]);
- file1NameOK = TRUE;
- }
- else {
- argFile2NamePtr = argPtr;
- memcpy (file2Name, argPtr, argLen + 1);
- c2pstr ((char*) &file2Name [0]);
- }
- }
- }
-
- if ((file1Name [0] == 0) || (file2Name [0] == 0))
- goto ShowUsage;
-
- short curRefNum = CurResFile ();
-
- FSSpec fileFSSpec;
- if ((FSMakeFSSpec (0, 0, file1Name, &fileFSSpec) != noErr)
- || ((ref1Num = FSpOpenResFile (&fileFSSpec, fsRdPerm)) == -1)) {
- UseResFile (curRefNum);
-
- fprintf (stderr, OpenError, argv [0], argFile1NamePtr);
- status = 2;
- }
- else if ((FSMakeFSSpec (0, 0, file2Name, &fileFSSpec) != noErr)
- || ((ref2Num = FSpOpenResFile (&fileFSSpec, fsRdPerm)) == -1)) {
- CloseResFile (ref1Num);
- UseResFile (curRefNum);
-
- fprintf (stderr, OpenError, argv [0], argFile2NamePtr);
- status = 2;
- }
- else {
- UseResFile (curRefNum);
-
- p2cstr (file1Name);
- p2cstr (file2Name);
- fprintf (stderr, FilePathStr, 1, file1Name);
- fprintf (stderr, FilePathStr, 2, file2Name);
- fprintf (stderr, "\n");
-
- DoTheJob (ref1Num, ref2Num, compareDITLs, compareMenus, compareStrings,
- compareViews, compareOther, extraTypes, extraIDs);
- CloseResFile (ref1Num);
- CloseResFile (ref2Num);
-
- if (gFilesMatch)
- fprintf (stderr, FilesMatch);
- }
- }
- else {
-
- ShowUsage:
-
- fprintf (stderr, Usage1, argv [0]);
- fprintf (stderr, Usage2);
- status = 1;
- }
-
- return (status);
-
- } // main
-
- //---------------------------------------------------------------------------------------------
- // DoTheJob:
- //---------------------------------------------------------------------------------------------
-
- static void DoTheJob (short ref1Num, short ref2Num, Boolean compareDITLs, Boolean compareMenus,
- Boolean compareStrings, Boolean compareViews, Boolean compareOther,
- Boolean extraTypes, Boolean extraIDs) {
-
- ResType** types1TableH = BuildTypesTable (ref1Num);
- ResType** types2TableH = BuildTypesTable (ref2Num);
-
- short types1Count = (short) GetHandleSize ((Handle) types1TableH) / sizeof (ResType);
- short types2Count = (short) GetHandleSize ((Handle) types2TableH) / sizeof (ResType);
-
- if (extraTypes) {
- CompareTypes (types1TableH, types2TableH, types1Count, types2Count, 1);
- CompareTypes (types2TableH, types1TableH, types2Count, types1Count, 2);
- }
-
- for (short whatToDo = kCompareResIDs1; whatToDo <= kCompareOther; whatToDo ++) {
- short index1 = 0;
- short index2 = 0;
-
- Boolean headerWritten = FALSE;
-
- while ((index1 < types1Count) && (index2 < types2Count)) {
- ResType resType = (*types1TableH) [index1];
-
- if (resType < (*types2TableH) [index2]) {
- // Extra type in table1
- index1 ++;
- }
- else if (resType > (*types2TableH) [index2]) {
- // Extra type in table2
- index2 ++;
- }
- else {
- ResID** res1TableH = NULL;
- ResID** res2TableH = NULL;
- short res1Count;
- short res2Count;
-
- switch (whatToDo) {
- case kCompareResIDs1:
-
- if (extraIDs) {
- BuildResIDsTables (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count);
- CompareResIDs (resType, res1TableH, res2TableH, res1Count, res2Count, 1,
- headerWritten);
- }
-
- break;
-
- case kCompareResIDs2:
-
- if (extraIDs) {
- BuildResIDsTables (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count);
- CompareResIDs (resType, res2TableH, res1TableH, res2Count, res1Count, 2,
- headerWritten);
- }
-
- break;
-
- case kCompareDITLs:
-
- if (resType == 'DITL') {
- BuildResIDsTables (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count);
- IterateResIDs (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count, 1, CompareDITLs,
- headerWritten);
- IterateResIDs (ref2Num, ref1Num, resType, res2TableH, res1TableH,
- res2Count, res1Count, 2, CompareDITLs,
- headerWritten);
-
- if (compareDITLs)
- IterateResIDs (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count, 0, CompareDITLItems,
- headerWritten);
-
- if (headerWritten) {
- fprintf (stderr, "\n");
- headerWritten = FALSE;
- }
- }
-
- break;
-
- case kCompareMenus:
-
- if ((resType == 'CMNU') || (resType == 'MENU')) {
- BuildResIDsTables (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count);
- IterateResIDs (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count, 1, CompareMenus,
- headerWritten);
- IterateResIDs (ref2Num, ref1Num, resType, res2TableH, res1TableH,
- res2Count, res1Count, 2, CompareMenus,
- headerWritten);
-
- if (compareMenus)
- IterateResIDs (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count, 0, CompareMenuItems,
- headerWritten);
-
- if (headerWritten) {
- fprintf (stderr, "\n");
- headerWritten = FALSE;
- }
- }
-
- break;
-
- case kCompareStrings:
-
- if ((resType == 'STR#') || (resType == 'STR ')) {
- BuildResIDsTables (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count);
-
- if (resType == 'STR#') {
- IterateResIDs (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count, 1, CompareStringLists,
- headerWritten);
- IterateResIDs (ref2Num, ref1Num, resType, res2TableH, res1TableH,
- res2Count, res1Count, 2, CompareStringLists,
- headerWritten);
- }
-
- if (compareStrings)
- IterateResIDs (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count, 0, CompareStrings,
- headerWritten);
-
- if (headerWritten) {
- fprintf (stderr, "\n");
- headerWritten = FALSE;
- }
- }
-
- break;
-
- case kCompareViews:
-
- if ((resType == 'View') && compareViews) {
- BuildResIDsTables (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count);
- IterateResIDs (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count, 0, CompareViews,
- headerWritten);
- }
-
- break;
-
- case kCompareOther:
-
- if (compareOther) {
- if ((resType != 'CMNU') && (resType != 'MENU')
- && (resType != 'STR#') && (resType != 'STR ')
- && (resType != 'View') && (resType != 'DITL')
- && ((resType != 'CODE') || gCompareCODE)) {
- BuildResIDsTables (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count);
- IterateResIDs (ref1Num, ref2Num, resType, res1TableH, res2TableH,
- res1Count, res2Count, 0, CompareGeneric,
- headerWritten);
- }
- }
-
- break;
- }
-
- if (res1TableH)
- DisposeHandle ((Handle) res1TableH);
- if (res2TableH)
- DisposeHandle ((Handle) res2TableH);
-
- index1 ++;
- index2 ++;
- }
- }
-
- if (headerWritten)
- fprintf (stderr, "\n");
- }
-
- DisposeHandle ((Handle) types1TableH);
- DisposeHandle ((Handle) types2TableH);
-
- } // DoTheJob
-
- //---------------------------------------------------------------------------------------------
- // CompareTypes: Compares resource types in ordered tables.
- //---------------------------------------------------------------------------------------------
-
- static void CompareTypes (ResType** types1TableH, ResType** types2TableH,
- short types1Count, short types2Count, short firstFile) {
-
- Boolean headerWritten = FALSE;
- short index1 = 0;
- short index2 = 0;
-
- while (index1 < types1Count) {
- RotateCursor (++ gCursorCounter);
- ResType resType = (*types1TableH) [index1];
- char resTypeStr [6];
-
- if ((index2 >= types2Count)
- || (resType < (*types2TableH) [index2])) {
- // Extra type in table1
- if (! headerWritten) {
- fprintf (stderr, ExtraTypes, (firstFile == 1) ? File1Str : File2Str);
- headerWritten = TRUE;
- gFilesMatch = FALSE;
- }
-
- ResType2str (resTypeStr, resType);
- fprintf (stderr, TypeStr, resTypeStr);
-
- index1 ++;
- }
- else if (resType > (*types2TableH) [index2]) {
- // Extra type in table2
- index2 ++;
- }
- else {
- index1 ++;
- index2 ++;
- }
- }
-
- if (headerWritten)
- fprintf (stderr, "\n");
-
- } // CompareTypes
-
- //---------------------------------------------------------------------------------------------
- // CompareResIDs: Compares resource IDs in ordered tables.
- //---------------------------------------------------------------------------------------------
-
- static void CompareResIDs (ResType resType, ResID** res1TableH, ResID** res2TableH,
- short res1Count, short res2Count, short firstFile,
- Boolean& headerWritten) {
-
- char resTypeStr [6];
- ResType2str (resTypeStr, resType);
-
- short index1 = 0;
- short index2 = 0;
-
- while (index1 < res1Count) {
- RotateCursor (++ gCursorCounter);
- ResID resID = (*res1TableH) [index1];
-
- if ((index2 >= res2Count)
- || (resID < (*res2TableH) [index2])) {
- // Extra ID in table1
- if (! headerWritten) {
- fprintf (stderr, ExtraResIDs, (firstFile == 1) ? File1Str : File2Str);
- headerWritten = TRUE;
- gFilesMatch = FALSE;
- }
-
- fprintf (stderr, TypeIDStr, resTypeStr, resID);
-
- index1 ++;
- }
- else if (resID > (*res2TableH) [index2]) {
- // Extra ID in table2
- index2 ++;
- }
- else {
- index1 ++;
- index2 ++;
- }
- }
-
- } // CompareResIDs
-
- //---------------------------------------------------------------------------------------------
- // CompareDITLs: Compares number of items in 'DITL' resources with equal IDs.
- //---------------------------------------------------------------------------------------------
-
- static void CompareDITLs (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile) {
-
- Handle res1H = GetTheResource (ref1Num, resType, resID);
- Handle res2H = GetTheResource (ref2Num, resType, resID);
-
- if (res1H && res2H) {
- short item1Count = *(short*) *res1H;
- short item2Count = *(short*) *res2H;
-
- if (item1Count > item2Count) {
- if (! headerWritten) {
- fprintf (stderr, ExtraDItems, (firstFile == 1) ? File1Str : File2Str);
- headerWritten = TRUE;
- gFilesMatch = FALSE;
- }
-
- fprintf (stderr, TypeIDExtraIStr, resTypeStr, resID, item1Count - item2Count);
- }
- }
-
- ReleaseResource (res1H);
- ReleaseResource (res2H);
-
- } // CompareDITLs
-
- //---------------------------------------------------------------------------------------------
- // CompareDITLItems: Compares corresponding 'DITL' items.
- //---------------------------------------------------------------------------------------------
-
- static void CompareDITLItems (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short /*firstFile*/) {
-
- // Template for items with a string
- struct ItemData {
- long filler;
- Rect rect;
- char kind;
- Str255 string;
- };
-
- // Template for items with a resID
- struct Item2Data {
- long filler;
- Rect rect;
- char kind;
- char what;
- short resID;
- };
-
- Handle res1H = GetTheResource (ref1Num, resType, resID);
- Handle res2H = GetTheResource (ref2Num, resType, resID);
-
- if (res1H && res2H) {
- HLock (res1H);
- HLock (res2H);
-
- Ptr pData1 = *res1H;
- Ptr pData2 = *res2H;
-
- short item = 1;
- short item1Count = *(short*) pData1;
- short item2Count = *(short*) pData2;
- pData1 += sizeof (short);
- pData2 += sizeof (short);
-
- Boolean idWritten = FALSE;
-
- while ((item1Count >= 0) && (item2Count >= 0)) {
- RotateCursor (++ gCursorCounter);
- Str255 string;
-
- if ((*(ItemData*) pData1).kind != (*(ItemData*) pData2).kind) {
- if (! headerWritten) {
- fprintf (stderr, BadDItems);
- headerWritten = TRUE;
- gFilesMatch = FALSE;
- }
-
- if (! idWritten) {
- fprintf (stderr, TypeIDStr, resTypeStr, resID);
- idWritten = TRUE;
- }
-
- fprintf (stderr, ItemStr, item);
- fprintf (stderr, DItemsMismatch);
- break;
- }
-
- Rect rect1 = (*(ItemData*) pData1).rect;
- Rect rect2 = (*(ItemData*) pData2).rect;
-
- Boolean rectsDontMatch = ! EqualRect (&rect1, &rect2);
- Boolean item1Enabled = ! ((*(ItemData*) pData1).kind & itemDisable);
- Boolean item2Enabled = ! ((*(ItemData*) pData2).kind & itemDisable);
- Boolean statesDontMatch = (item1Enabled != item2Enabled);
-
- switch ((*(ItemData*) pData1).kind & 0x7F) {
- case ctrlItem + btnCtrl:
- case ctrlItem + chkCtrl:
- case ctrlItem + radCtrl:
- case statText:
- case editText:
-
- Ptr str1 = (char*) (*(ItemData*) pData1).string;
- Ptr str2 = (char*) (*(ItemData*) pData2).string;
-
- Boolean stringsDontMatch = ((*str1 != *str2)
- || (memcmp (str1, str2, (unsigned char) *str1 + 1)));
-
- if ((gDITLStrings && stringsDontMatch)
- || (rectsDontMatch || statesDontMatch)) {
- WriteDITLTypeIDItemStr (resTypeStr, resID, item,
- headerWritten, idWritten);
-
- if (gDITLStrings)
- BlockMove (str1, string, (unsigned char) *str1 + 1);
- else
- string [0] = 0;
- p2cstr (string);
-
- if (rectsDontMatch || statesDontMatch)
- fprintf (stderr, DRectStateStr, string, rect1.top, rect1.left,
- rect1.bottom, rect1.right,
- (item1Enabled) ? EnabledStr : DisabledStr);
- else
- fprintf (stderr, StringStr, string);
-
- if (gDITLStrings)
- BlockMove (str2, string, (unsigned char) *str2 + 1);
- else
- string [0] = 0;
- p2cstr (string);
-
- if (rectsDontMatch || statesDontMatch)
- fprintf (stderr, DRectStateStr, string, rect2.top, rect2.left,
- rect2.bottom, rect2.right,
- (item2Enabled) ? EnabledStr : DisabledStr);
- else
- fprintf (stderr, StringStr, string);
- }
-
- pData1 = str1 + (unsigned char) *str1 + 1;
- pData2 = str2 + (unsigned char) *str2 + 1;
- break;
-
- case ctrlItem + resCtrl:
- case iconItem:
- case picItem:
-
- short resID1 = (*(Item2Data*) pData1).resID;
- short resID2 = (*(Item2Data*) pData2).resID;
- Boolean resIDsDontMatch = (resID1 != resID2);
-
- if (rectsDontMatch || statesDontMatch || resIDsDontMatch) {
- WriteDITLTypeIDItemStr (resTypeStr, resID, item,
- headerWritten, idWritten);
- string [0] = 0;
-
- fprintf (stderr, DRectStateIDStr, string, rect1.top, rect1.left,
- rect1.bottom, rect1.right,
- (item1Enabled) ? EnabledStr : DisabledStr, resID1);
-
- fprintf (stderr, DRectStateIDStr, string, rect2.top, rect2.left,
- rect2.bottom, rect2.right,
- (item2Enabled) ? EnabledStr : DisabledStr, resID2);
- }
-
- pData1 += sizeof (Item2Data);
- pData2 += sizeof (Item2Data);
- break;
-
- case userItem:
-
- if (rectsDontMatch || statesDontMatch) {
- WriteDITLTypeIDItemStr (resTypeStr, resID, item,
- headerWritten, idWritten);
- string [0] = 0;
-
- fprintf (stderr, DRectStateStr, string, rect1.top, rect1.left,
- rect1.bottom, rect1.right,
- (item1Enabled) ? EnabledStr : DisabledStr);
-
- fprintf (stderr, DRectStateStr, string, rect2.top, rect2.left,
- rect2.bottom, rect2.right,
- (item2Enabled) ? EnabledStr : DisabledStr);
- }
-
- pData1 += sizeof (Item2Data) - sizeof (short); // no resID
- pData2 += sizeof (Item2Data) - sizeof (short);
- break;
- case 1:
-
- // Help Mgr type item (no constant yet)
- if (rectsDontMatch || statesDontMatch) {
- WriteDITLTypeIDItemStr (resTypeStr, resID, item,
- headerWritten, idWritten);
- string [0] = 0;
-
- fprintf (stderr, DRectStateStr, string, rect1.top, rect1.left,
- rect1.bottom, rect1.right,
- (item1Enabled) ? EnabledStr : DisabledStr);
-
- fprintf (stderr, DRectStateStr, string, rect2.top, rect2.left,
- rect2.bottom, rect2.right,
- (item2Enabled) ? EnabledStr : DisabledStr);
- }
-
- pData1 += sizeof (Item2Data) + (*(Item2Data*) pData1).what - sizeof (short);
- pData2 += sizeof (Item2Data) + (*(Item2Data*) pData2).what - sizeof (short);
- break;
- }
-
- if ((long) pData1 & 1)
- pData1 ++; // word aligned
-
- if ((long) pData2 & 1)
- pData2 ++; // word aligned
-
- item ++;
- item1Count --;
- item2Count --;
- }
- }
-
- ReleaseResource (res1H);
- ReleaseResource (res2H);
-
- } // CompareDITLItems
-
- //---------------------------------------------------------------------------------------------
- // WriteDITLTypeIDItemStr:
- //---------------------------------------------------------------------------------------------
-
- static void WriteDITLTypeIDItemStr (char* resTypeStr, ResID resID, short item,
- Boolean& headerWritten, Boolean& idWritten) {
-
- if (! headerWritten) {
- fprintf (stderr, BadDItems);
- headerWritten = TRUE;
- gFilesMatch = FALSE;
- }
-
- if (! idWritten) {
- fprintf (stderr, TypeIDStr, resTypeStr, resID);
- idWritten = TRUE;
- }
-
- fprintf (stderr, ItemStr, item);
-
- } // WriteDITLTypeIDItemStr
-
- //---------------------------------------------------------------------------------------------
- // CompareMenus: Compares number of items in 'CMNU' & 'MENU' resources with equal IDs.
- //---------------------------------------------------------------------------------------------
-
- static void CompareMenus (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile) {
-
- Handle res1H = GetTheResource (ref1Num, resType, resID);
- Handle res2H = GetTheResource (ref2Num, resType, resID);
-
- if (res1H && res2H) {
- short item1Count = RCCountMenuItems (res1H, resType);
- short item2Count = RCCountMenuItems (res2H, resType);
-
- if (item1Count > item2Count) {
- if (! headerWritten) {
- fprintf (stderr, (resType == 'MENU') ? ExtraMItems : ExtraCMItems,
- (firstFile == 1) ? File1Str : File2Str);
- headerWritten = TRUE;
- gFilesMatch = FALSE;
- }
-
- fprintf (stderr, TypeIDExtraIStr, resTypeStr, resID, item1Count - item2Count);
- }
- }
-
- ReleaseResource (res1H);
- ReleaseResource (res2H);
-
- } // CompareMenus
-
- //---------------------------------------------------------------------------------------------
- // CompareMenuItems: Compares corresponding menu items.
- //---------------------------------------------------------------------------------------------
-
- static void CompareMenuItems (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short /*firstFile*/) {
-
- Handle res1H = GetTheResource (ref1Num, resType, resID);
- Handle res2H = GetTheResource (ref2Num, resType, resID);
-
- if (res1H && res2H) {
- HLock (res1H);
- HLock (res2H);
-
- short item = 0;
- Boolean idWritten = FALSE;
-
- MenuInfo& menu1Info = *(MenuInfo*) *res1H;
- MenuInfo& menu2Info = *(MenuInfo*) *res2H;
-
- // Menu header is compared first
- if ((menu1Info.menuID != menu2Info.menuID)
- || (*(short*) &menu1Info.menuProc != *(short*) &menu2Info.menuProc)
- || (menu1Info.enableFlags != menu2Info.enableFlags)) {
- if (! headerWritten) {
- fprintf (stderr, (resType == 'MENU') ? BadMItems : BadCMItems);
- headerWritten = TRUE;
- gFilesMatch = FALSE;
- }
-
- fprintf (stderr, TypeIDStr, resTypeStr, resID);
- idWritten = TRUE;
-
- fprintf (stderr, HeaderStr);
- fprintf (stderr, MenuHeaderStr, menu1Info.menuID, *(short*) &menu1Info.menuProc,
- menu1Info.enableFlags);
- fprintf (stderr, MenuHeaderStr, menu2Info.menuID, *(short*) &menu2Info.menuProc,
- menu2Info.enableFlags);
- }
-
- Ptr str1 = (Ptr) menu1Info.menuData;
- Ptr str2 = (Ptr) menu2Info.menuData;
-
- do {
- RotateCursor (++ gCursorCounter);
- char icon1 = 0;
- char icon2 = 0;
- char key1 = 0;
- char key2 = 0;
- char mark1 = 0;
- char mark2 = 0;
- char style1 = 0;
- char style2 = 0;
- long command1Number = 0;
- long command2Number = 0;
-
- if (item != 0) {
- Ptr pData = str1 + (unsigned char) *str1 + 1;
- icon1 = *pData ++;
- key1 = *pData ++;
- mark1 = *pData ++;
- style1 = (*pData ++) & 0x7F;
-
- if ((long) pData & 1)
- pData ++; // word aligned
-
- if (resType == 'CMNU')
- command1Number = *(long*) pData;
-
- pData = str2 + (unsigned char) *str2 + 1;
- icon2 = *pData ++;
- key2 = *pData ++;
- mark2 = *pData ++;
- style2 = (*pData ++) & 0x7F;
-
- if ((long) pData & 1)
- pData ++; // word aligned
-
- if (resType == 'CMNU')
- command2Number = *(long*) pData;
- }
-
- Boolean attrsDontMatch = ((icon1 != icon2) || (key1 != key2)
- || (mark1 != mark2) || (style1 != style2));
- Boolean cmdsDontMatch = (command1Number != command2Number);
- Boolean stringsDontMatch = ((*str1 != *str2)
- || (memcmp (str1, str2, (unsigned char) *str1 + 1)));
-
- if ((gMenuStrings && stringsDontMatch)
- || (cmdsDontMatch || attrsDontMatch)) {
- if (! headerWritten) {
- fprintf (stderr, (resType == 'MENU') ? BadMItems : BadCMItems);
- headerWritten = TRUE;
- gFilesMatch = FALSE;
- }
-
- if (! idWritten) {
- fprintf (stderr, TypeIDStr, resTypeStr, resID);
- idWritten = TRUE;
- }
-
- if (item == 0)
- fprintf (stderr, TitleStr);
- else
- fprintf (stderr, ItemStr, item);
-
- Str255 string;
- if (gMenuStrings)
- BlockMove (str1, string, (unsigned char) *str1 + 1);
- else
- string [0] = 0;
- p2cstr (string);
-
- if (cmdsDontMatch || attrsDontMatch) {
- if (! cmdsDontMatch)
- fprintf (stderr, MenuAttrsStr, string, icon1, key1, mark1, style1);
- else if (! attrsDontMatch)
- fprintf (stderr, MenuCmdStr, string, command1Number);
- else
- fprintf (stderr, MenuCmdAttrsStr, string, command1Number,
- icon1, key1, mark1, style1);
- }
- else
- fprintf (stderr, StringStr, string);
-
- if (gMenuStrings)
- BlockMove (str2, string, (unsigned char) *str2 + 1);
- else
- string [0] = 0;
- p2cstr (string);
-
- if (cmdsDontMatch || attrsDontMatch) {
- if (! cmdsDontMatch)
- fprintf (stderr, MenuAttrsStr, string, icon2, key2, mark2, style2);
- else if (! attrsDontMatch)
- fprintf (stderr, MenuCmdStr, string, command2Number);
- else
- fprintf (stderr, MenuCmdAttrsStr, string, command2Number,
- icon2, key2, mark2, style2);
- }
- else
- fprintf (stderr, StringStr, string);
- }
-
- str1 += (unsigned char) *str1 + 1;
- str2 += (unsigned char) *str2 + 1;
-
- if (item != 0) {
- // Note that there are four bytes of data after the item string for all menus
- str1 += 4;
- str2 += 4;
-
- if (resType == 'CMNU') {
- if ((long) str1 & 1)
- str1 ++; // word aligned
- str1 += 4; // skip command number
-
- if ((long) str2 & 1)
- str2 ++; // word aligned
- str2 += 4; // skip command number
- }
- }
-
- item ++;
-
- } while ((*str1 != 0) && (*str2 != 0));
- }
-
- ReleaseResource (res1H);
- ReleaseResource (res2H);
-
- } // CompareMenuItems
-
- //---------------------------------------------------------------------------------------------
- // CompareStringLists: Compares number of strings in 'STR#' resources with equal IDs.
- //---------------------------------------------------------------------------------------------
-
- static void CompareStringLists (short ref1Num, short ref2Num,
- ResType /*resType*/, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile) {
-
- Handle res1H = GetTheResource (ref1Num, 'STR#', resID);
- Handle res2H = GetTheResource (ref2Num, 'STR#', resID);
-
- if (res1H && res2H) {
- short str1Count = *(short*) *res1H;
- short str2Count = *(short*) *res2H;
-
- if (str1Count > str2Count) {
- if (! headerWritten) {
- fprintf (stderr, ExtraStrings, (firstFile == 1) ? File1Str : File2Str);
- headerWritten = TRUE;
- gFilesMatch = FALSE;
- }
-
- fprintf (stderr, TypeIDExtraSStr, resTypeStr, resID, str1Count - str2Count);
- }
- }
-
- ReleaseResource (res1H);
- ReleaseResource (res2H);
-
- } // CompareStringLists
-
- //---------------------------------------------------------------------------------------------
- // CompareStrings: Compares corresponding 'STR#' & 'STR ' strings.
- //---------------------------------------------------------------------------------------------
-
- static void CompareStrings (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short /*firstFile*/) {
-
- Handle res1H = GetTheResource (ref1Num, resType, resID);
- Handle res2H = GetTheResource (ref2Num, resType, resID);
-
- if (res1H && res2H) {
- HLock (res1H);
- HLock (res2H);
-
- short strCount = 1;
- Ptr str1 = *res1H;
- Ptr str2 = *res2H;
-
- if (resType == 'STR#') {
- short res1StrCount = *(short*) str1;
- short res2StrCount = *(short*) str2;
- strCount = (res1StrCount <= res2StrCount) ? res1StrCount : res2StrCount;
-
- str1 += sizeof (short);
- str2 += sizeof (short);
- }
-
- Boolean idWritten = FALSE;
-
- for (short item = 1; item <= strCount; item ++) {
- RotateCursor (++ gCursorCounter);
-
- if ((*str1 != *str2)
- || (memcmp (str1, str2, (unsigned char) *str1 + 1))) {
- if (! headerWritten) {
- fprintf (stderr, (resType == 'STR#') ? BadLStrings : BadStrings);
- headerWritten = TRUE;
- gFilesMatch = FALSE;
- }
-
- if (resType == 'STR#') {
- if (! idWritten) {
- fprintf (stderr, TypeIDStr, resTypeStr, resID);
- idWritten = TRUE;
- }
-
- fprintf (stderr, ItemStr, item);
- }
- else
- fprintf (stderr, TypeIDStr, resTypeStr, resID);
-
- Str255 string;
- BlockMove (str1, string, (unsigned char) *str1 + 1);
- p2cstr (string);
- fprintf (stderr, StringStr, string);
-
- BlockMove (str2, string, (unsigned char) *str2 + 1);
- p2cstr (string);
- fprintf (stderr, StringStr, string);
- }
-
- str1 += (unsigned char) *str1 + 1;
- str2 += (unsigned char) *str2 + 1;
- }
- }
-
- ReleaseResource (res1H);
- ReleaseResource (res2H);
-
- } // CompareStrings
-
- //---------------------------------------------------------------------------------------------
- // CompareViews: Compares 'View' resources with equal IDs.
- //---------------------------------------------------------------------------------------------
-
- static void CompareViews (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short firstFile) {
-
- // Handled as generic resources for now
- CompareGeneric (ref1Num, ref2Num, resType, resID, resTypeStr,
- headerWritten, firstFile);
-
- } // CompareViews
-
- //---------------------------------------------------------------------------------------------
- // CompareGeneric: Compares generic resources with equal IDs.
- //---------------------------------------------------------------------------------------------
-
- static void CompareGeneric (short ref1Num, short ref2Num,
- ResType resType, ResID resID, char* resTypeStr,
- Boolean& headerWritten, short /*firstFile*/) {
-
- Handle res1H = GetTheResource (ref1Num, resType, resID);
- Handle res2H = GetTheResource (ref2Num, resType, resID);
-
- if (res1H && res2H) {
- long res1HSize = GetHandleSize (res1H);
-
- if ((res1HSize != GetHandleSize (res2H))
- || (memcmp (*res1H, *res2H, (unsigned int) res1HSize))) {
- if (! headerWritten) {
- if (resType == 'View')
- fprintf (stderr, BadViews);
- else
- fprintf (stderr, BadResources);
-
- headerWritten = TRUE;
- gFilesMatch = FALSE;
- }
-
- fprintf (stderr, TypeIDStr, resTypeStr, resID);
- }
- }
-
- ReleaseResource (res1H);
- ReleaseResource (res2H);
-
- } // CompareGeneric
-
- //---------------------------------------------------------------------------------------------
- // IterateResIDs: Iterates thru all resIDs calling <doCompare> function for equal resIDs.
- //---------------------------------------------------------------------------------------------
-
- static void IterateResIDs (short ref1Num, short ref2Num, ResType resType,
- ResID** res1TableH, ResID** res2TableH,
- short res1Count, short res2Count, short firstFile,
- DoCompare doCompare, Boolean& headerWritten) {
-
- char resTypeStr [6];
- ResType2str (resTypeStr, resType);
-
- short index1 = 0;
- short index2 = 0;
-
- while ((index1 < res1Count) && (index2 < res2Count)) {
- RotateCursor (++ gCursorCounter);
- ResID resID = (*res1TableH) [index1];
-
- if (resID < (*res2TableH) [index2]) {
- // Extra ID in table1
- index1 ++;
- }
- else if (resID > (*res2TableH) [index2]) {
- // Extra ID in table2
- index2 ++;
- }
- else {
- doCompare (ref1Num, ref2Num, resType, resID, resTypeStr, headerWritten, firstFile);
- index1 ++;
- index2 ++;
- }
- }
-
- if ((firstFile != 0) && headerWritten) {
- fprintf (stderr, "\n");
- headerWritten = FALSE;
- }
-
- } // IterateResIDs
-
- //---------------------------------------------------------------------------------------------
- // BuildTypesTable: Builds ordered table of resource types.
- //---------------------------------------------------------------------------------------------
-
- static ResType** BuildTypesTable (short refNum) {
-
- short curRefNum = SetResourceFile (refNum);
- short typesCount = Count1Types ();
- ResType** typesTableH = (ResType**) NewHandle (typesCount * sizeof (ResType));
-
- for (short typeIndex = 1; typeIndex <= typesCount; typeIndex ++) {
- ResType resType;
- Get1IndType (&resType, typeIndex);
-
- ResType* pTypes = *typesTableH;
- for (short i = 1; i < typeIndex; i ++) {
- if (resType < *pTypes) {
- BlockMove (pTypes, pTypes + 1, (typeIndex - i) * sizeof (ResType));
- break;
- }
-
- pTypes ++;
- }
-
- *pTypes = resType;
- }
-
- UseResFile (curRefNum);
- return (typesTableH);
-
- } // BuildTypesTable
-
- //---------------------------------------------------------------------------------------------
- // BuildResIDsTable: Builds ordered table of resource IDs.
- //---------------------------------------------------------------------------------------------
-
- static ResID** BuildResIDsTable (short refNum, ResType resType) {
-
- short curRefNum = SetResourceFile (refNum);
- short resCount = Count1Resources (resType);
- ResID** resTableH = (ResID**) NewHandle (resCount * sizeof (ResID));
-
- for (short resIndex = 1; resIndex <= resCount; resIndex ++) {
- ResType dontCare;
- Str255 resName;
- short resID;
-
- Handle resH = Get1IndResource (resType, resIndex);
- GetResInfo (resH, &resID, &dontCare, resName);
-
- ResID* pIDs = *resTableH;
- for (short i = 1; i < resIndex; i ++) {
- if (resID < *pIDs) {
- BlockMove (pIDs, pIDs + 1, (resIndex - i) * sizeof (ResID));
- break;
- }
-
- pIDs ++;
- }
-
- *pIDs = resID;
- }
-
- UseResFile (curRefNum);
- return (resTableH);
-
- } // BuildResIDsTable
-
- //---------------------------------------------------------------------------------------------
- // BuildResIDsTables:
- //---------------------------------------------------------------------------------------------
-
- static void BuildResIDsTables (short ref1Num, short ref2Num, ResType resType,
- ResID**& res1TableH, ResID**& res2TableH,
- short& res1Count, short& res2Count) {
-
- res1TableH = BuildResIDsTable (ref1Num, resType);
- res2TableH = BuildResIDsTable (ref2Num, resType);
-
- res1Count = (short) GetHandleSize ((Handle) res1TableH) / sizeof (short);
- res2Count = (short) GetHandleSize ((Handle) res2TableH) / sizeof (short);
-
- } // BuildResIDsTables
-
- //---------------------------------------------------------------------------------------------
- // GetTheResource: Gets a resource from the appropriate resource file.
- //---------------------------------------------------------------------------------------------
-
- static Handle GetTheResource (short refNum, ResType resType, ResID resID) {
-
- short curRefNum = SetResourceFile (refNum);
- Handle resH = Get1Resource (resType, resID);
-
- UseResFile (curRefNum);
- return (resH);
-
- } // GetTheResource
-
- //---------------------------------------------------------------------------------------------
- // SetResourceFile: Sets the resource file to be used.
- //---------------------------------------------------------------------------------------------
-
- static short SetResourceFile (short refNum) {
-
- short curRefNum = CurResFile ();
- if (curRefNum != refNum)
- UseResFile (refNum);
-
- return (curRefNum);
-
- } // SetResourceFile
-
- //---------------------------------------------------------------------------------------------
- // ResType2str: Returns in resTypeStr a resType in a form of a C string.
- //---------------------------------------------------------------------------------------------
-
- static void ResType2str (char* resTypeStr, ResType resType) {
-
- *(ResType*) resTypeStr = resType;
- resTypeStr [sizeof (resType)] = 0;
-
- } // ResType2str
-
- //---------------------------------------------------------------------------------------------
- // RCCountMenuItems: Returns number of items in specified 'MENU' or 'CMNU'.
- //---------------------------------------------------------------------------------------------
-
- static short RCCountMenuItems (Handle menuH, ResType resType) {
-
- Ptr pData = (Ptr) (*(MenuInfo*) *menuH).menuData;
-
- // Skip the menu title
- pData += (unsigned char) *pData + 1;
-
- short itemCount = 0;
- while (*pData != 0) {
- // Note that there are four bytes of data after the item string for all menus
- pData += (unsigned char) *pData + 1 + 4;
-
- if (resType == 'CMNU') {
- if ((long) pData & 1)
- pData ++; // word aligned
-
- pData += 4; // skip command number
- }
-
- itemCount ++;
- }
-
- return (itemCount);
-
- } // RCCountMenuItems
-