Esempio n. 1
0
/* Add the blame for the diffs between LAST_FILE and CUR_FILE with the rev
   specified in FRB.  LAST_FILE may be NULL in which
   case blame is added for every line of CUR_FILE. */
static svn_error_t *
add_file_blame(const char *last_file,
               const char *cur_file,
               struct blame_chain *chain,
               struct rev *rev,
               const svn_diff_file_options_t *diff_options,
               apr_pool_t *pool)
{
  if (!last_file)
    {
      SVN_ERR_ASSERT(chain->blame == NULL);
      chain->blame = blame_create(chain, rev, 0);
    }
  else
    {
      svn_diff_t *diff;
      struct diff_baton diff_baton;

      diff_baton.chain = chain;
      diff_baton.rev = rev;

      /* We have a previous file.  Get the diff and adjust blame info. */
      SVN_ERR(svn_diff_file_diff_2(&diff, last_file, cur_file,
                                   diff_options, pool));
      SVN_ERR(svn_diff_output(diff, &diff_baton, &output_fns));
    }

  return SVN_NO_ERROR;
}
Esempio n. 2
0
svn_error_t *
svn_diff_file_diff(svn_diff_t **diff,
                   const char *original,
                   const char *modified,
                   apr_pool_t *pool)
{
  return svn_diff_file_diff_2(diff, original, modified,
                              svn_diff_file_options_create(pool), pool);
}
Esempio n. 3
0
File: diff.c Progetto: lysine/wasp
static svn_error_t *
do_diff(svn_stream_t *ostream,
        const char *original,
        const char *modified,
        svn_boolean_t *has_changes,
        svn_diff_file_options_t *options,
        svn_boolean_t show_c_function,
        apr_pool_t *pool)
{
  svn_diff_t *diff;

  SVN_ERR(svn_diff_file_diff_2(&diff, original, modified, options, pool));
  *has_changes = svn_diff_contains_diffs(diff);
  return svn_diff_file_output_unified4(ostream, diff, original, modified,
                                       NULL, NULL, SVN_APR_LOCALE_CHARSET,
                                       NULL, show_c_function,
                                       options->context_size,
                                       NULL, NULL, pool);
}
Esempio n. 4
0
bool CAppUtils::CreateUnifiedDiff(const CString& orig, const CString& modified, const CString& output, bool bShowError)
{
	apr_file_t * outfile = NULL;
	apr_pool_t * pool = svn_pool_create(NULL);

	svn_error_t * err = svn_io_file_open (&outfile, svn_path_internal_style(CUnicodeUtils::GetUTF8(output), pool),
		APR_WRITE | APR_CREATE | APR_BINARY | APR_TRUNCATE,
		APR_OS_DEFAULT, pool);
	if (err == NULL)
	{
		svn_stream_t * stream = svn_stream_from_aprfile2(outfile, false, pool);
		if (stream)
		{
			svn_diff_t * diff = NULL;
			svn_diff_file_options_t * opts = svn_diff_file_options_create(pool);
			opts->ignore_eol_style = false;
			opts->ignore_space = svn_diff_file_ignore_space_none;
			err = svn_diff_file_diff_2(&diff, svn_path_internal_style(CUnicodeUtils::GetUTF8(orig), pool), 
				svn_path_internal_style(CUnicodeUtils::GetUTF8(modified), pool), opts, pool);
			if (err == NULL)
			{
				err = svn_diff_file_output_unified(stream, diff, svn_path_internal_style(CUnicodeUtils::GetUTF8(orig), pool), 
					svn_path_internal_style(CUnicodeUtils::GetUTF8(modified), pool),
					NULL, NULL, pool);
				svn_stream_close(stream);
			}
		}
		apr_file_close(outfile);
	}
	if (err)
	{
		if (bShowError)
			AfxMessageBox(CAppUtils::GetErrorString(err), MB_ICONERROR);
		svn_error_clear(err);
		svn_pool_destroy(pool);
		return false;
	}
	svn_pool_destroy(pool);
	return true;
}
Esempio n. 5
0
bool
CDiffData::DoTwoWayDiff(const CString& sBaseFilename, const CString& sYourFilename, DWORD dwIgnoreWS, bool bIgnoreEOL, apr_pool_t * pool)
{
    svn_diff_file_options_t * options = CreateDiffFileOptions(dwIgnoreWS, bIgnoreEOL, pool);
    // convert CString filenames (UTF-16 or ANSI) to UTF-8
    CStringA sBaseFilenameUtf8 = CUnicodeUtils::GetUTF8(sBaseFilename);
    CStringA sYourFilenameUtf8 = CUnicodeUtils::GetUTF8(sYourFilename);

    svn_diff_t * diffYourBase = NULL;
    svn_error_t * svnerr = svn_diff_file_diff_2(&diffYourBase, sBaseFilenameUtf8, sYourFilenameUtf8, options, pool);

    if (svnerr)
        return HandleSvnError(svnerr);

    tsvn_svn_diff_t_extension * movedBlocks = NULL;
    if(m_bViewMovedBlocks)
        movedBlocks = MovedBlocksDetect(diffYourBase, dwIgnoreWS, pool); // Side effect is that diffs are now splitted

    svn_diff_t * tempdiff = diffYourBase;
    LONG baseline = 0;
    LONG yourline = 0;
    while (tempdiff)
    {
        svn_diff__type_e diffType = tempdiff->type;
        // Side effect described above overcoming - sticking together
        apr_off_t original_length_sticked = tempdiff->original_length;
        apr_off_t modified_length_sticked = tempdiff->modified_length;
        StickAndSkip(tempdiff, original_length_sticked, modified_length_sticked);

        for (int i=0; i<original_length_sticked; i++)
        {
            if (baseline >= m_arBaseFile.GetCount())
            {
                m_sError.LoadString(IDS_ERR_DIFF_NEWLINES);
                return false;
            }
            const CString& sCurrentBaseLine = m_arBaseFile.GetAt(baseline);
            EOL endingBase = m_arBaseFile.GetLineEnding(baseline);
            if (diffType == svn_diff__type_common)
            {
                if (yourline >= m_arYourFile.GetCount())
                {
                    m_sError.LoadString(IDS_ERR_DIFF_NEWLINES);
                    return false;
                }
                const CString& sCurrentYourLine = m_arYourFile.GetAt(yourline);
                EOL endingYours = m_arYourFile.GetLineEnding(yourline);
                if (sCurrentBaseLine != sCurrentYourLine)
                {
                    bool changedWS = false;
                    if (dwIgnoreWS == 2 || dwIgnoreWS == 3)
                        changedWS = CompareWithIgnoreWS(sCurrentBaseLine, sCurrentYourLine, dwIgnoreWS);
                    if (changedWS || dwIgnoreWS == 0)
                    {
                        // one-pane view: two lines, one 'removed' and one 'added'
                        m_YourBaseBoth.AddData(sCurrentBaseLine, DIFFSTATE_REMOVEDWHITESPACE, yourline, endingBase, HIDESTATE_SHOWN, -1);
                        m_YourBaseBoth.AddData(sCurrentYourLine, DIFFSTATE_ADDEDWHITESPACE, yourline, endingYours, HIDESTATE_SHOWN, -1);
                    }
                    else
                    {
                        m_YourBaseBoth.AddData(sCurrentYourLine, DIFFSTATE_NORMAL, yourline, endingBase, HIDESTATE_HIDDEN, -1);
                    }
                }
                else
                {
                    m_YourBaseBoth.AddData(sCurrentYourLine, DIFFSTATE_NORMAL, yourline, endingBase, HIDESTATE_HIDDEN, -1);
                }
                yourline++;     //in both files
            }
            else
            { // small trick - we need here a baseline, but we fix it back to yourline at the end of routine
                m_YourBaseBoth.AddData(sCurrentBaseLine, DIFFSTATE_REMOVED, -1, endingBase, HIDESTATE_SHOWN, -1);
            }
            baseline++;
        }
        if (diffType == svn_diff__type_diff_modified)
        {
            for (int i=0; i<modified_length_sticked; i++)
            {
                if (m_arYourFile.GetCount() > yourline)
                {
                    m_YourBaseBoth.AddData(m_arYourFile.GetAt(yourline), DIFFSTATE_ADDED, yourline, m_arYourFile.GetLineEnding(yourline), HIDESTATE_SHOWN, -1);
                }
                yourline++;
            }
        }
        tempdiff = tempdiff->next;
    }

    HideUnchangedSections(&m_YourBaseBoth, NULL, NULL);

    tempdiff = diffYourBase;
    baseline = 0;
    yourline = 0;
    while (tempdiff)
    {
        if (tempdiff->type == svn_diff__type_common)
        {
            for (int i=0; i<tempdiff->original_length; i++)
            {
                const CString& sCurrentYourLine = m_arYourFile.GetAt(yourline);
                EOL endingYours = m_arYourFile.GetLineEnding(yourline);
                const CString& sCurrentBaseLine = m_arBaseFile.GetAt(baseline);
                EOL endingBase = m_arBaseFile.GetLineEnding(baseline);
                if (sCurrentBaseLine != sCurrentYourLine)
                {
                    bool changedWS = false;
                    if (dwIgnoreWS == 2 || dwIgnoreWS == 3)
                        changedWS = CompareWithIgnoreWS(sCurrentBaseLine, sCurrentYourLine, dwIgnoreWS);
                    if (changedWS || dwIgnoreWS == 0)
                    {
                        m_YourBaseLeft.AddData(sCurrentBaseLine, DIFFSTATE_WHITESPACE, baseline, endingBase, HIDESTATE_SHOWN, -1);
                        m_YourBaseRight.AddData(sCurrentYourLine, DIFFSTATE_WHITESPACE, yourline, endingYours, HIDESTATE_SHOWN, -1);
                    }
                    else
                    {
                        m_YourBaseLeft.AddData(sCurrentBaseLine, DIFFSTATE_NORMAL, baseline, endingBase, HIDESTATE_HIDDEN, -1);
                        m_YourBaseRight.AddData(sCurrentYourLine, DIFFSTATE_NORMAL, yourline, endingYours, HIDESTATE_HIDDEN, -1);
                    }
                }
                else
                {
                    m_YourBaseLeft.AddData(sCurrentBaseLine, DIFFSTATE_NORMAL, baseline, endingBase, HIDESTATE_HIDDEN, -1);
                    m_YourBaseRight.AddData(sCurrentYourLine, DIFFSTATE_NORMAL, yourline, endingYours, HIDESTATE_HIDDEN, -1);
                }
                baseline++;
                yourline++;
            }
        }
        if (tempdiff->type == svn_diff__type_diff_modified)
        {
            // now we trying to stick together parts, that were splitted by MovedBlocks
            apr_off_t original_length_sticked = tempdiff->original_length;
            apr_off_t modified_length_sticked = tempdiff->modified_length;
            StickAndSkip(tempdiff, original_length_sticked, modified_length_sticked);

            apr_off_t original_length = original_length_sticked;
            for (int i=0; i<modified_length_sticked; i++)
            {
                if (m_arYourFile.GetCount() > yourline)
                {
                    EOL endingYours = m_arYourFile.GetLineEnding(yourline);
                    m_YourBaseRight.AddData(m_arYourFile.GetAt(yourline), DIFFSTATE_ADDED, yourline, endingYours, HIDESTATE_SHOWN, -1);
                    if (original_length-- <= 0)
                    {
                        m_YourBaseLeft.AddEmpty();
                    }
                    else
                    {
                        EOL endingBase = m_arBaseFile.GetLineEnding(baseline);
                        m_YourBaseLeft.AddData(m_arBaseFile.GetAt(baseline), DIFFSTATE_REMOVED, baseline, endingBase, HIDESTATE_SHOWN, -1);
                        baseline++;
                    }
                    yourline++;
                }
            }
            apr_off_t modified_length = modified_length_sticked;
            for (int i=0; i<original_length_sticked; i++)
            {
                if ((modified_length-- <= 0)&&(m_arBaseFile.GetCount() > baseline))
                {
                    EOL endingBase = m_arBaseFile.GetLineEnding(baseline);
                    m_YourBaseLeft.AddData(m_arBaseFile.GetAt(baseline), DIFFSTATE_REMOVED, baseline, endingBase, HIDESTATE_SHOWN, -1);
                    m_YourBaseRight.AddEmpty();
                    baseline++;
                }
            }
        }
        tempdiff = tempdiff->next;
    }
    // add last (empty) lines if needed - diff don't report those
    if (m_arBaseFile.GetCount() > baseline)
    {
        if (m_arYourFile.GetCount() > yourline)
        {
            // last line is missing in both files add them to end and mark as no diff
            m_YourBaseLeft.AddData(m_arBaseFile.GetAt(baseline), DIFFSTATE_NORMAL, baseline, m_arBaseFile.GetLineEnding(baseline), HIDESTATE_SHOWN, -1);
            m_YourBaseRight.AddData(m_arYourFile.GetAt(yourline), DIFFSTATE_NORMAL, yourline, m_arYourFile.GetLineEnding(yourline), HIDESTATE_SHOWN, -1);
            yourline++;
            baseline++;
        }
        else
        {
            viewdata oViewData(m_arBaseFile.GetAt(baseline), DIFFSTATE_REMOVED, baseline, m_arBaseFile.GetLineEnding(baseline), HIDESTATE_SHOWN);
            baseline++;

            // find first EMPTY line in last blok
            int nPos = m_YourBaseLeft.GetCount();
            while (--nPos>=0 && m_YourBaseLeft.GetState(nPos)==DIFFSTATE_EMPTY) ;
            if (++nPos<m_YourBaseLeft.GetCount())
            {
                m_YourBaseLeft.SetData(nPos, oViewData);
            }
            else
            {
                m_YourBaseLeft.AddData(oViewData);
                m_YourBaseRight.AddEmpty();
            }
        }
    }
    else if (m_arYourFile.GetCount() > yourline)
    {
        viewdata oViewData(m_arYourFile.GetAt(yourline), DIFFSTATE_ADDED, yourline, m_arYourFile.GetLineEnding(yourline), HIDESTATE_SHOWN);
        yourline++;

        // try to move last line higher
        int nPos = m_YourBaseRight.GetCount();
        while (--nPos>=0 && m_YourBaseRight.GetState(nPos)==DIFFSTATE_EMPTY) ;
        if (++nPos<m_YourBaseRight.GetCount())
        {
            m_YourBaseRight.SetData(nPos, oViewData);
        }
        else
        {
            m_YourBaseLeft.AddEmpty();
            m_YourBaseRight.AddData(oViewData);
        }
    }


    // Fixing results for conforming moved blocks

    while(movedBlocks)
    {
        tempdiff = movedBlocks->base;
        if(movedBlocks->moved_to != -1)
        {
            // set states in a block original:length -> moved_to:length
            TieMovedBlocks((int)tempdiff->original_start, movedBlocks->moved_to, tempdiff->original_length);
        }
        if(movedBlocks->moved_from != -1)
        {
            // set states in a block modified:length -> moved_from:length
            TieMovedBlocks(movedBlocks->moved_from, (int)tempdiff->modified_start, tempdiff->modified_length);
        }
        movedBlocks = movedBlocks->next;
    }

    // replace baseline with the yourline in m_YourBaseBoth
/*    yourline = 0;
    for(int i=0; i<m_YourBaseBoth.GetCount(); i++)
    {
        DiffStates state = m_YourBaseBoth.GetState(i);
        if((state == DIFFSTATE_REMOVED)||(state == DIFFSTATE_MOVED_FROM))
        {
            m_YourBaseBoth.SetLineNumber(i, -1);
        }
        else
        {
            yourline++;
        }
    }//*/

    TRACE(_T("done with 2-way diff\n"));

    HideUnchangedSections(&m_YourBaseLeft, &m_YourBaseRight, NULL);

    return true;
}