#include "CCPrompt.h"
#include "PropVss.h"
#include "PropGeneral.h"
+#include "PropFilter.h"
#include "RegKey.h"
#include "logfile.h"
#include "PropSyntax.h"
extern CLogFile gLog;
extern bool gWriteLog;
+// add a
+static void add_regexp PARAMS((struct regexp_list **, char const*));
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
m_strVssPath = theApp.GetProfileString(_T("Settings"), _T("VssPath"), _T(""));
m_nTabSize = theApp.GetProfileInt(_T("Settings"), _T("TabSize"), 4);
m_bHiliteSyntax = theApp.GetProfileInt(_T("Settings"), _T("HiliteSyntax"), TRUE)!=0;
+ m_bIgnoreRegExp = theApp.GetProfileInt(_T("Settings"), _T("IgnoreRegExp"), FALSE);
+ m_sPattern = theApp.GetProfileString(_T("Settings"), _T("RegExps"), NULL);
+
if (m_strVssPath.IsEmpty())
{
CRegKeyEx reg;
CMainFrame::~CMainFrame()
{
+ // destroy the reg expression list
+ FreeRegExpList();
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
ignore_case_flag = m_bIgnoreCase;
ignore_blank_lines_flag = m_bIgnoreBlankLines;
ignore_some_changes = m_bIgnoreWhitespace || m_bIgnoreCase || m_bIgnoreBlankLines;
+ // build the initial reg expression list
+ RebuildRegExpList();
heuristic = 1;
output_style = OUTPUT_NORMAL;
CPropVss vss;
CPropGeneral gen;
CPropSyntax syn;
+ CPropFilter filter;
sht.AddPage(&gen);
sht.AddPage(&syn);
+ sht.AddPage(&filter);
sht.AddPage(&vss);
vss.m_nVerSys = m_nVerSys;
gen.m_nTabSize = m_nTabSize;
syn.m_bHiliteSyntax = m_bHiliteSyntax;
+ filter.m_bIgnoreRegExp = m_bIgnoreRegExp;
+ filter.m_sPattern = m_sPattern;
if (sht.DoModal()==IDOK)
{
ignore_some_changes = m_bIgnoreWhitespace || m_bIgnoreCase || m_bIgnoreBlankLines;
length_varies = m_bIgnoreWhitespace;
+ m_bIgnoreRegExp = filter.m_bIgnoreRegExp;
+ m_sPattern = filter.m_sPattern;
+
theApp.WriteProfileInt(_T("Settings"), _T("VersionSystem"), m_nVerSys);
theApp.WriteProfileInt(_T("Settings"), _T("IgnoreSpace"), m_bIgnoreWhitespace);
theApp.WriteProfileInt(_T("Settings"), _T("ScrollToFirst"), m_bScrollToFirst);
theApp.WriteProfileInt(_T("Settings"), _T("TabSize"), m_nTabSize);
theApp.WriteProfileInt(_T("Settings"), _T("IgnoreBlankLines"), m_bIgnoreBlankLines);
theApp.WriteProfileInt(_T("Settings"), _T("IgnoreCase"), m_bIgnoreCase);
+ theApp.WriteProfileInt(_T("Settings"), _T("IgnoreRegExp"), m_bIgnoreRegExp);
+ theApp.WriteProfileString(_T("Settings"), _T("RegExps"), m_sPattern);
m_bHiliteSyntax = syn.m_bHiliteSyntax;
theApp.WriteProfileInt(_T("Settings"), _T("HiliteSyntax"), m_bHiliteSyntax);
+ RebuildRegExpList();
// make an attempt at rescanning any open diff sessions
if (m_pLeft != NULL && m_pRight != NULL)
}
+void CMainFrame::FreeRegExpList()
+{
+ struct regexp_list *r;
+ r = ignore_regexp_list;
+ // iterate through the list, free the reg expression
+ // list item
+ while (ignore_regexp_list)
+ {
+ r = r->next;
+ free((ignore_regexp_list->buf).fastmap);
+ free((ignore_regexp_list->buf).buffer);
+ free(ignore_regexp_list);
+ ignore_regexp_list = r;
+ }
+
+}
+
+
+void CMainFrame::RebuildRegExpList()
+{
+ _TCHAR tmp[MAX_PATH];
+ _TCHAR* token;
+ _TCHAR sep[] = "\r\n";
+
+ // destroy the old list if the it is not NULL
+ FreeRegExpList();
+
+ // build the new list if the user choose to
+ // ignore lines matching the reg expression patterns
+ if (m_bIgnoreRegExp)
+ {
+ // find each regular expression and add to list
+ _tcscpy(tmp, m_sPattern);
+
+ token = _tcstok(tmp, sep);
+ while (token)
+ {
+ add_regexp(&ignore_regexp_list, token);
+ token = _tcstok(NULL, sep);
+ }
+ }
+
+ if (ignore_regexp_list)
+ {
+ ignore_some_changes = 1;
+ }
+
+}
+
+// Add the compiled form of regexp pattern to reglist
+static void
+add_regexp(struct regexp_list **reglist,
+ char const* pattern)
+{
+ struct regexp_list *r;
+ char const *m;
+
+ r = (struct regexp_list *) xmalloc (sizeof (*r));
+ bzero (r, sizeof (*r));
+ r->buf.fastmap = (char*) xmalloc (256);
+ m = re_compile_pattern (pattern, strlen (pattern), &r->buf);
+ if (m != 0)
+ error ("%s: %s", pattern, m);
+
+ /* Add to the start of the list, since it's easier than the end. */
+ r->next = *reglist;
+ *reglist = r;
+}
void CleanupFileBufs();
BOOL m_bIgnoreBlankLines;
BOOL m_bIgnoreCase;
+ BOOL m_bIgnoreRegExp;
+ CString m_sPattern;
void UpdateResources();
void UpdateCurrentFileStatus(UINT nStatus);
BOOL SyncFiles(LPCTSTR pszSrc, LPCTSTR pszDest);
afx_msg void OnClose();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
+
+private:
+ // builds the regular expression list if the
+ // user choose to ignore Ignore changes affecting only lines
+ // that match the specified regexp.
+ void RebuildRegExpList();
+ // destroy the regular expression list and free up the memory
+ void FreeRegExpList();
};
extern CMainFrame *mf;
# End Source File
# Begin Source File
+SOURCE=.\PropFilter.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\PropGeneral.cpp
!IF "$(CFG)" == "Merge - Win32 Release"
# End Source File
# Begin Source File
+SOURCE=.\PropFilter.h
+# End Source File
+# Begin Source File
+
SOURCE=.\PropGeneral.h
# End Source File
# Begin Source File
BS_AUTOCHECKBOX | WS_TABSTOP,7,7,57,10
END
+IDD_PROPPAGE_FILTER DIALOG DISCARDABLE 0, 0, 235, 156
+STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Filter"
+FONT 8, "MS Sans Serif"
+BEGIN
+ CONTROL "Ignore lines matching the follow patterns",
+ IDC_IGNOREREGEXP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,
+ 7,221,15
+ LTEXT "Regular Expressions (one per line):",IDC_STATIC,7,28,
+ 221,8
+ EDITTEXT IDC_EDITPATTERN,7,39,221,96,ES_MULTILINE |
+ ES_AUTOHSCROLL | ES_WANTRETURN
+END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
TOPMARGIN, 7
BOTTOMMARGIN, 149
END
+
+ IDD_PROPPAGE_FILTER, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 228
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 149
+ END
END
#endif // APSTUDIO_INVOKED
--- /dev/null
+// PropFilter.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "merge.h"
+#include "PropFilter.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CPropFilter property page
+
+IMPLEMENT_DYNCREATE(CPropFilter, CPropertyPage)
+
+CPropFilter::CPropFilter() : CPropertyPage(CPropFilter::IDD)
+{
+ //{{AFX_DATA_INIT(CPropFilter)
+ m_bIgnoreRegExp = FALSE;
+ m_sPattern = _T("");
+ //}}AFX_DATA_INIT
+}
+
+CPropFilter::~CPropFilter()
+{
+}
+
+void CPropFilter::DoDataExchange(CDataExchange* pDX)
+{
+ CPropertyPage::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CPropFilter)
+ DDX_Control(pDX, IDC_EDITPATTERN, m_cPattern);
+ DDX_Check(pDX, IDC_IGNOREREGEXP, m_bIgnoreRegExp);
+ DDX_Text(pDX, IDC_EDITPATTERN, m_sPattern);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CPropFilter, CPropertyPage)
+ //{{AFX_MSG_MAP(CPropFilter)
+ ON_BN_CLICKED(IDC_IGNOREREGEXP, OnIgnoreregexp)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CPropFilter message handlers
+
+BOOL CPropFilter::OnInitDialog()
+{
+ CPropertyPage::OnInitDialog();
+
+ // TODO: Add extra initialization here
+ m_cPattern.EnableWindow(m_bIgnoreRegExp);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CPropFilter::OnIgnoreregexp()
+{
+ // TODO: Add your control notification handler code here
+ UpdateData();
+ // enable or disable the edit box according to
+ // the value of the check box
+ m_cPattern.EnableWindow(m_bIgnoreRegExp);
+ if (m_bIgnoreRegExp)
+ m_cPattern.SetFocus();
+}
--- /dev/null
+#if !defined(AFX_PROPFILTER_H__73E79E13_34DD_4C86_A3EC_A1044B721CCA__INCLUDED_)
+#define AFX_PROPFILTER_H__73E79E13_34DD_4C86_A3EC_A1044B721CCA__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// PropFilter.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CPropFilter dialog
+
+class CPropFilter : public CPropertyPage
+{
+ DECLARE_DYNCREATE(CPropFilter)
+
+// Construction
+public:
+ CPropFilter();
+ ~CPropFilter();
+
+// Dialog Data
+ //{{AFX_DATA(CPropFilter)
+ enum { IDD = IDD_PROPPAGE_FILTER };
+ CEdit m_cPattern;
+ BOOL m_bIgnoreRegExp;
+ CString m_sPattern;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generate virtual function overrides
+ //{{AFX_VIRTUAL(CPropFilter)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ // Generated message map functions
+ //{{AFX_MSG(CPropFilter)
+ virtual BOOL OnInitDialog();
+ afx_msg void OnIgnoreregexp();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_PROPFILTER_H__73E79E13_34DD_4C86_A3EC_A1044B721CCA__INCLUDED_)
/* Set `can_be_null' for the last path (also the first path, if the
pattern is empty). */
- bufp->can_be_null |= path_can_be_null;
+ bufp->can_be_null |= path_can_be_null;
+
+ /* free the fail_statck: it is causing memory leaks */
+#ifdef MATCH_MAY_ALLOCATE
+ if (fail_stack.stack)
+ {
+ free (fail_stack.stack);
+ fail_stack.stack = NULL;
+ }
+#endif
+
return 0;
} /* re_compile_fastmap */
\f
unfortunately clutters up the declarations a bit, but I think it's
worth it. */
-#if __STDC__
+#if __STDC__ || defined(__MSDOS__) || defined(__NT__) || defined(WIN32)
#define _RE_ARGS(args) args
}
script=NULL;
}
+ else if (changes == 0 && ignore_regexp_list )
+ {
+ // determined that there were no changes after considering flags
+ for (e = script; e; e = p)
+ {
+ p = e->link;
+ free (e);
+ }
+ script=NULL;
+ }
else if (changes || ! no_diff_means_no_output)
{
// Record info for starting up output,
#define IDS_COPY2DIR_FMT 134
#define IDD_CLEARCASE 134
#define IDS_CONFIRM_COPY2DIR 135
+#define IDD_PROPPAGE_FILTER 135
#define IDS_FONT_CHANGE 136
#define IDS_DIRECTORY_WINDOW_TITLE 137
#define IDS_DIRECTORY_WINDOW_STATUS_FMT 138
#define IDC_COMMENTS 1017
#define IDC_VER_SYS 1018
#define IDC_HILITE_CHECK 1019
+#define IDC_IGNOREREGEXP 1020
+#define IDC_EDITPATTERN 1021
#define IDR_MARGIN_CURSOR 22900
#define IDD_LANGUAGE_SELECT 30000
#define IDD_PROPSYNTAX 30001
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 135
#define _APS_NEXT_COMMAND_VALUE 32806
-#define _APS_NEXT_CONTROL_VALUE 1020
+#define _APS_NEXT_CONTROL_VALUE 1023
#define _APS_NEXT_SYMED_VALUE 106
#endif
#endif