⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compitem.c

📁 <Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.
💻 C
📖 第 1 页 / 共 2 页
字号:


/****************************** Module Header *******************************
* Module Name: COMPITEM.C
*
* Module which does the comparison between two files. 
*
* Functions:
*
* ci_copytext()
* ci_makecomposite()
* ci_compare()
* ci_onesection()
* compitem_new()
* compitem_delete()
* compitem_discardsections()
* compitem_getcomposite()
* compitem_getleftsections()
* compitem_getrightsections()
* compitem_getleftfile()
* compitem_getrightfile()
* compitem_getstate()
* compitem_gettext_tag()
* compitem_gettext_result()
* compitem_getfilename()
* compitem_frefilename()
*
* Comments:
*
* This module uses the structure compitem which is a data type that knows
* about two files, and can compare them. The result of the comparison
* is a list of sections for each file, and a composite list of sections
* representing the comparison of the two files.
*
* A compitem has a state (one of the integer values defined in state.h)
* representing the result of the comparison. It can also be
* queried for the text result (text equivalent of the state) as well
* as the tag - or title for this compitem (usually a text string containing
* the name(s) of the files being compared).
*
* A compitem will supply a composite section list even if the files are
* the same, or if there is only one file. The composite section list will
* only be built (and the files read in) when the compitem_getcomposite()
* call is made (and not at compitem_new time).
* 
*  
****************************************************************************/

#include <windows.h>
#include <stdlib.h>
#include <string.h>

#include "gutils.h"
#include "state.h"
#include "windiff.h"
#include "wdiffrc.h"
#include "list.h"
#include "line.h"
#include "scandir.h"
#include "file.h"
#include "section.h"
#include "compitem.h"


struct compitem {

        FILEDATA left;          /* handle for left-hand file */
        FILEDATA right;         /* handle for right-hand file */

        LIST secs_composite;    /* list of sections (composite file)*/
        LIST secs_left;         /* list of sections (left file) */
        LIST secs_right;        /* list of sections (right file) */

        int state;              /* compitem state - result of compare */
        BOOL bDiscard;          /* true if not alloc-ed on list */
        LPSTR tag;              /* text for tag (title of compitem) */
        LPSTR result;           /* text equivalent of state */

};


LPSTR ci_copytext(LPSTR in);
void ci_makecomposite(COMPITEM ci);
void ci_compare(COMPITEM ci);


/***************************************************************************
 * Function: compitem_new
 *
 * Purpose:
 *
 * Returns a handle to a new compitem - given the filenames for the
 * left and right files to be compared. Either left or right or neither
 * (but not both) may be null. In this case we set the state accordingly.
 *
 * The parameters are handles to DIRITEM objects: these allow us to get the
 * the name of the file relative to the compare roots (needed for the tag)
 * and the absolute name of the file (needed for opening the file).
 *
 * Comments:
 *
 * If the list parameter is not null, the List_New* functions are used to
 * allocate memory for the compitem. We remember this (in the bDiscard flag)
 * so we do not delete the compitem if it was allocated on the list.
 *
 * If the list parameter is null, the memory
 * for the compitem is allocated from the gmem_* heap initialised by the app.
 *
 ****************************************************************************/
