scmdiff.cpp revision 739c9e0e5fccb99475b8202ead8fc5665b2fa64c
/* $Id$ */
/** @file
* IPRT Testcase / Tool - Source Code Massager.
*/
/*
* Copyright (C) 2010-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include "scmdiff.h"
/*******************************************************************************
* Global Variables *
*******************************************************************************/
/**
* Prints a range of lines with a prefix.
*
* @param pState The diff state.
* @param chPrefix The prefix.
* @param pStream The stream to get the lines from.
* @param iLine The first line.
* @param cLines The number of lines.
*/
static void scmDiffPrintLines(PSCMDIFFSTATE pState, char chPrefix, PSCMSTREAM pStream, size_t iLine, size_t cLines)
{
while (cLines-- > 0)
{
{
if (!pState->fSpecialChars)
else
{
while (pchTab)
{
switch (cchTab)
{
}
/* next */
}
if (cchLeft)
}
}
if (!pState->fSpecialChars)
else if (enmEol == SCMEOL_CRLF)
else
iLine++;
}
}
/**
* Reports a difference and propels the streams to the lines following the
* resync.
*
*
* @returns New pState->cDiff value (just to return something).
* @param pState The diff state. The cDiffs member will be
* incremented.
* @param cMatches The resync length.
* @param iLeft Where the difference starts on the left side.
* @param cLeft How long it is on this side. ~(size_t)0 is used
* to indicate that it goes all the way to the end.
* @param iRight Where the difference starts on the right side.
* @param cRight How long it is.
*/
{
/*
* Adjust the input.
*/
{
if (c >= iLeft)
else
{
iLeft = c;
cLeft = 0;
}
}
{
if (c >= iRight)
else
{
iRight = c;
cRight = 0;
}
}
/*
* Print header if it's the first difference
*/
/*
* Emit the change description.
*/
? 'a'
: cRight == 0
? 'd'
: 'c';
RTStrmPrintf(pState->pDiff, "%zu,%zu%c%zu,%zu\n", iLeft + 1, iLeft + cLeft, ch, iRight + 1, iRight + cRight);
else if (cLeft > 1)
else if (cRight > 1)
else
/*
* And the lines.
*/
if (cLeft)
if (cRight)
/*
* Reposition the streams (safely ignores return value).
*/
}
/**
* Helper for scmDiffCompare that takes care of trailing spaces and stuff
* like that.
*/
{
if (pState->fIgnoreTrailingWhite)
{
cchLeft--;
cchRight--;
}
if (pState->fIgnoreLeadingWhite)
{
}
return false;
return true;
}
/**
* Compare two lines.
*
* @returns true if the are equal, false if not.
*/
{
{
if ( pState->fIgnoreTrailingWhite
return scmDiffCompareSlow(pState,
return false;
}
return true;
}
/**
* Compares two sets of lines from the two files.
*
* @returns true if they matches, false if they don't.
* @param pState The diff state.
* @param iLeft Where to start in the left stream.
* @param iRight Where to start in the right stream.
* @param cLines How many lines to compare.
*/
{
{
const char *pchRight = ScmStreamGetLineByNo(pState->pRight, iRight + iLine, &cchRight, &enmEolRight);
return false;
}
return true;
}
/**
* Resynchronize the two streams and reports the difference.
*
* Upon return, the streams will be positioned after the block of @a cMatches
* lines where it resynchronized them.
*
* @returns pState->cDiffs (just so we can use it in a return statement).
* @param pState The state.
* @param cMatches The number of lines that needs to match for the
* stream to be considered synchronized again.
*/
{
/*
* Compare each new line from each of the streams will all the preceding
* ones, including iStartLeft/Right.
*/
{
/*
* Get the next line in the left stream and compare it against all the
* preceding lines on the right side.
*/
if (!pchLine)
{
&cchRight, &enmEolRight);
cMatches - 1)
)
}
/*
* Get the next line in the right stream and compare it against all the
* lines on the right side.
*/
if (!pchLine)
{
&cchLeft, &enmEolLeft);
cMatches - 1)
)
}
}
}
/**
* Creates a diff of the changes between the streams @a pLeft and @a pRight.
*
* This currently only implements the simplest diff format, so no contexts.
*
* Also, note that we won't detect differences in the final newline of the
* streams.
*
* @returns The number of differences.
* @param pszFilename The filename.
* @param pLeft The left side stream.
* @param pRight The right side stream.
* @param fIgnoreEol Whether to ignore end of line markers.
* @param fIgnoreLeadingWhite Set if leading white space should be ignored.
* @param fIgnoreTrailingWhite Set if trailing white space should be ignored.
* @param fSpecialChars Whether to print special chars in a human
* readable form or not.
* @param cchTab The tab size.
* @param pDiff Where to write the diff.
*/
size_t ScmDiffStreams(const char *pszFilename, PSCMSTREAM pLeft, PSCMSTREAM pRight, bool fIgnoreEol,
{
#ifdef RT_STRICT
#endif
/*
* Set up the diff state.
*/
/*
* Compare them line by line.
*/
const char *pchLeft;
const char *pchRight;
for (;;)
{
break;
}
/*
* Deal with any remaining differences.
*/
if (pchLeft)
else if (pchRight)
/*
* Report any errors.
*/
}