Revision: 5862
http://winmerge.svn.sourceforge.net/winmerge/?rev=5862&view=rev
Author: jtuc
Date: 2008-08-29 20:38:41 +0000 (Fri, 29 Aug 2008)
Log Message:
-----------
Patch #2081779 - Revised command line processing
Modified Paths:
--------------
trunk/Src/ConflictFileParser.cpp
trunk/Src/ConflictFileParser.h
trunk/Src/MainFrm.cpp
trunk/Src/MainFrm.h
trunk/Src/Merge.cpp
trunk/Src/Merge.h
trunk/Src/Merge.vcproj
trunk/Src/MergeCmdLineInfo.cpp
trunk/Src/MergeCmdLineInfo.h
Modified: trunk/Src/ConflictFileParser.cpp
===================================================================
--- trunk/Src/ConflictFileParser.cpp 2008-08-28 16:25:10 UTC (rev 5861)
+++ trunk/Src/ConflictFileParser.cpp 2008-08-29 20:38:41 UTC (rev 5862)
@@ -48,13 +48,13 @@
* @param [in] conflictFileName Full path to file to check.
* @return true if given file is a conflict file, false otherwise.
*/
-bool IsConflictFile(const String &conflictFileName)
+bool IsConflictFile(LPCTSTR conflictFileName)
{
UniMemFile conflictFile;
BOOL startFound = FALSE;
// open input file
- BOOL success = conflictFile.OpenReadOnly(conflictFileName.c_str());
+ BOOL success = conflictFile.OpenReadOnly(conflictFileName);
// Search for a conflict marker
BOOL linesToRead = TRUE;
@@ -88,8 +88,8 @@
* @param [out] bNestedConflicts returned as true if nested conflicts found.
* @return true if conflict file was successfully parsed, false otherwise.
*/
-bool ParseConflictFile(const String &conflictFileName,
- const String &workingCopyFileName, const String &newRevisionFileName,
+bool ParseConflictFile(LPCTSTR conflictFileName,
+ LPCTSTR workingCopyFileName, LPCTSTR newRevisionFileName,
bool &bNestedConflicts)
{
UniMemFile conflictFile;
@@ -106,11 +106,11 @@
bNestedConflicts = false;
// open input file
- BOOL success = conflictFile.OpenReadOnly(conflictFileName.c_str());
+ BOOL success = conflictFile.OpenReadOnly(conflictFileName);
// Create output files
- BOOL success2 = workingCopy.Open(workingCopyFileName.c_str(), _T("wb"));
- BOOL success3 = newRevision.Open(newRevisionFileName.c_str(), _T("wb"));
+ BOOL success2 = workingCopy.Open(workingCopyFileName, _T("wb"));
+ BOOL success3 = newRevision.Open(newRevisionFileName, _T("wb"));
state = 0;
BOOL linesToRead = TRUE;
Modified: trunk/Src/ConflictFileParser.h
===================================================================
--- trunk/Src/ConflictFileParser.h 2008-08-28 16:25:10 UTC (rev 5861)
+++ trunk/Src/ConflictFileParser.h 2008-08-29 20:38:41 UTC (rev 5862)
@@ -32,10 +32,10 @@
#include "UnicodeString.h"
-bool IsConflictFile(const String &conflictFileName);
+bool IsConflictFile(LPCTSTR conflictFileName);
-bool ParseConflictFile(const String &conflictFileName,
- const String &workingCopyFileName, const String &newRevisionFileName,
+bool ParseConflictFile(LPCTSTR conflictFileName,
+ LPCTSTR workingCopyFileName, LPCTSTR newRevisionFileName,
bool &nestedConflicts);
#endif // _CONFLICT_FILE_PARSER_H_
Modified: trunk/Src/MainFrm.cpp
===================================================================
--- trunk/Src/MainFrm.cpp 2008-08-28 16:25:10 UTC (rev 5861)
+++ trunk/Src/MainFrm.cpp 2008-08-29 20:38:41 UTC (rev 5862)
@@ -203,7 +203,6 @@
ON_COMMAND(ID_VIEW_RESIZE_PANES, OnResizePanes)
ON_COMMAND(ID_FILE_OPENPROJECT, OnFileOpenproject)
ON_MESSAGE(WM_COPYDATA, OnCopyData)
- ON_MESSAGE(WM_USER, OnUser)
ON_COMMAND(ID_WINDOW_CLOSEALL, OnWindowCloseAll)
ON_UPDATE_COMMAND_UI(ID_WINDOW_CLOSEALL, OnUpdateWindowCloseAll)
ON_COMMAND(ID_FILE_SAVEPROJECT, OnSaveProject)
@@ -352,27 +351,31 @@
static StatusDisplay myStatusDisplay;
+#ifdef _UNICODE
+const TCHAR CMainFrame::szClassName[] = _T("WinMergeWindowClassW");
+#else
+const TCHAR CMainFrame::szClassName[] = _T("WinMergeWindowClassA");
+#endif
/**
* @brief Change MainFrame window class name
* see http://support.microsoft.com/kb/403825/ja
*/
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
- LPCTSTR lpzsNewName = _T("WinMergeWindowClass");
WNDCLASS wndcls;
BOOL bRes = CMDIFrameWnd::PreCreateWindow(cs);
HINSTANCE hInst = AfxGetInstanceHandle();
// see if the class already exists
- if (!::GetClassInfo(hInst, lpzsNewName, &wndcls))
+ if (!::GetClassInfo(hInst, szClassName, &wndcls))
{
// get default stuff
::GetClassInfo(hInst, cs.lpszClass, &wndcls);
// register a new class
- wndcls.lpszClassName = lpzsNewName;
+ wndcls.lpszClassName = szClassName;
wndcls.hIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(IDR_MAINFRAME));
::RegisterClass(&wndcls);
}
- cs.lpszClass = lpzsNewName;
+ cs.lpszClass = szClassName;
return bRes;
}
@@ -2812,51 +2815,13 @@
LRESULT CMainFrame::OnCopyData(WPARAM wParam, LPARAM lParam)
{
COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam;
- LPWSTR p = (LPWSTR)(pCopyData->lpData);
- int argc = pCopyData->dwData;
- TCHAR **argv = new (TCHAR *[argc]);
- USES_CONVERSION;
-
- for (int i = 0; i < argc; i++)
- {
- argv[i] = new TCHAR[lstrlenW(p) * (sizeof(WCHAR)/sizeof(TCHAR)) + 1];
- lstrcpy(argv[i], W2T(p));
- while (*p) p++;
- p++;
- }
-
- PostMessage(WM_USER, (WPARAM)argc, (LPARAM)argv);
-
- return TRUE;
-}
-
-LRESULT CMainFrame::OnUser(WPARAM wParam, LPARAM lParam)
-{
- // MFC's ParseCommandLine method is working with __argc and __targv
- // variables. We need to send MergeCmdLineInfo object rather than
- // passing the command line as string. Until we do, we temporary
- // change these variable values and restore then after parsing.
-
- int argc = __argc;
- TCHAR **argv = __targv;
-
- __argc = wParam;
- __targv = reinterpret_cast<TCHAR **>(lParam);
-
- MergeCmdLineInfo cmdInfo(*__targv);
- theApp.ParseCommandLine(cmdInfo);
+ LPCTSTR pchData = (LPCTSTR)pCopyData->lpData;
+ // Bail out if data isn't zero-terminated
+ DWORD cchData = pCopyData->cbData / sizeof(TCHAR);
+ if (cchData == 0 || pchData[cchData - 1] != _T('\0'))
+ return FALSE;
+ MergeCmdLineInfo cmdInfo = pchData;
theApp.ParseArgsAndDoOpen(cmdInfo, this);
-
- // Delete memrory allocated in OnCopyData method.
- for (int i = 0; i < __argc; ++i)
- {
- delete[] __targv[i];
- }
- delete __targv;
-
- __argc = argc;
- __targv = argv;
-
return TRUE;
}
@@ -3505,15 +3470,14 @@
BOOL CMainFrame::DoOpenConflict(LPCTSTR conflictFile, bool checked)
{
BOOL conflictCompared = FALSE;
- String confl = (LPCTSTR)conflictFile;
if (!checked)
{
- bool confFile = IsConflictFile(confl);
+ bool confFile = IsConflictFile(conflictFile);
if (!confFile)
{
CString message;
- LangFormatString1(message, IDS_NOT_CONFLICT_FILE, confl.c_str());
+ LangFormatString1(message, IDS_NOT_CONFLICT_FILE, conflictFile);
AfxMessageBox(message, MB_ICONSTOP);
return FALSE;
}
@@ -3530,7 +3494,7 @@
// Parse conflict file into two files.
bool inners;
- bool success = ParseConflictFile(confl, workFile, revFile, inners);
+ bool success = ParseConflictFile(conflictFile, workFile.c_str(), revFile.c_str(), inners);
if (success)
{
Modified: trunk/Src/MainFrm.h
===================================================================
--- trunk/Src/MainFrm.h 2008-08-28 16:25:10 UTC (rev 5861)
+++ trunk/Src/MainFrm.h 2008-08-29 20:38:41 UTC (rev 5862)
@@ -110,7 +110,7 @@
BOOL m_bShowErrors; /**< Show folder compare error items? */
LOGFONT m_lfDiff; /**< MergeView user-selected font */
LOGFONT m_lfDir; /**< DirView user-selected font */
-
+ static const TCHAR szClassName[];
// Operations
public:
HMENU NewDirViewMenu();
@@ -323,7 +323,6 @@
afx_msg void OnResizePanes();
afx_msg void OnFileOpenproject();
afx_msg LRESULT OnCopyData(WPARAM wParam, LPARAM lParam);
- afx_msg LRESULT OnUser(WPARAM wParam, LPARAM lParam);
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnWindowCloseAll();
afx_msg void OnUpdateWindowCloseAll(CCmdUI* pCmdUI);
Modified: trunk/Src/Merge.cpp
===================================================================
--- trunk/Src/Merge.cpp 2008-08-28 16:25:10 UTC (rev 5861)
+++ trunk/Src/Merge.cpp 2008-08-29 20:38:41 UTC (rev 5862)
@@ -227,14 +227,11 @@
}
// Parse command-line arguments.
- MergeCmdLineInfo cmdInfo(*__targv);
- ParseCommandLine(cmdInfo);
+ MergeCmdLineInfo cmdInfo = GetCommandLine();
// If paths were given to commandline we consider this being an invoke from
// commandline (from other application, shellextension etc).
- BOOL bCommandLineInvoke = FALSE;
- if (cmdInfo.m_nFiles > 0)
- bCommandLineInvoke = TRUE;
+ BOOL bCommandLineInvoke = cmdInfo.m_Files.size() > 0;
// Set default codepage
DirScan_InitializeDefaultCodepage();
@@ -245,48 +242,33 @@
BOOL bSingleInstance = GetOptionsMgr()->GetBool(OPT_SINGLE_INSTANCE) ||
(true == cmdInfo.m_bSingleInstance);
-
+
// Create exclusion mutex name
- TCHAR szDesktopName[_MAX_PATH] = _T("Win9xDesktop");
+ TCHAR szDesktopName[MAX_PATH] = _T("Win9xDesktop");
DWORD dwLengthNeeded;
GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME,
szDesktopName, sizeof(szDesktopName), &dwLengthNeeded);
- String mutexName =
- String(_T("WinMerge{05963771-8B2E-11d8-B3B9-000000000000}-"))
- + szDesktopName;
-
- HANDLE hMutex = CreateMutex(NULL, FALSE, mutexName.c_str());
+ TCHAR szMutexName[MAX_PATH + 40];
+ // Combine window class name and desktop name to form a unique mutex name.
+ // As the window class name is decorated to distinguish between ANSI and
+ // UNICODE build, so will be the mutex name.
+ wsprintf(szMutexName, _T("%s-%s"), CMainFrame::szClassName, szDesktopName);
+ HANDLE hMutex = CreateMutex(NULL, FALSE, szMutexName);
if (hMutex)
WaitForSingleObject(hMutex, INFINITE);
if (bSingleInstance && GetLastError() == ERROR_ALREADY_EXISTS)
{
- USES_CONVERSION;
-
// Activate previous instance and send commandline to it
- HWND hWnd = FindWindow(_T("WinMergeWindowClass"), NULL);
+ HWND hWnd = FindWindow(CMainFrame::szClassName, NULL);
if (hWnd)
{
if (IsIconic(hWnd))
ShowWindow(hWnd, SW_RESTORE);
SetForegroundWindow(GetLastActivePopup(hWnd));
-
- WCHAR *pszArgs = new WCHAR[_tcslen(__targv[0]) + _tcslen(m_lpCmdLine) + 3];
- WCHAR *p = pszArgs;
- for (int i = 0; i < __argc; i++)
+ LPTSTR cmdLine = GetCommandLine();
+ COPYDATASTRUCT data = { 0, (lstrlen(cmdLine) + 1) * sizeof(TCHAR), cmdLine};
+ if (SendMessage(hWnd, WM_COPYDATA, NULL, (LPARAM)&data))
{
- wcscpy(p, T2W(__targv[i]));
- p += lstrlenW(p) + 1;
- }
- *p++ = _T('\0');
- COPYDATASTRUCT data = {0};
- data.cbData = (DWORD)(p - pszArgs) * sizeof(WCHAR);
- data.lpData = pszArgs;
- data.dwData = __argc;
- SetLastError(ERROR_SUCCESS);
- SendMessage(hWnd, WM_COPYDATA, NULL, (LPARAM)&data);
- delete[] pszArgs;
- if (GetLastError() == ERROR_SUCCESS)
- {
ReleaseMutex(hMutex);
CloseHandle(hMutex);
return FALSE;
@@ -309,7 +291,7 @@
m_pOptions->SaveOption(OPT_FILEFILTER_CURRENT, filter);
}
- CSplashWnd::EnableSplashScreen(bDisableSplash==FALSE && cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew);
+ CSplashWnd::EnableSplashScreen(!bDisableSplash && !bCommandLineInvoke);
// Initialize i18n (multiple language) support
@@ -570,21 +552,10 @@
BOOL bCompared = FALSE;
m_bNonInteractive = cmdInfo.m_bNonInteractive;
- SetOptionsFromCmdLine(cmdInfo);
-
- // Do not load or remember options (preferences).
- if (cmdInfo.m_bNoPrefs)
- {
- // Turn off serializing to registry.
- GetOptionsMgr()->SetSerializing(false);
- // Load all default settings.
- ResetOptions();
- }
-
// Set the global file filter.
- if (!cmdInfo.m_sFileFilter.IsEmpty())
+ if (!cmdInfo.m_sFileFilter.empty())
{
- m_globalFileFilter.SetFilter(cmdInfo.m_sFileFilter);
+ m_globalFileFilter.SetFilter(cmdInfo.m_sFileFilter.c_str());
}
// Unless the user has requested to see WinMerge's usage open files for
@@ -606,78 +577,52 @@
pMainFrame->m_strDescriptions[0] = cmdInfo.m_sLeftDesc;
pMainFrame->m_strDescriptions[1] = cmdInfo.m_sRightDesc;
- if (cmdInfo.m_nFiles > 2)
+ if (cmdInfo.m_Files.size() > 2)
{
- pMainFrame->m_strSaveAsPath = cmdInfo.m_Files[2];
- bCompared = pMainFrame->DoFileOpen(cmdInfo.m_Files[0],
- cmdInfo.m_Files[1], cmdInfo.m_dwLeftFlags,
+ pMainFrame->m_strSaveAsPath = cmdInfo.m_Files[2].c_str();
+ bCompared = pMainFrame->DoFileOpen(cmdInfo.m_Files[0].c_str(),
+ cmdInfo.m_Files[1].c_str(), cmdInfo.m_dwLeftFlags,
cmdInfo.m_dwRightFlags, cmdInfo.m_bRecurse, NULL,
- cmdInfo.m_sPreDiffer);
+ cmdInfo.m_sPreDiffer.c_str());
}
- else if (cmdInfo.m_nFiles > 1)
+ else if (cmdInfo.m_Files.size() > 1)
{
cmdInfo.m_dwLeftFlags |= FFILEOPEN_CMDLINE;
cmdInfo.m_dwRightFlags |= FFILEOPEN_CMDLINE;
- bCompared = pMainFrame->DoFileOpen(cmdInfo.m_Files[0],
- cmdInfo.m_Files[1], cmdInfo.m_dwLeftFlags,
+ bCompared = pMainFrame->DoFileOpen(cmdInfo.m_Files[0].c_str(),
+ cmdInfo.m_Files[1].c_str(), cmdInfo.m_dwLeftFlags,
cmdInfo.m_dwRightFlags, cmdInfo.m_bRecurse, NULL,
- cmdInfo.m_sPreDiffer);
+ cmdInfo.m_sPreDiffer.c_str());
}
- else if (cmdInfo.m_nFiles == 1)
+ else if (cmdInfo.m_Files.size() == 1)
{
- CString sFilepath = cmdInfo.m_Files[0];
- if (IsProjectFile(sFilepath))
+ String sFilepath = cmdInfo.m_Files[0];
+ if (IsProjectFile(sFilepath.c_str()))
{
- bCompared = LoadAndOpenProjectFile(sFilepath);
+ bCompared = LoadAndOpenProjectFile(sFilepath.c_str());
}
- else if (IsConflictFile((LPCTSTR)sFilepath))
+ else if (IsConflictFile(sFilepath.c_str()))
{
- bCompared = pMainFrame->DoOpenConflict(sFilepath);
+ bCompared = pMainFrame->DoOpenConflict(sFilepath.c_str());
}
else
{
cmdInfo.m_dwRightFlags = FFILEOPEN_NONE;
- bCompared = pMainFrame->DoFileOpen(sFilepath, _T(""),
+ bCompared = pMainFrame->DoFileOpen(sFilepath.c_str(), _T(""),
cmdInfo.m_dwLeftFlags, cmdInfo.m_dwRightFlags,
- cmdInfo.m_bRecurse, NULL, cmdInfo.m_sPreDiffer);
+ cmdInfo.m_bRecurse, NULL, cmdInfo.m_sPreDiffer.c_str());
}
}
}
return bCompared;
}
-/** @brief Handle all command line arguments which are mapped to WinMerge options. */
-void CMergeApp::SetOptionsFromCmdLine(const MergeCmdLineInfo& cmdInfo)
-{
- static const ArgSetting f_ArgSettings[] =
- {
- { _T("ignorews"), OPT_CMP_IGNORE_WHITESPACE },
- { _T("ignoreblanklines"), OPT_CMP_IGNORE_BLANKLINES },
- { _T("ignorecase"), OPT_CMP_IGNORE_CASE },
- { _T("ignoreeol"), OPT_CMP_IGNORE_EOL }
- };
-
- for (int i = 0; i < countof(f_ArgSettings); ++i)
- {
- const ArgSetting& argSetting = f_ArgSettings[i];
- LPCTSTR szCmdArgName = argSetting.CmdArgName;
- LPCTSTR szOptionName = argSetting.WinMergeOptionName;
- CString sValue;
-
- if (cmdInfo.m_Settings.Lookup(szCmdArgName, sValue))
- {
- GetOptionsMgr()->SaveOption(szOptionName, sValue);
- }
- }
-}
-
/** @brief Open help from mainframe when user presses F1*/
void CMergeApp::OnHelp()
{
GetMainFrame()->ShowHelp();
}
-
/**
* @brief Is specified file a project file?
* @param [in] filepath Full path to file to check.
Modified: trunk/Src/Merge.h
===================================================================
--- trunk/Src/Merge.h 2008-08-28 16:25:10 UTC (rev 5861)
+++ trunk/Src/Merge.h 2008-08-29 20:38:41 UTC (rev 5862)
@@ -106,7 +106,6 @@
virtual BOOL PreTranslateMessage(MSG* pMsg);
void InitializeFileFilters();
BOOL ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainFrame);
- void SetOptionsFromCmdLine(const MergeCmdLineInfo& cmdInfo);
// End MergeArgs.cpp
bool LoadAndOpenProjectFile(LPCTSTR sFilepath);
Modified: trunk/Src/Merge.vcproj
===================================================================
--- trunk/Src/Merge.vcproj 2008-08-28 16:25:10 UTC (rev 5861)
+++ trunk/Src/Merge.vcproj 2008-08-29 20:38:41 UTC (rev 5862)
@@ -588,43 +588,6 @@
</FileConfiguration>
</File>
<File
- RelativePath="ClearCaseCmdLineParser.cpp">
- <FileConfiguration
- Name="UnicodeRelease|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="1"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- <FileConfiguration
- Name="UnicodeDebug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- BrowseInformation="1"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- BrowseInformation="1"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="1"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
RelativePath="Common\ClipBoard.cpp">
<FileConfiguration
Name="UnicodeRelease|Win32">
@@ -5949,43 +5912,6 @@
</FileConfiguration>
</File>
<File
- RelativePath="WinMergeCmdLineParser.cpp">
- <FileConfiguration
- Name="UnicodeRelease|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="1"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- <FileConfiguration
- Name="UnicodeDebug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- BrowseInformation="1"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- BrowseInformation="1"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="1"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
RelativePath="WMGotoDlg.cpp">
<FileConfiguration
Name="UnicodeRelease|Win32">
@@ -6051,9 +5977,6 @@
RelativePath="ChildFrm.h">
</File>
<File
- RelativePath="ClearCaseCmdLineParser.h">
- </File>
- <File
RelativePath="Common\ClipBoard.h">
</File>
<File
@@ -6519,9 +6442,6 @@
RelativePath="Common\WinClasses.h">
</File>
<File
- RelativePath="WinMergeCmdLineParser.h">
- </File>
- <File
RelativePath="WMGotoDlg.h">
</File>
</Filter>
Modified: trunk/Src/MergeCmdLineInfo.cpp
===================================================================
--- trunk/Src/MergeCmdLineInfo.cpp 2008-08-28 16:25:10 UTC (rev 5861)
+++ trunk/Src/MergeCmdLineInfo.cpp 2008-08-29 20:38:41 UTC (rev 5862)
@@ -20,9 +20,9 @@
/////////////////////////////////////////////////////////////////////////////
/**
- * @file CmdLineParser.h
+ * @file MergeCmdLineInfo.cpp
*
- * @brief CmdLineParser class implementation.
+ * @brief MergeCmdLineInfo class implementation.
*
*/
@@ -33,33 +33,88 @@
#include <shlwapi.h> // Required for PathFindFileName
+#include "Paths.h"
+#include "Merge.h"
#include "MainFrm.h"
#include "MergeCmdLineInfo.h"
-#include "ClearCaseCmdLineParser.h"
-#include "WinMergeCmdLineParser.h"
+#include "OptionsDef.h"
// MergeCmdLineInfo
/**
+ * @brief Eat and digest a command line parameter.
+ * @param [in] p Points into the command line.
+ * @param [out] param Receives the digested command line parameter.
+ * @param [out] flag Tells whether param is the name of a flag.
+ * @return Points to the remaining portion of the command line.
+ */
+LPCTSTR MergeCmdLineInfo::EatParam(LPCTSTR p, String ¶m, bool *flag)
+{
+ if (p && *(p += StrSpn(p, _T(" \t"))) == '\0')
+ p = 0;
+ LPCTSTR q = PathGetArgs(p);
+ if (q > p && flag)
+ {
+ if (*p == _T('-') || *p == _T('/'))
+ {
+ *flag = true;
+ ++p;
+ if (LPCTSTR colon = StrRChr(p, q, _T(':')))
+ q = colon;
+ }
+ else
+ {
+ *flag = false;
+ flag = 0;
+ }
+ }
+ param.assign(p, q - p);
+ if (q > p && flag)
+ {
+ CharLower(&*param.begin());
+ }
+ // Strip any leading or trailing whitespace or quotes
+ param.erase(0, param.find_first_not_of(_T(" \t\"")));
+ param.erase(param.find_last_not_of(_T(" \t\"")) + 1);
+ return q;
+}
+
+/**
+ * @brief Set WinMerge option from command line.
+ * @param [in] p Points into the command line.
+ * @param [in] key Name of WinMerge option to set.
+ * @param [in] value Default value in case none is specified.
+ * @return Points to the remaining portion of the command line.
+ */
+LPCTSTR MergeCmdLineInfo::SetOption(LPCTSTR q, LPCTSTR key, LPCTSTR value)
+{
+ String s;
+ if (*q == _T(':'))
+ {
+ q = EatParam(q, s);
+ value = s.c_str() + 1;
+ }
+ GetOptionsMgr()->SaveOption(key, value);
+ return q;
+}
+
+/**
* @brief ClearCaseCmdLineParser's constructor.
- * @param [in] szExeName Executable file name. Required in order to
- * know which command line parser to create and use.
+ * @param [in] q Points to the beginning of the command line.
*/
-MergeCmdLineInfo::MergeCmdLineInfo(const TCHAR *szExeName) : CCommandLineInfo(),
+MergeCmdLineInfo::MergeCmdLineInfo(LPCTSTR q):
m_nCmdShow(SW_SHOWNORMAL),
m_bClearCaseTool(false),
m_bEscShutdown(false),
m_bExitIfNoDiff(false),
m_bRecurse(false),
m_bNonInteractive(false),
- m_bNoPrefs(false),
m_bSingleInstance(false),
m_bShowUsage(false),
m_dwLeftFlags(FFILEOPEN_CMDLINE),
- m_dwRightFlags(FFILEOPEN_CMDLINE),
- m_nFiles(0)
+ m_dwRightFlags(FFILEOPEN_CMDLINE)
{
- m_Files.SetSize(2);
+ m_Files.reserve(2);
// Rational ClearCase has a weird way of executing external
// tools which replace the build-in ones. It also doesn't allow
@@ -70,40 +125,212 @@
// parse ClearCase's command line parameters and not the
// "regular" parameters. More information can be found in
// C:\Program Files\Rational\ClearCase\lib\mgrs\mgr_info.h file.
-
- LPTSTR szFileName = ::PathFindFileName(szExeName);
-
- if (lstrcmpi(szFileName, _T("xcompare")) && lstrcmpi(szFileName, _T("xmerge")))
+ String exeName;
+ q = EatParam(q, exeName);
+ LPTSTR szFileName = PathFindFileName(exeName.c_str());
+ if (lstrcmpi(szFileName, _T("xcompare")) == 0)
{
- m_pCmdLineParser = new WinMergeCmdLineParser(*this);
+ m_dwRightFlags |= FFILEOPEN_READONLY;
+ ParseClearCaseCmdLine(q);
}
+ else if (lstrcmpi(szFileName, _T("xmerge")) == 0)
+ {
+ ParseClearCaseCmdLine(q);
+ }
else
{
- m_bClearCaseTool = true;
- m_pCmdLineParser = new ClearCaseCmdLineParser(*this, szFileName);
+ ParseWinMergeCmdLine(q);
}
}
/**
- * @brief Destructor.
+ * @brief Parse a command line passed in from ClearCase.
+ * @param [in] p Points into the command line.
*/
-MergeCmdLineInfo::~MergeCmdLineInfo()
+void MergeCmdLineInfo::ParseClearCaseCmdLine(LPCTSTR q)
{
- delete m_pCmdLineParser;
+ String sBaseFile; /**< Base file path. */
+ String sBaseDesc; /**< Base file description. */
+ String sOutFile; /**< Out file path. */
+ if (m_dwRightFlags & FFILEOPEN_READONLY)
+ {
+ // Compare tool doesn't have a common ancestor file description. We
+ // put a phony description so the command line parser will skip it.
+ sBaseDesc = _T("<No Base>");
+ }
+ m_bClearCaseTool = true;
+ String param;
+ bool flag;
+ while ((q = EatParam(q, param, &flag)) != 0)
+ {
+ if (!flag)
+ {
+ // Not a flag
+ param = paths_GetLongPath(param.c_str());
+ m_Files.push_back(param);
+ }
+ else if (param == _T("base"))
+ {
+ // -base is followed by common ancestor file description.
+ q = EatParam(q, sBaseFile);
+ }
+ else if (param == _T("out"))
+ {
+ // -out is followed by merge's output file name.
+ q = EatParam(q, sOutFile);
+ }
+ else if (param == _T("fname"))
+ {
+ // -fname is followed by file description.
+ if (sBaseDesc.empty())
+ q = EatParam(q, sBaseDesc);
+ else if (m_sLeftDesc.empty())
+ q = EatParam(q, m_sLeftDesc);
+ else if (m_sRightDesc.empty())
+ q = EatParam(q, m_sRightDesc);
+ else
+ q = EatParam(q, param); // ignore excess arguments
+ }
+ }
+ if (!sOutFile.empty())
+ {
+ String path = paths_GetLongPath(sOutFile.c_str());
+ m_Files.push_back(path);
+ }
}
/**
- * @brief Parser function.
- * This functino overrides CCommandLineInfo's parser function and calls
- * WinMerge's parser function.
- * @param [in] pszParam The parameter or flag to parse.
- * @param [in] bFlag Is the item to parse a flag?
- * @param [in] bLast Is the item to parse a last of items?
+ * @brief Parse native WinMerge command line.
+ * @param [in] p Points into the command line.
*/
-void MergeCmdLineInfo::ParseParam(const TCHAR* pszParam, BOOL bFlag, BOOL bLast)
+void MergeCmdLineInfo::ParseWinMergeCmdLine(LPCTSTR q)
{
- // Give our base class a chance to figure out what is the parameter.
- CCommandLineInfo::ParseParam(pszParam, bFlag, bLast);
-
- m_pCmdLineParser->ParseParam(pszParam, bFlag, bLast);
+ String param;
+ bool flag;
+ while ((q = EatParam(q, param, &flag)) != 0)
+ {
+ if (!flag)
+ {
+ // Not a flag
+ // If shortcut, expand it first
+ if (paths_IsShortcut(param.c_str()))
+ param = ExpandShortcut(param.c_str());
+ param = paths_GetLongPath(param.c_str());
+ m_Files.push_back(param);
+ }
+ else if (param == _T("?"))
+ {
+ // -? to show common command line arguments.
+ m_bShowUsage = true;
+ }
+ else if (param == _T("dl"))
+ {
+ // -dl "desc" - description for left file
+ q = EatParam(q, m_sLeftDesc);
+ }
+ else if (param == _T("dr"))
+ {
+ // -dr "desc" - description for right file
+ q = EatParam(q, m_sRightDesc);
+ }
+ else if (param == _T("e"))
+ {
+ // -e to allow closing with single esc press
+ m_bEscShutdown = true;
+ }
+ else if (param == _T("f"))
+ {
+ // -f "mask" - file filter mask ("*.h *.cpp")
+ q = EatParam(q, m_sFileFilter);
+ }
+ else if (param == _T("r"))
+ {
+ // -r to compare recursively
+ m_bRecurse = true;
+ }
+ else if (param == _T("s"))
+ {
+ // -s to allow only one instance
+ m_bSingleInstance = true;
+ }
+ else if (param == _T("noninteractive"))
+ {
+ // -noninteractive to suppress message boxes & close with result code
+ m_bNonInteractive = true;
+ }
+ else if (param == _T("noprefs"))
+ {
+ // -noprefs means do not load or remember options (preferences)
+ // Turn off serializing to registry.
+ GetOptionsMgr()->SetSerializing(false);
+ // Load all default settings.
+ theApp.ResetOptions();
+ }
+ else if (param == _T("minimize"))
+ {
+ // -minimize means minimize the main window.
+ m_nCmdShow = SW_MINIMIZE;
+ }
+ else if (param == _T("maximize"))
+ {
+ // -maximize means maximize the main window.
+ m_nCmdShow = SW_MAXIMIZE;
+ }
+ else if (param == _T("prediffer"))
+ {
+ // Get prediffer if specified (otherwise prediffer will be blank, which is default)
+ q = EatParam(q, m_sPreDiffer);
+ }
+ else if (param == _T("wl"))
+ {
+ // -wl to open left path as read-only
+ m_dwLeftFlags |= FFILEOPEN_READONLY;
+ }
+ else if (param == _T("wr"))
+ {
+ // -wr to open right path as read-only
+ m_dwRightFlags |= FFILEOPEN_READONLY;
+ }
+ else if (param == _T("ul"))
+ {
+ // -ul to not add left path to MRU
+ m_dwLeftFlags |= FFILEOPEN_NOMRU;
+ }
+ else if (param == _T("ur"))
+ {
+ // -ur to not add right path to MRU
+ m_dwRightFlags |= FFILEOPEN_NOMRU;
+ }
+ else if (param == _T("u") || param == _T("ub"))
+ {
+ // -u or -ub (deprecated) to add neither right nor left path to MRU
+ m_dwLeftFlags |= FFILEOPEN_NOMRU;
+ m_dwRightFlags |= FFILEOPEN_NOMRU;
+ }
+ else if (param == _T("x"))
+ {
+ // -x to close application if files are identical.
+ m_bExitIfNoDiff = true;
+ }
+ else if (param == _T("ignorews"))
+ {
+ q = SetOption(q, OPT_CMP_IGNORE_WHITESPACE);
+ }
+ else if (param == _T("ignoreblanklines"))
+ {
+ q = SetOption(q, OPT_CMP_IGNORE_BLANKLINES);
+ }
+ else if (param == _T("ignorecase"))
+ {
+ q = SetOption(q, OPT_CMP_IGNORE_CASE);
+ }
+ else if (param == _T("ignoreeol"))
+ {
+ q = SetOption(q, OPT_CMP_IGNORE_EOL);
+ }
+ }
+ if (m_bShowUsage)
+ {
+ m_bNonInteractive = false;
+ }
}
Modified: trunk/Src/MergeCmdLineInfo.h
===================================================================
--- trunk/Src/MergeCmdLineInfo.h 2008-08-28 16:25:10 UTC (rev 5861)
+++ trunk/Src/MergeCmdLineInfo.h 2008-08-29 20:38:41 UTC (rev 5862)
@@ -32,21 +32,16 @@
// ID line follows -- this is updated by SVN
// $Id$
-class CmdLineParser;
-
/**
* @brief WinMerge's command line handler.
* This class calls command line parser(s) and allows reading parsed values
* from public member variables.
*/
-class MergeCmdLineInfo : public CCommandLineInfo
+class MergeCmdLineInfo
{
public:
- MergeCmdLineInfo(const TCHAR *szExeName);
- ~MergeCmdLineInfo();
+ MergeCmdLineInfo(LPCTSTR);
- virtual void ParseParam(const TCHAR* pszParam, BOOL bFlag, BOOL bLast);
-
public:
int m_nCmdShow; /**< Initial state of the application's window. */
@@ -56,32 +51,29 @@
bool m_bExitIfNoDiff; /**< Exit after telling the user that files are identical. */
bool m_bRecurse; /**< Include sub folder in directories compare. */
bool m_bNonInteractive; /**< Suppress user's notifications. */
- bool m_bNoPrefs; /**< Do not load or remember preferences. */
bool m_bSingleInstance; /**< Allow only one instance of WinMerge executable. */
bool m_bShowUsage; /**< Show a brief reminder to command line arguments. */
DWORD m_dwLeftFlags; /**< Left side file's behavior options. */
DWORD m_dwRightFlags; /**< Right side file's behavior options. */
- CString m_sLeftDesc; /**< Left side file's description. */
- CString m_sRightDesc; /**< Right side file's description. */
+ String m_sLeftDesc; /**< Left side file's description. */
+ String m_sRightDesc; /**< Right side file's description. */
- CString m_sFileFilter; /**< File filter mask. */
- CString m_sPreDiffer; /**< Pre-differ name. */
+ String m_sFileFilter; /**< File filter mask. */
+ String m_sPreDiffer; /**< Pre-differ name. */
- /** Command line arguments which are mapped to WinMerge's preferences. */
- CMapStringToString m_Settings;
+ std::vector<String> m_Files; /**< Files (or directories) to compare. */
- CStringArray m_Files; /**< Files (or directories) to compare. */
-
- int m_nFiles; /**< Number of files (or directories) in m_Files. */
-
private:
+ static LPCTSTR EatParam(LPCTSTR, String &, bool *flag = 0);
+ static LPCTSTR SetOption(LPCTSTR, LPCTSTR key, LPCTSTR value = _T("1"));
+ void ParseClearCaseCmdLine(LPCTSTR);
+ void ParseWinMergeCmdLine(LPCTSTR);
+
/** Operator= is not implemented. */
MergeCmdLineInfo& operator=(const MergeCmdLineInfo& rhs);
-
- CmdLineParser *m_pCmdLineParser; /**< The command line parser instance. */
};
#endif // _MERGE_CMD_LINE_INFO_INCLUDED_
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|