You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

187 lines
5.3 KiB

// search for a switch in the command line
// return -1 if the switch is not found
// for separation purposes, we make the assumption that flags begin with a dash "-",
// but the "-" is still required in the pSwitch parameter
// otherwise return the number of characters in the argument after the flag
// if pArgs is a valid pointer, copy the argument data into it
// if bRemove is set, the flag (and it's argument, if pArgs is valid) will be removed
#include "StdAfx.h"
#include "CmdLine.h"
#include "Utils.h"
CCmdLine::CCmdLine() {
m_sProfilesDir = NULL;
m_bChrome = FALSE;
}
CCmdLine::~CCmdLine() {
if (m_sProfilesDir)
delete m_sProfilesDir;
}
void CCmdLine::Initialize(char *cmdLine) {
int len;
m_sCmdLine = cmdLine;
if (GetSwitch("-chrome", NULL, true) > 0)
m_bChrome = TRUE;
// -profilesDir <directory>
// or -profilesDir $appdata
len = GetSwitch("-profilesDir", NULL, false);
if (len == 0) // no arguments, invalid
GetSwitch("-profilesDir", NULL, true); // remove from command line
else if (len > 0) {
m_sProfilesDir = new char[len+1];
GetSwitch("-profilesDir", m_sProfilesDir, true);
if (!stricmp(m_sProfilesDir, "$appdata")) {
delete m_sProfilesDir;
m_sProfilesDir = new char[MAX_PATH];
ITEMIDLIST *idl;
if (SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &idl) == NOERROR) {
IMalloc *malloc;
SHGetPathFromIDListA(idl, m_sProfilesDir);
SHGetMalloc(&malloc);
malloc->Free(idl);
malloc->Release();
}
else
GetWindowsDirectoryA(m_sProfilesDir, MAX_PATH);
int len = strlen(m_sProfilesDir);
if (m_sProfilesDir[len-1] != '\\') {
m_sProfilesDir[len] = '\\';
m_sProfilesDir[len+1] = 0;
}
strcat(m_sProfilesDir, "K-Meleon");
}
}
}
int CCmdLine::GetSwitch(const char *pSwitch, char *pArgs, BOOL bRemove) {
char *p, *c;
char *pQuote;
char *pSwitchPos;
char *pCmdLine;
char *pArgStart, *pArgEnd;
int iQuoteCount;
BOOL bIsValidSwitch;
int iSwitchLen, iArgLen=0;
if ( !pSwitch || !*pSwitch )
return -1;
else
iSwitchLen = strlen(pSwitch);
p = pCmdLine = SkipWhiteSpace(m_sCmdLine);
do {
bIsValidSwitch = FALSE;
if ( ((!p) || (!*p)) || !(pSwitchPos = strstr(p, pSwitch)) ) {
if (pArgs) *pArgs = 0;
return -1;
}
p = SkipWhiteSpace(pSwitchPos + iSwitchLen);
// if this happens to be the first character on the command line,
// then we don't need to do any error checking
if (pSwitchPos == pCmdLine)
bIsValidSwitch = TRUE;
// make sure the flag is preceeded by whitespace
else if ( (*(pSwitchPos-1) != ' ') && (*(pSwitchPos-1) != '\t') )
continue;
// make sure the character after the flag is whitespace or null
else if ( (*(pSwitchPos+iSwitchLen) != ' ') && (*(pSwitchPos+iSwitchLen) != '\t') && (*(pSwitchPos+iSwitchLen) != 0) )
continue;
// if the "argument" starts with a dash, it's another switch, and this
// switch has no argument
else if (*p == '-') {
if (pArgs) *pArgs = 0;
return 0;
}
// make sure the switch we've found isn't inside quotation marks
else {
c = pCmdLine;
iQuoteCount = 0;
do {
pQuote = strchr(c, '\"');
if (pQuote) {
if ( !( *(pQuote-1) == '\\') )
iQuoteCount++;
c = pQuote+1;
}
} while ( pQuote && (pQuote < pSwitchPos) );
// there are 3 cases when the switch found will be valid
// 1) if there are the no quotes found before the switch
// 2) if there an odd number of quotes found, and the last quote is found after the switch
// 3) if there are an even number of quotes found, and no quotes after the switch
if ( (iQuoteCount == 0) || \
((pQuote) && (iQuoteCount%2)) || \
((!pQuote) && (!(iQuoteCount%2))) )
bIsValidSwitch = TRUE;
}
} while (pSwitchPos && !bIsValidSwitch);
if (pSwitchPos && bIsValidSwitch) {
pArgStart = SkipWhiteSpace(p);
// check if the argument is inside quotes
if (*pArgStart == '\"') {
pArgStart++;
pArgEnd = strchr(pArgStart, '\"');
}
// find the first whitespace
else {
char *pTab = strchr(pArgStart, '\t');
char *pSpace = strchr(pArgStart, ' ');
if (pTab && pSpace)
pArgEnd = ( pTab > pSpace ? pSpace : pTab );
else
pArgEnd = ( pTab ? pTab : pSpace );
}
if (pArgEnd)
iArgLen = pArgEnd-pArgStart;
else
iArgLen = strlen(pArgStart);
if (pArgs) {
if (iArgLen) {
memcpy(pArgs, pArgStart, iArgLen);
pArgs[iArgLen] = 0;
}
else
*pArgs = 0;
}
if (bRemove) {
char *pNewData;
if (pArgs)
pNewData = pArgEnd ? pArgEnd+1 : pArgStart + iArgLen;
else
pNewData = pSwitchPos + iSwitchLen;
pNewData = SkipWhiteSpace(pNewData);
while (*pNewData)
*pSwitchPos++ = *pNewData++;
*pSwitchPos = 0;
}
}
return iArgLen;
}