/*
 * fhist - file history and comparison tools
 * Copyright (C) 1991-1994, 1998-2002, 2008, 2010, 2012 Peter Miller
 *
 * Derived from a work
 * Copyright (C) 1990 David I. Bell.
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 *
 *
 *
 * Common definitions for talking to the fcomp module.
 * These are the variables which control its actions.
 */

#ifndef COMPARE_H
#define COMPARE_H

#include <common/ac/stddef.h>

#define INFINITY (long)(~(unsigned long)0 >> 1) /* maximum number */

#define VERBOSE_NONE 0          /* least verbosity level */
#define VERBOSE_DEFAULT 1       /* default verbosity level */
#define VERBOSE_FULL 2          /* full verbosity level */


/*
 * Structure which traces an optimal D-path through the edit path
 * for the two files.  The linked list of these structures lists the
 * snakes which define the path, where a snake is a region of multiple
 * line matchings.
 */
typedef struct snake SNAKE;
struct snake
{
    SNAKE   *next;          /* next snake in path */
    long    line1;          /* line number in file1 */
    long    line2;          /* line number in file2 */
    long    count;          /* number of matching lines */
};


/*
 * Data about a line.
 * Each line is placed on an appropriate hash chain.
 * For any two entries, the two l_hash values match if and only if
 * the two lines match, so that the data never needs to be examined
 * once the original comparisons are complete.  In the extremely rare
 * cases where the hash would incorrectly match, it is modified.
 */
typedef struct line LINE;
struct line
{
    LINE    *l_next;        /* next line on same hash chain */
    long    l_hash;         /* hash value for line */
    char    *l_canon;
    char    l_data[4];      /* chars (variable length, MUST BE LAST) */
};
#define LINE_SIZE(chars) (sizeof(LINE) + (chars) - 2)


/*
 * Data about the files being compared.
 */
typedef struct FILEINFO FILEINFO;
struct FILEINFO
{
    LINE    **f_lines;      /* pointer to data lines */
    long    *f_lnums;       /* line number of each saved line */
    long    f_linecount;    /* number of saved lines in file */
    long    f_linestotal;   /* total number of lines in file */
    const char *f_name;        /* file name */
    struct input_ty *f_file; /* file structure for input */
    char    f_tag;          /* tag character for file */
    int     is_binary;
};


/*
 * Global data for file comparisons.
 */
typedef struct FCOMP_DATA FCOMP_DATA;
struct FCOMP_DATA
{
    /*
     * Input arguments
     */
    long    maxjoin;        /* maximum number of lines to join */
    long    maxchanges;     /* maximum changes to allow */
    long    maxlines;       /* maximum number of lines */
    long    context;        /* lines of context in output */
    long    fileAskip;      /* lines to skip for first file */
    long    fileBskip;      /* lines to skip for second file */
    long    fileAmodify;    /* lines to be modified for first file */
    long    fileBmodify;    /* lines to be modified for second file */
    long    verbosity;      /* verbosity level */
    short   numflag;        /* show line numbers */
    short   spaceflag;      /* ignore extra spaces in lines */
    short   blankflag;      /* ignore blank lines in files */
    short   hexify_flag;    /* turn binary files into byte-per-line text */
    short   upcaseflag;     /* ignore case differences in lines */
    short   quickflag;      /* only show quick summary */
    short   whatflag;       /* show both files showing what changed */
    short   editscriptflag; /* output an edit script */
    short   matchflag;      /* output lines which match */
    short   debugflag;      /* tell some debugging info */
    /*
     * Output arguments
     */
    long    inserts;        /* number of lines inserted into first file */
    long    deletes;        /* number of lines deleted from first file */
    long    matches;        /* number of lines unchanged between files */
    SNAKE   *snakelist;     /* snake list describing matching lines */
    FILEINFO fileA;         /* first file being compared */
    FILEINFO fileB;         /* second file being compared */
    int     binary;         /* -binary cmd line option */
    int     cant_do_binary; /* -no-binary cmd line option */
};

extern FCOMP_DATA fc;           /* all data defined in here */

/*
 * for prototypes
 */
struct INFO;

/*
 * Function prototypes
 */
void *allocstr(size_t);
void fcomp(const char *fileA, const char *fileB);
void dumpmatch(const char *outfile);
void dumpnormal(const char *outfile);
void dumpwhat(const char *outfile);
void dumplines(const char *outfile);
void fcompreset(void);
void binary_warning(const char *);
void binary_fatal(const char *);

/*
 * the modifyline calls are used to alter line between reading them
 * and comparing them.
 */
typedef char *(*modifyline_type)(char *, long *, struct INFO *);
void modifyline_register(modifyline_type);

#endif /* COMPARE_H */
/* vim: set ts=8 sw=4 et : */
