toolscmdlineparser.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 397 行
CPP
397 行
// ToolsCmdlineParser.cpp: implementation of the CToolsCmdlineParser class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "todolist.h"
#include "ToolsCmdlineParser.h"
#include "..\shared\datehelper.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMap<CString, LPCTSTR, CLA_TYPE, CLA_TYPE&> CToolsCmdlineParser::s_mapTypes;
CToolsCmdlineParser::CToolsCmdlineParser(LPCTSTR szCmdLine)
{
// init static map first time only
if (s_mapTypes.GetCount() == 0)
{
s_mapTypes["pathname"] = CLAT_PATHNAME;
s_mapTypes["filetitle"] = CLAT_FILETITLE;
s_mapTypes["folder"] = CLAT_FOLDER;
s_mapTypes["filename"] = CLAT_FILENAME;
s_mapTypes["seltid"] = CLAT_SELTASKID;
s_mapTypes["selttitle"] = CLAT_SELTASKTITLE;
s_mapTypes["userfile"] = CLAT_USERFILE;
s_mapTypes["userfolder"] = CLAT_USERFOLDER;
s_mapTypes["usertext"] = CLAT_USERTEXT;
s_mapTypes["userdate"] = CLAT_USERDATE;
s_mapTypes["todaysdate"] = CLAT_TODAYSDATE;
s_mapTypes["todolist"] = CLAT_TODOLIST;
s_mapTypes["seltextid"] = CLAT_SELTASKEXTID;
s_mapTypes["seltcomments"] = CLAT_SELTASKCOMMENTS;
}
SetCmdLine(szCmdLine);
}
CToolsCmdlineParser::~CToolsCmdlineParser()
{
}
void CToolsCmdlineParser::SetCmdLine(LPCTSTR szCmdLine)
{
m_sCmdLine = szCmdLine;
m_aArgs.RemoveAll();
ParseCmdLine();
// replace todaysdate
ReplaceArgument(CLAT_TODAYSDATE, CDateHelper::FormatCurrentDate(TRUE));
}
int CToolsCmdlineParser::GetArguments(CCLArgArray& aArgs) const
{
aArgs.Copy(m_aArgs);
return aArgs.GetSize();
}
int CToolsCmdlineParser::GetUserArguments(CCLArgArray& aArgs) const
{
int nArg = m_aArgs.GetSize();
// add to start to maintain order
while (nArg--)
{
switch (m_aArgs[nArg].nType)
{
case CLAT_USERFILE:
case CLAT_USERFOLDER:
case CLAT_USERTEXT:
case CLAT_USERDATE:
{
CMDLINEARG cla = m_aArgs[nArg];
aArgs.InsertAt(0, cla);
}
break;
}
}
return aArgs.GetSize();
}
BOOL CToolsCmdlineParser::ReplaceArgument(CLA_TYPE nType, LPCTSTR szValue)
{
// see if we have that type
int nArg = m_aArgs.GetSize();
BOOL bFound = FALSE;
// and replace all of them
while (nArg--)
{
if (m_aArgs[nArg].nType == nType)
bFound |= ReplaceArgument(nArg, szValue);
}
// not found
return bFound;
}
BOOL CToolsCmdlineParser::ReplaceArgument(CLA_TYPE nType, DWORD dwValue)
{
CString sValue;
sValue.Format("%d", dwValue);
return ReplaceArgument(nType, sValue);
}
BOOL CToolsCmdlineParser::ReplaceArgument(LPCTSTR szName, LPCTSTR szValue)
{
// see if we have a user item with that name
CString sName(szName);
sName.MakeLower();
int nArg = m_aArgs.GetSize();
while (nArg--)
{
switch (m_aArgs[nArg].nType)
{
case CLAT_USERFILE:
case CLAT_USERFOLDER:
case CLAT_USERTEXT:
case CLAT_USERDATE:
if (sName.CompareNoCase(m_aArgs[nArg].sName) == 0)
return ReplaceArgument(nArg, szValue);
break;
}
}
// not found
return FALSE;
}
BOOL CToolsCmdlineParser::IsUserInputRequired() const
{
// see if we have any 'USER' types
int nArg = m_aArgs.GetSize();
while (nArg--)
{
switch (m_aArgs[nArg].nType)
{
case CLAT_USERFILE:
case CLAT_USERFOLDER:
case CLAT_USERTEXT:
case CLAT_USERDATE:
return TRUE;
}
}
// not found
return FALSE;
}
BOOL CToolsCmdlineParser::HasTasklistArgument() const
{
// see if we have any tasklist related types
int nArg = m_aArgs.GetSize();
while (nArg--)
{
switch (m_aArgs[nArg].nType)
{
case CLAT_PATHNAME:
case CLAT_FILETITLE:
case CLAT_FOLDER:
case CLAT_FILENAME:
return TRUE;
}
}
// not found
return FALSE;
}
BOOL CToolsCmdlineParser::IsUserInputType(LPCTSTR szVarType)
{
switch (GetType(szVarType))
{
case CLAT_USERFILE:
case CLAT_USERFOLDER:
case CLAT_USERTEXT:
case CLAT_USERDATE:
return TRUE;
}
return FALSE;
}
BOOL CToolsCmdlineParser::ReplaceArgument(int nArg, LPCTSTR szValue)
{
if (nArg < 0 || nArg >= m_aArgs.GetSize())
return FALSE;
CMDLINEARG& cla = m_aArgs[nArg];
if (m_sCmdLine.Replace(cla.sPlaceHolder, szValue))
{
// also check if there are any user references to this variable name
// and replace those too
int nUserArg = m_aUserArgs.GetSize();
while (nUserArg--)
{
CMDLINEARG& claUser = m_aUserArgs[nUserArg];
if (claUser.sName.CompareNoCase(cla.sName) == 0)
{
m_sCmdLine.Replace(claUser.sPlaceHolder, szValue);
// and remove
m_aUserArgs.RemoveAt(nUserArg);
}
}
return TRUE;
}
// else
return FALSE;
}
BOOL CToolsCmdlineParser::HasArgument(CLA_TYPE nType) const
{
int nArg = m_aArgs.GetSize();
while (nArg--)
{
if (m_aArgs[nArg].nType == nType)
return TRUE;
}
return FALSE;
}
void CToolsCmdlineParser::ParseCmdLine()
{
CString sCmdLine(m_sCmdLine); // preserve original
int n$Find = sCmdLine.Find('$');
while (-1 != n$Find)
{
// find opening bracket
int nOpenFind = sCmdLine.Find('(', n$Find);
if (nOpenFind == -1)
break;
// find closing bracket
int nCloseFind = sCmdLine.Find(')', nOpenFind);
if (nCloseFind == -1)
break;
// parse variable in the form of (vartype, varname, varlabel, vardefvalue)
CString sVarArgs = sCmdLine.Mid(nOpenFind + 1, nCloseFind - nOpenFind - 1);
CString sType, sName, sLabel, sDefValue;
int nComma1Find = sVarArgs.Find(','), nComma2Find = -1;
if (nComma1Find != -1)
{
sType = sVarArgs.Left(nComma1Find);
nComma2Find = sVarArgs.Find(',', nComma1Find + 1);
if (nComma2Find != -1)
{
sName = sVarArgs.Mid(nComma1Find + 1, nComma2Find - nComma1Find - 1);
int nComma3Find = sVarArgs.Find(',', nComma2Find + 1);
if (nComma3Find != -1)
{
// this comma can either be a comma in the label string
// or the delimeter before 'vardefvalue'
// we determine which of these it is by looking for double quotes
int nQuoteStartFind = sVarArgs.Find('\"', nComma2Find + 1);
// and seeing if they preceed nComma3Find
if (nQuoteStartFind != -1 && nQuoteStartFind < nComma3Find)
{
// now look for closing quotes
int nQuoteEndFind = sVarArgs.Find('\"', nQuoteStartFind + 1);
if (nQuoteEndFind != -1) // test for nComma3Find again cos it was previously a false find
nComma3Find = sVarArgs.Find(',', nQuoteEndFind + 1);
else
nComma3Find = -1; // safest thing to do because no end quotes found
}
if (nComma3Find != -1)
{
sLabel = sVarArgs.Mid(nComma2Find + 1, nComma3Find - nComma2Find - 1);
sDefValue = sVarArgs.Mid(nComma3Find + 1);
sDefValue.Replace("\"", ""); // remove double quotes
}
else
sLabel = sVarArgs.Mid(nComma2Find + 1);
}
else
sLabel = sVarArgs.Mid(nComma2Find + 1);
sLabel.Replace("\"", ""); // remove double quotes
}
else
sName = sVarArgs.Mid(nComma1Find);
}
else
sType = sVarArgs;
// process
sType.TrimLeft();
sType.TrimRight();
sName.TrimLeft();
sName.TrimRight();
sName.MakeLower();
sLabel.TrimLeft();
sLabel.TrimRight();
sDefValue.TrimLeft();
sDefValue.TrimRight();
CMDLINEARG cla;
cla.nType = GetType(sType);
cla.sPlaceHolder = sCmdLine.Mid(n$Find, nCloseFind - n$Find + 1);
switch (cla.nType)
{
// user input types must have a valid name that is not a 'keyword'
case CLAT_USERFILE:
case CLAT_USERFOLDER:
case CLAT_USERTEXT:
case CLAT_USERDATE:
ASSERT(!sName.IsEmpty() && GetType(sName) == CLAT_NONE);
if (!sName.IsEmpty() && GetType(sName) == CLAT_NONE)
{
cla.sName = sName;
cla.sLabel = sLabel;
cla.sDefValue = sDefValue;
m_aArgs.Add(cla);
}
break;
case CLAT_TODOLIST:
case CLAT_PATHNAME:
case CLAT_FILETITLE:
case CLAT_FOLDER:
case CLAT_FILENAME:
case CLAT_TODAYSDATE:
case CLAT_SELTASKID:
case CLAT_SELTASKTITLE:
case CLAT_SELTASKEXTID:
case CLAT_SELTASKCOMMENTS:
m_aArgs.Add(cla);
break;
default: // it might a reference to a user type (or it may be a mistake)
ASSERT (cla.nType == CLAT_NONE); // what else?
cla.sName = sType;
m_aUserArgs.Add(cla);
break;
}
// next arg
n$Find = sCmdLine.Find('$', nCloseFind);
}
}
CLA_TYPE CToolsCmdlineParser::GetType(LPCTSTR szVarType)
{
CString sType(szVarType);
sType.TrimLeft();
sType.TrimRight();
sType.MakeLower();
CLA_TYPE nType = CLAT_NONE;
s_mapTypes.Lookup(sType, nType);
return nType;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?