COMPITEM
compitem_new(DIRITEM leftname, DIRITEM rightname, LIST list, BOOL fExact)
{
        COMPITEM ci;
        LPSTR str1, str2;
        char buf[2*MAX_PATH+20];


        /*
         * Allocate the memory for the compitem, either at the end of the
         * list or in the gmem_* heap.
         */
        if (list == NULL) {
                /* no list passed */
                ci = (COMPITEM) gmem_get(hHeap, sizeof(struct compitem));
                memset(ci, 0, sizeof(struct compitem));
                ci->bDiscard = TRUE;
        } else {
                /* add to end of list */
                ci = (COMPITEM) List_NewLast(list, sizeof(struct compitem));
                ci->bDiscard = FALSE;
        }

        ci->secs_composite = NULL;
        ci->secs_left = NULL;
        ci->secs_right = NULL;

        /*
         * Make a filedata for each of the files that are non-null.
         * Filedata objects are responsible for reading the file and
         * accessing the lines in it. Don't read in the files until we need to.
         */
        if (leftname != NULL) {
                ci->left = file_new(leftname, FALSE);
                if (ci->left == NULL) {
                        return(NULL);
                }
        } else {
                ci->left = NULL;
        }
        if ( rightname != NULL) {
                ci->right = file_new(rightname, FALSE);
                if (ci->right == NULL) {
                        return(NULL);
                }
        } else {
                ci->right = NULL;
        }


        /*
         * See if we have one or two files, and set the state accordingly
         */
        if ( ! ci->left && !ci->right) {
                /* two NULL files - this is wrong */
                return(NULL);
        }


        /* Set the tag (title field) for this item. If the
         * two files have names that match, we use just that name -
         * otherwise we use both names separated by a colon 'left : right'.
         *
         * In both cases, use the names relative to compare root (the
         * names will certainly be different if we compare the abs paths)
         */
        str1 = dir_getrelname(leftname);
        str2 = dir_getrelname(rightname);

        /* If only one file - set name to that */
        if (ci->left == NULL) {
                ci->tag = ci_copytext(str2);
        } else if (ci->right == NULL) {
                ci->tag = ci_copytext(str1);
        } else {
                if (lstrcmpi(str1, str2) == 0) {
                        ci->tag = ci_copytext(str2);
                } else {
                        wsprintf(buf, "%s : %s", str1, str2);
                        ci->tag = ci_copytext(buf);
                }
        }

        dir_freerelname(leftname, str1);
        dir_freerelname(leftname, str2);


        if (ci->left == NULL) {
                str1 = dir_getroot_item(rightname);
                wsprintf(buf, LoadRcString(IDS_ONLY_IN), str1);
                dir_freeroot_item(rightname, str1);

                ci->result = ci_copytext(buf);
                ci->state = STATE_FILERIGHTONLY;
        } else if (ci->right == NULL) {
                str1 = dir_getroot_item(leftname);
                wsprintf(buf, LoadRcString(IDS_ONLY_IN), str1);
                dir_freeroot_item(leftname, str1);

                ci->result = ci_copytext(buf);
                ci->state = STATE_FILELEFTONLY;
        } else {
                /* two files - are they the same ? compare
                 * the file sizes
                 */


                if (dir_getfilesize(leftname) != dir_getfilesize(rightname)) 
                {
                    ci->state = STATE_DIFFER;
                    ci->result = ci_copytext(LoadRcString(IDS_DIFFERENT_SIZES));
                } else if (!fExact){
                    ci->result = ci_copytext(LoadRcString(IDS_SAME_SIZE));
                    ci->state = STATE_SAME;
                } else {
                    ci->result =  ci_copytext(LoadRcString(IDS_IDENTICAL));
                    ci->state = STATE_SAME;
                }
        }


#if FALSE
                if (dir_getfilesize(leftname) == dir_getfilesize(rightname)) {
                    if (  !fExact )
                       {
                        ci->result = ci_copytext("same size etc.");
                        ci->state = STATE_SAME;
                    } else {
                        ci->result = ci_copytext("files differ");
                        ci->state = STATE_DIFFER;
                        ci->result = ci_copytext("files differ");
                     }
                } else {
                        ci->result = ci_copytext("files differ");
                        ci->state = STATE_DIFFER;
                }
        }
#endif

        /*
         * Building the section lists and composite lists can wait
         * until needed.
         */
        return(ci);
} /* compitem_new */

/***************************************************************************
 * Function: compitem_delete
 *
 * Purpose:
 *
 * Deletes a compitem and free all associated data.
 *
 * Comments:
 *
 * If the ci->bDiscard flag is set, the compitem was alloc-ed on a list,
 * and should not be discarded (the list itself will be deleted).
 *
 * The DIRDATA we were passed are not deleted. the filedata, lines
 * and sections are.
 ***************************************************************************/
