1 // WinMergeScript.cpp : Implementation of CWinMergeScript
3 #include "IgnoreColumns.h"
4 #include "WinMergeScript.h"
8 /////////////////////////////////////////////////////////////////////////////
12 * @brief Get the name of the current dll
14 LPTSTR GetDllFilename(LPTSTR name, int len)
16 // careful for the last char, the doc does not give this detail
18 GetModuleFileName(_Module.GetModuleInstance(), name, len-1);
19 // find last backslash
20 TCHAR * lastslash = _tcsrchr(name, '/');
25 TCHAR * lastslash2 = _tcsrchr(lastslash, '\\');
30 if (lastslash2 != name)
31 lstrcpy(name, lastslash2);
39 GetDllFilename(name, 256);
40 lstrcpy(szKeyName, _T("Software\\Thingamahoochie\\WinMerge\\Plugins\\"));
41 lstrcat(szKeyName, name);
45 CString RegReadString(const CString& key, const CString& valuename, const CString& defaultValue)
48 if (reg.Open(HKEY_CURRENT_USER, key, KEY_READ) == ERROR_SUCCESS)
50 TCHAR value[512] = {0};
51 DWORD dwSize = sizeof(value) / sizeof(value[0]);
52 reg.QueryStringValue(valuename, value, &dwSize);
58 int CreateArrayFromRangeString(const TCHAR *rangestr, int (* value)[2])
62 lstrcpy(name, rangestr);
67 // first pass : prepare the chunks
69 TCHAR * token = _tcstok(name, _T(",_"));
70 while( token != NULL )
74 token = _tcstok( NULL, _T(",_") );
78 // just return the number of values
83 for (i = 0 ; i < nValue ; i++)
85 value[i][0] = _tcstol(token, &token, 10);
86 while (*token != 0 && !_istdigit(*token))
90 value[i][1] = value[i][0];
94 value[i][1] = _tcstol(token, &token, 10);
96 token = token + _tcslen(token) + 1;
102 CString CreateRangeStringFromArray(int nExcludedRanges, const int aExcludedRanges[][2])
104 CString rangestr = _T("");
105 for (int i = 0; i < nExcludedRanges; ++i)
108 if (aExcludedRanges[i][0] > 0 && aExcludedRanges[i][1] > 0)
110 if (aExcludedRanges[i][0] == aExcludedRanges[i][1])
112 wsprintf(value, _T("%d"), aExcludedRanges[i][0]);
117 wsprintf(value, _T("%d-%d"), aExcludedRanges[i][0], aExcludedRanges[i][1]);
123 if (!rangestr.IsEmpty())
124 rangestr.Delete(rangestr.GetLength() - 1);
129 CString GetColumnRangeString()
132 GetDllFilename(name, 256);
134 TCHAR * token = _tcspbrk(name, _T(",_"));
136 rangestr = RegReadString(KeyName(), _T("ColumnRanges"), _T(""));
138 rangestr = token + 1;
140 int nExcludedRanges = CreateArrayFromRangeString(rangestr, NULL);
141 int (* aExcludedRanges)[2] = new int[nExcludedRanges][2];
142 if (aExcludedRanges == NULL)
145 nExcludedRanges = CreateArrayFromRangeString(rangestr, aExcludedRanges);
147 rangestr = CreateRangeStringFromArray(nExcludedRanges, aExcludedRanges);
149 delete[] aExcludedRanges;
155 STDMETHODIMP CWinMergeScript::get_PluginEvent(BSTR *pVal)
157 *pVal = SysAllocString(L"BUFFER_PREDIFF");
161 STDMETHODIMP CWinMergeScript::get_PluginDescription(BSTR *pVal)
163 *pVal = SysAllocString(L"Ignore some columns - ignored columns list from the plugin name or the plugin argument");
167 STDMETHODIMP CWinMergeScript::get_PluginFileFilters(BSTR *pVal)
169 *pVal = SysAllocString(L"\\.txt$");
173 STDMETHODIMP CWinMergeScript::get_PluginIsAutomatic(VARIANT_BOOL *pVal)
175 *pVal = VARIANT_TRUE;
179 STDMETHODIMP CWinMergeScript::get_PluginArguments(BSTR *pVal)
181 *pVal = m_bstrArguments.Copy();
185 STDMETHODIMP CWinMergeScript::put_PluginArguments(BSTR val)
187 m_bstrArguments = val;
191 STDMETHODIMP CWinMergeScript::get_PluginExtendedProperties(BSTR *pVal)
193 *pVal = SysAllocString(L"MenuCaption=Ignore Columns");
197 STDMETHODIMP CWinMergeScript::PrediffBufferW(BSTR *pText, INT *pSize, VARIANT_BOOL *pbChanged, VARIANT_BOOL *pbHandled)
199 WCHAR * pBeginText = *pText;
201 WCHAR * pEndText = pBeginText + nSize;
204 wchar_t **argv = CommandLineToArgvW(m_bstrArguments.m_str, &argc);
205 CString rangestr = (argc > 0) ? argv[0] : GetColumnRangeString();
209 int nExcludedRanges = CreateArrayFromRangeString(rangestr, NULL);
210 int (* aExcludedRanges)[2] = new int[nExcludedRanges][2];
211 if (aExcludedRanges == NULL)
214 nExcludedRanges = CreateArrayFromRangeString(rangestr, aExcludedRanges);
216 if (nExcludedRanges == 0)
218 *pbChanged = VARIANT_FALSE;
219 *pbHandled = VARIANT_TRUE;
223 // character position begins at 1 for user, but at 0 here
225 for (i = 0 ; i < nExcludedRanges ; i++)
227 aExcludedRanges[i][0] --;
228 aExcludedRanges[i][1] --;
232 WCHAR * pDst = pBeginText;
236 for (zoneBegin = lineBegin = pBeginText; lineBegin < pEndText ; lineBegin = zoneBegin)
238 // next excluded range in the current line
239 int nextExcludedRange;
240 for (nextExcludedRange = 0 ; nextExcludedRange < nExcludedRanges ; nextExcludedRange ++)
242 // look for the end of the included zone
243 WCHAR * zoneEnd = zoneBegin;
244 WCHAR * zoneMaxEnd = lineBegin + aExcludedRanges[nextExcludedRange][0];
245 while (zoneEnd < pEndText && zoneEnd < zoneMaxEnd &&
246 *zoneEnd != L'\n' && *zoneEnd != L'\r')
249 // copy the characters of included columns
250 wcsncpy(pDst, zoneBegin, zoneEnd - zoneBegin);
251 pDst += zoneEnd - zoneBegin;
253 // advance the cursor
256 if (zoneEnd < zoneMaxEnd)
259 // look for the end of the excluded zone
261 zoneMaxEnd = lineBegin + aExcludedRanges[nextExcludedRange][1] + 1;
262 while (zoneEnd < pEndText && zoneEnd < zoneMaxEnd &&
263 *zoneEnd != L'\n' && *zoneEnd != L'\r')
266 // advance the cursor
269 if (zoneEnd < zoneMaxEnd)
273 if (nextExcludedRange == nExcludedRanges)
275 // treat the trailing included zone
277 // look for the end of the included zone
278 WCHAR * zoneEnd = zoneBegin;
279 while (zoneEnd < pEndText &&
280 *zoneEnd != L'\n' && *zoneEnd != L'\r')
283 // copy the characters of included columns
284 wcsncpy(pDst, zoneBegin, zoneEnd - zoneBegin);
285 pDst += zoneEnd - zoneBegin;
287 // advance the cursor
291 // keep possible EOL characters
292 WCHAR * eolEnd = zoneBegin;
293 while (eolEnd < pEndText &&
294 (*eolEnd == L'\n' || *eolEnd == L'\r'))
299 if (eolEnd > zoneBegin)
301 // copy the EOL characters
302 wcsncpy(pDst, zoneBegin, eolEnd - zoneBegin);
303 pDst += eolEnd - zoneBegin;
304 // advance the cursor
311 delete [] aExcludedRanges;
314 *pSize = pDst - pBeginText;
317 *pbChanged = VARIANT_FALSE;
319 *pbChanged = VARIANT_TRUE;
321 *pbHandled = VARIANT_TRUE;
325 INT_PTR CALLBACK DlgProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
329 SetDlgItemText(hWnd, IDC_EDIT1, GetColumnRangeString());
333 if (LOWORD(wParam) == IDOK)
336 if (reg.Create(HKEY_CURRENT_USER, KeyName(), REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE) != ERROR_SUCCESS)
338 TCHAR value[512] = {0};
339 GetDlgItemText(hWnd, IDC_EDIT1, value, sizeof(value)/sizeof(TCHAR));
340 reg.SetStringValue(_T("ColumnRanges"), value);
341 EndDialog(hWnd, IDOK);
343 else if (LOWORD(wParam) == IDCANCEL)
345 EndDialog(hWnd, IDCANCEL);
356 STDMETHODIMP CWinMergeScript::ShowSettingsDialog(VARIANT_BOOL *pbHandled)
358 *pbHandled = (DialogBox(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc) == IDOK);