void
compitem_delete(COMPITEM ci)
{
        if (ci == NULL) {
                return;
        }

        compitem_discardsections(ci);

        /* Delete the two filedatas (and associated line lists) */
        file_delete(ci->left);
        file_delete(ci->right);

        /* text we allocated */
        gmem_free(hHeap, ci->tag, lstrlen(ci->tag) + 1);
        gmem_free(hHeap, ci->result, lstrlen(ci->result) + 1);

        /* Free the compitem struct itself if not alloced on a list */
        if (ci->bDiscard) {
                gmem_free(hHeap, (LPSTR) ci, sizeof(struct compitem));
        }
}


/*
/***************************************************************************
 * Function: compitem_discardsections
 *
 * Purpose:
 *
 * To discard sections - throw away cached information relating to the
 * comparison (but not the files if they are read into memory). This
 * is used to force a re-compare if changes in the comparison options
 * are made
 *
 ***************************************************************************/
void
compitem_discardsections(COMPITEM ci)
{
        /* delete the lists of sections we built */
        if (ci == NULL) {
                return;
        }
        if (ci->secs_composite) {
                section_deletelist(ci->secs_composite);
                ci->secs_composite = NULL;
        }
        if (ci->secs_left) {
                section_deletelist(ci->secs_left);
                ci->secs_left = NULL;
        }
        if (ci->secs_right) {
                section_deletelist(ci->secs_right);
                ci->secs_right = NULL;
        }

        /* reset the line lists to throw away cached hash codes and links */
        if (ci->left != NULL) {
                file_reset(ci->left);
        }
        if (ci->right != NULL) {
                file_reset(ci->right);
        }

}

/***************************************************************************
 * Function: compitem_getcomposite
 *
 * Purpose:
 *
 * To get the handle for the composite section list 
 *
 ***************************************************************************/
LIST
compitem_getcomposite(COMPITEM ci)
{
        if (ci == NULL) {
                return NULL;
        }
        /*
         * do the comparison if we haven't already done it
         */
        if (ci->secs_composite == NULL) {
                ci_makecomposite(ci);
        }

        return(ci->secs_composite);
}

/***************************************************************************
 * Function: compitem_getleftsections
 *
 * Purpose:
 *
 * To get the handle for the list of sections in the left file 
 *
 ***************************************************************************/
LIST
compitem_getleftsections(COMPITEM ci)
{
        if (ci == NULL) {
                return NULL;
        }
        /*
         * do the comparison if we haven't already done it
         */
        if (ci->secs_composite == NULL) {
                ci_makecomposite(ci);
        }

        return(ci->secs_left);
}

/***************************************************************************
 * Function: compitem_getrightsections
 *
 * Purpose:
 *
 * To get the handle for the list of sections in the right file 
 *
 ***************************************************************************/
LIST
compitem_getrightsections(COMPITEM ci)
{
        if (ci == NULL) {
                return NULL;
        }
        /*
         * do the comparison if we haven't already done it
         */
        if (ci->secs_composite == NULL) {
                ci_makecomposite(ci);
        }

        return(ci->secs_right);
}

/***************************************************************************
 * Function: compitem_getleftfile
 *
 * Purpose:
 *
 * To get the handle to the left file itself
 *
 ***************************************************************************/
FILEDATA
compitem_getleftfile(COMPITEM ci)
{
        if (ci == NULL) {
                return(NULL);
        }
        return(ci->left);
}

/***************************************************************************
 * Function: compitem_getrightfile
 *
 * Purpose:
 *
 * To get the handle to the right file itself 
 *
 ***************************************************************************/
FILEDATA
compitem_getrightfile(COMPITEM ci)
{
        if (ci == NULL) {
                return(NULL);
        }
        return(ci->right);
}

/***************************************************************************
 * Function: compitem_getstate
 *
 * Purpose:
 *
 * To get the state (compare result) of this compitem 
 *
 ***************************************************************************/
int
compitem_getstate(COMPITEM ci)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -