From dee72d2925b82fbf1e2ebf186ba84ccac699e98f Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 6 Feb 2015 21:56:21 -0800 Subject: [PATCH 1/9] Remove pnUtCmd. --- .../Plasma/NucleusLib/pnUtils/CMakeLists.txt | 2 - .../NucleusLib/pnUtils/pnUtAllIncludes.h | 1 - Sources/Plasma/NucleusLib/pnUtils/pnUtCmd.cpp | 650 ------------------ Sources/Plasma/NucleusLib/pnUtils/pnUtCmd.h | 136 ---- 4 files changed, 789 deletions(-) delete mode 100644 Sources/Plasma/NucleusLib/pnUtils/pnUtCmd.cpp delete mode 100644 Sources/Plasma/NucleusLib/pnUtils/pnUtCmd.h diff --git a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt index 6196649f..b1fac80f 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt +++ b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt @@ -7,7 +7,6 @@ set(pnUtils_HEADERS pnUtCoreLib.h pnUtAllIncludes.h pnUtArray.h - pnUtCmd.h pnUtCrypt.h pnUtHash.h pnUtList.h @@ -21,7 +20,6 @@ set(pnUtils_HEADERS set(pnUtils_SOURCES pnUtArray.cpp - pnUtCmd.cpp pnUtCrypt.cpp pnUtHash.cpp pnUtList.cpp diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h b/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h index ebc16979..f36cfd36 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h +++ b/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h @@ -58,7 +58,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "pnUtPriQ.h" #include "pnUtTime.h" #include "pnUtStr.h" -#include "pnUtCmd.h" #include "pnUtMisc.h" #include "pnUtCrypt.h" diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtCmd.cpp b/Sources/Plasma/NucleusLib/pnUtils/pnUtCmd.cpp deleted file mode 100644 index a11dca75..00000000 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtCmd.cpp +++ /dev/null @@ -1,650 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCmd.cpp -* -***/ - -#include "pnUtCmd.h" -#include "pnUtMisc.h" - - -/***************************************************************************** -* -* Private -* -***/ - -#define WHITESPACE L" \"\t\r\n\x1A" -#define FLAGS L"-/" -#define SEPARATORS L"=:" -#define TOGGLES L"+-" -#define ALL WHITESPACE FLAGS SEPARATORS TOGGLES - -#if HS_BUILD_FOR_WIN32 -static const unsigned kMaxTokenLength = MAX_PATH; -#else -static const unsigned kMaxTokenLength = 1024; -#endif - -struct CmdArgData { - CmdArgDef def; - union { - bool boolVal; - float floatVal; - int intVal; - const wchar_t * strVal; - unsigned unsignedVal; - } val; - wchar_t * buffer; - unsigned nameChars; - bool isSpecified; - - ~CmdArgData () { - if (buffer) - free(buffer); - } -}; - -struct CmdTokState { - CCmdParser * parser; - unsigned pendingIndex; - unsigned unflaggedIndex; -}; - -class CICmdParser { -private: - FARRAYOBJ(CmdArgData) m_argArray; - FARRAY(unsigned) m_idLookupArray; - unsigned m_requiredCount; - FARRAY(unsigned) m_unflaggedArray; - - inline bool CheckFlag (unsigned flags, unsigned flag, unsigned mask) const; - void Error (const CmdTokState * state, ECmdError errorCode, const wchar_t arg[], const wchar_t value[]) const; - bool LookupFlagged (const wchar_t ** name, unsigned * lastIndex) const; - bool ProcessValue (CmdTokState * state, unsigned index, const wchar_t str[]); - void SetDefaultValue (CmdArgData & arg); - bool TokenizeFlags (CmdTokState * state, const wchar_t str[]); - -public: - CICmdParser (const CmdArgDef def[], unsigned defCount); - bool CheckAllRequiredArguments (CmdTokState * state); - const CmdArgData * FindArgById (unsigned id) const; - const CmdArgData * FindArgByName (const wchar_t name[]) const; - bool Tokenize (CmdTokState * state, const wchar_t str[]); - -}; - - -/***************************************************************************** -* -* CICmdParser implementation -* -***/ - -//=========================================================================== -bool CICmdParser::CheckFlag (unsigned flags, unsigned flag, unsigned mask) const { - return ((flags & mask) == flag); -} - -//=========================================================================== -bool CICmdParser::CheckAllRequiredArguments (CmdTokState * state) { - bool result = (state->unflaggedIndex >= m_requiredCount); - if (!result) - Error(state, kCmdErrorTooFewArgs, nil, nil); - return result; -} - -//=========================================================================== -CICmdParser::CICmdParser (const CmdArgDef def[], unsigned defCount) { - unsigned loop; - - // Save the argument definitions - unsigned maxId = 0; - unsigned unflaggedCount = 0; - m_argArray.SetCount(defCount); - for (loop = 0; loop < defCount; ++loop) { - - // Check whether this argument is flagged - bool flagged = CheckFlag(def[loop].flags, kCmdArgFlagged, kCmdMaskArg); - - // Disallow names on unflagged arguments - ASSERT(flagged || !def[loop].name); - - // Store the argument data - CmdArgData & arg = m_argArray[loop]; - arg.def = def[loop]; - arg.buffer = nil; - arg.nameChars = def[loop].name ? StrLen(def[loop].name) : 0; - arg.isSpecified = false; - SetDefaultValue(arg); - maxId = std::max(maxId, def[loop].id); - - // Track the number of unflagged arguments - if (!flagged) - ++unflaggedCount; - - } - - // Build the id lookup table - unsigned idTableSize = std::min(maxId + 1, defCount * 2); - m_idLookupArray.SetCount(idTableSize); - m_idLookupArray.Zero(); - for (loop = 0; loop < defCount; ++loop) - if (def[loop].id < idTableSize) - m_idLookupArray[def[loop].id] = loop; - - // Build the unflagged array - unsigned unflaggedIndex = 0; - m_unflaggedArray.SetCount(unflaggedCount); - for (loop = 0; loop < defCount; ++loop) - if (CheckFlag(def[loop].flags, kCmdArgRequired, kCmdMaskArg)) - m_unflaggedArray[unflaggedIndex++] = loop; - m_requiredCount = unflaggedIndex; - for (loop = 0; loop < defCount; ++loop) - if (!(CheckFlag(def[loop].flags, kCmdArgFlagged, kCmdMaskArg) || - CheckFlag(def[loop].flags, kCmdArgRequired, kCmdMaskArg))) - m_unflaggedArray[unflaggedIndex++] = loop; - -} - -//=========================================================================== -void CICmdParser::Error (const CmdTokState * state, ECmdError errorCode, const wchar_t arg[], const wchar_t value[]) const { - - // Compose the error text - // (This text is only provided as a shortcut for trivial applications that - // don't want to compose their own text. Normally, an application would - // compose error text using its own localized strings.) - unsigned chars = 256 + (arg ? StrLen(arg) : 0) + (value ? StrLen(value) : 0); - wchar_t * buffer = (wchar_t *)malloc(chars * sizeof(wchar_t)); - switch (errorCode) { - - case kCmdErrorInvalidArg: - StrPrintf(buffer, chars, L"Invalid argument: %s", arg); - break; - - case kCmdErrorInvalidValue: - StrPrintf(buffer, chars, L"Argument %s invalid value: %s", arg, value); - break; - - case kCmdErrorTooFewArgs: - StrPrintf(buffer, chars, L"Too few arguments"); - break; - - case kCmdErrorTooManyArgs: - StrPrintf(buffer, chars, L"Too many arguments: %s", arg); - break; - - DEFAULT_FATAL(errorCode); - } - - // Call the error handler - state->parser->OnError(buffer, errorCode, arg, value); - - // Free memory - free(buffer); - -} - -//=========================================================================== -const CmdArgData * CICmdParser::FindArgById (unsigned id) const { - - // Search for the argument with this id - unsigned index; - if (id < m_idLookupArray.Count()) - index = m_idLookupArray[id]; - else - for (index = 0; index < m_argArray.Count(); ++index) - if (m_argArray[index].def.id == id) - break; - - // Verify that we found the correct argument - if ( (index >= m_argArray.Count()) || - (m_argArray[index].def.id != id) ) - return nil; - - // Return the argument data - return &m_argArray[index]; - -} - -//=========================================================================== -const CmdArgData * CICmdParser::FindArgByName (const wchar_t name[]) const { - - // Search for an argument with this name - unsigned index = (unsigned)-1; - if (!LookupFlagged(&name, &index)) - return nil; - - // Return the argument data - return &m_argArray[index]; - -} - -//=========================================================================== -bool CICmdParser::LookupFlagged (const wchar_t ** name, unsigned * lastIndex) const { - unsigned argCount = m_argArray.Count(); - unsigned chars = StrLen(*name); - unsigned bestIndex = (unsigned)-1; - unsigned bestChars = 0; - - // Check whether this argument is a suffix to any previously - // provided prefix in this token - for (unsigned prevChars = (*lastIndex != (unsigned)-1) ? m_argArray[*lastIndex].nameChars : 0; - (prevChars != (unsigned)-1) && !bestChars; - --prevChars) { - const CmdArgData & prev = prevChars ? m_argArray[*lastIndex] : *(const CmdArgData *)nil; - - // Find this argument in the list - for (unsigned index = 0; index < argCount; ++index) { - const CmdArgData & arg = m_argArray[index]; - - // Ignore non-flagged arguments - if (!CheckFlag(arg.def.flags, kCmdArgFlagged, kCmdMaskArg)) - continue; - - // Ignore this argument if it wouldn't beat the previous best match - if (arg.nameChars < bestChars + prevChars) - continue; - - // Ignore this argument if it doesn't match the prefix - bool caseSensitive = CheckFlag(arg.def.flags, kCmdCaseSensitive, kCmdCaseSensitive); - if ( prevChars && - ( (prevChars >= arg.nameChars) || - ( caseSensitive && StrCmp(arg.def.name, prev.def.name, prevChars)) || - (!caseSensitive && StrCmpI(arg.def.name, prev.def.name, prevChars)) ) ) - continue; - - // Ignore this argument if it doesn't match the suffix - if ( ( caseSensitive && StrCmp(*name, arg.def.name + prevChars, arg.nameChars - prevChars)) || - (!caseSensitive && StrCmpI(*name, arg.def.name + prevChars, arg.nameChars - prevChars)) ) - continue; - - // Track the best match - bestIndex = index; - bestChars = arg.nameChars - prevChars; - if (bestChars == chars) - break; - - } - - } - - // Return the result - *name += bestChars; - *lastIndex = bestIndex; - return (bestChars != 0); -} - -//=========================================================================== -bool CICmdParser::ProcessValue (CmdTokState * state, unsigned index, const wchar_t str[]) { - CmdArgData & arg = m_argArray[index]; - arg.isSpecified = true; - unsigned argType = arg.def.flags & kCmdMaskType; - switch (argType) { - - case kCmdTypeBool: - if (*str == '+') - arg.val.boolVal = true; - else if (*str == '-') - arg.val.boolVal = false; - else if (!*str) - arg.val.boolVal = CheckFlag(arg.def.flags, kCmdBoolSet, kCmdMaskBool); - else - Error(state, kCmdErrorInvalidValue, arg.def.name, str); - break; - - case kCmdTypeFloat: - { - const wchar_t * endPtr; - arg.val.floatVal = StrToFloat(str, &endPtr); - if (*endPtr) - Error(state, kCmdErrorInvalidValue, arg.def.name, str); - } - break; - - case kCmdTypeInt: - { - const wchar_t * endPtr; - arg.val.intVal = StrToInt(str, &endPtr); - if (*endPtr) - Error(state, kCmdErrorInvalidValue, arg.def.name, str); - } - break; - - case kCmdTypeString: - if (arg.buffer) - free(arg.buffer); - arg.buffer = StrDup(str); - arg.val.strVal = arg.buffer; - break; - - case kCmdTypeUnsigned: - { - const wchar_t * endPtr; - arg.val.unsignedVal = StrToUnsigned(str, &endPtr, 10); - if (*endPtr) - Error(state, kCmdErrorInvalidValue, arg.def.name, str); - } - break; - - DEFAULT_FATAL(argType); - - } - return true; -} - -//=========================================================================== -void CICmdParser::SetDefaultValue (CmdArgData & arg) { - unsigned argType = arg.def.flags & kCmdMaskType; - switch (argType) { - - case kCmdTypeBool: - arg.val.boolVal = !CheckFlag(arg.def.flags, kCmdBoolSet, kCmdMaskBool); - break; - - case kCmdTypeInt: - arg.val.intVal = 0; - break; - - case kCmdTypeUnsigned: - arg.val.unsignedVal = 0; - break; - - case kCmdTypeFloat: - arg.val.floatVal = 0.0f; - break; - - case kCmdTypeString: - arg.val.strVal = L""; - break; - - DEFAULT_FATAL(argType); - - } -} - -//=========================================================================== -bool CICmdParser::Tokenize (CmdTokState * state, const wchar_t str[]) { - wchar_t buffer[kMaxTokenLength]; - bool result = true; - while (result && StrTokenize(&str, buffer, arrsize(buffer), WHITESPACE)) { - - // If the previous argument is awaiting a value, then use this token - // as the value - if (state->pendingIndex != (unsigned)-1) { - result = ProcessValue(state, state->pendingIndex, buffer); - state->pendingIndex = (unsigned)-1; - continue; - } - - // Identify and process flagged parameters - if (StrChr(FLAGS, buffer[0]) && TokenizeFlags(state, buffer)) - continue; - - // Process unflagged parameters - if (state->unflaggedIndex < m_unflaggedArray.Count()) { - result = ProcessValue(state, m_unflaggedArray[state->unflaggedIndex++], buffer); - continue; - } - - // Process extra parameters - if (state->parser->OnExtra(buffer)) - continue; - - // Process invalid parameters - Error(state, kCmdErrorTooManyArgs, buffer, nil); - result = false; - break; - - } - return result; -} - -//=========================================================================== -bool CICmdParser::TokenizeFlags (CmdTokState * state, const wchar_t str[]) { - - // Process each separately flagged token within the string - wchar_t buffer[kMaxTokenLength]; - bool result = true; - while (result && StrTokenize(&str, buffer, arrsize(buffer), ALL)) { - if (!buffer[0]) - continue; - - // Process each flag within the token - unsigned lastIndex = (unsigned)-1; - const wchar_t * bufferPtr = buffer; - while (result) { - - // Lookup the argument name - result = LookupFlagged(&bufferPtr, &lastIndex); - if (!result) { - Error(state, kCmdErrorInvalidArg, bufferPtr, nil); - result = false; - break; - } - - // If this argument is boolean, allow it to share a common prefix - // with the next argument. In this case there is no place for - // the user to provide a value, so use the default value. - if (*bufferPtr && - CheckFlag(m_argArray[lastIndex].def.flags, kCmdTypeBool, kCmdMaskType)) { - result = ProcessValue(state, lastIndex, L""); - continue; - } - - break; - } - if (!result) - break; - - // Check for an argument value provided using a separator - if (*str && StrChr(SEPARATORS, *str)) { - result = ProcessValue(state, lastIndex, str + 1); - break; - } - - // Process values for boolean arguments - if (CheckFlag(m_argArray[lastIndex].def.flags, kCmdTypeBool, kCmdMaskType)) { - - // Check for a value provided with a toggle - if (*str && StrChr(TOGGLES, *str)) { - wchar_t tempStr[] = {*str, 0}; - result = ProcessValue(state, lastIndex, tempStr); - ++str; - continue; - } - - // Check for a default value - else { - result = ProcessValue(state, lastIndex, L""); - continue; - } - - } - - // Process values for non-boolean arguments - else { - - // Check for an argument value immediately following the name - if (*bufferPtr) { - result = ProcessValue(state, lastIndex, bufferPtr); - break; - } - - // Check for an argument value in the next token - else { - state->pendingIndex = lastIndex; - break; - } - - } - - } - return result; -} - - -/***************************************************************************** -* -* CCmdParser implementation -* -***/ - -//=========================================================================== -CCmdParser::CCmdParser () { - fParser = nil; -} - -//=========================================================================== -CCmdParser::CCmdParser (const CmdArgDef def[], unsigned defCount) { - Initialize(def, defCount); -} - -//=========================================================================== -CCmdParser::~CCmdParser () { - delete fParser; -} - -//=========================================================================== -bool CCmdParser::GetBool (unsigned id) const { - return fParser->FindArgById(id)->val.boolVal; -} - -//=========================================================================== -bool CCmdParser::GetBool (const wchar_t name[]) const { - return fParser->FindArgByName(name)->val.boolVal; -} - -//=========================================================================== -float CCmdParser::GetFloat (unsigned id) const { - return fParser->FindArgById(id)->val.floatVal; -} - -//=========================================================================== -float CCmdParser::GetFloat (const wchar_t name[]) const { - return fParser->FindArgByName(name)->val.floatVal; -} - -//=========================================================================== -int CCmdParser::GetInt (unsigned id) const { - return fParser->FindArgById(id)->val.intVal; -} - -//=========================================================================== -int CCmdParser::GetInt (const wchar_t name[]) const { - return fParser->FindArgByName(name)->val.intVal; -} - -//=========================================================================== -const wchar_t * CCmdParser::GetString (unsigned id) const { - return fParser->FindArgById(id)->val.strVal; -} - -//=========================================================================== -const wchar_t * CCmdParser::GetString (const wchar_t name[]) const { - return fParser->FindArgByName(name)->val.strVal; -} - -//=========================================================================== -unsigned CCmdParser::GetUnsigned (unsigned id) const { - return fParser->FindArgById(id)->val.unsignedVal; -} - -//=========================================================================== -unsigned CCmdParser::GetUnsigned (const wchar_t name[]) const { - return fParser->FindArgByName(name)->val.unsignedVal; -} - -//=========================================================================== -void CCmdParser::Initialize (const CmdArgDef def[], unsigned defCount) { - fParser = new CICmdParser(def, defCount); -} - -//=========================================================================== -bool CCmdParser::IsSpecified (unsigned id) const { - if (const CmdArgData * data = fParser->FindArgById(id)) - return data->isSpecified; - return false; -} - -//=========================================================================== -bool CCmdParser::IsSpecified (const wchar_t name[]) const { - if (const CmdArgData * data = fParser->FindArgByName(name)) - return data->isSpecified; - return false; -} - -//=========================================================================== -void CCmdParser::OnError (const wchar_t str[], ECmdError errorCode, const wchar_t arg[], const wchar_t value[]) { -} - -//=========================================================================== -bool CCmdParser::OnExtra (const wchar_t str[]) { - return false; -} - -//=========================================================================== -bool CCmdParser::Parse (const wchar_t cmdLine[]) { - // If no command line was passed, use the application's command line, - // skipping past the program name - if (!cmdLine) { - cmdLine = AppGetCommandLine(); - StrTokenize(&cmdLine, nil, 0, WHITESPACE); - while (*cmdLine == L' ') - ++cmdLine; - } - - // Process the command line - CmdTokState state = { - this, - (unsigned)-1, // pending index - 0 // unflagged index - }; - bool result; - result = fParser->Tokenize(&state, cmdLine); - if (result) - result = fParser->CheckAllRequiredArguments(&state); - - return result; -} diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtCmd.h b/Sources/Plasma/NucleusLib/pnUtils/pnUtCmd.h deleted file mode 100644 index bed775d6..00000000 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtCmd.h +++ /dev/null @@ -1,136 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtCmd.h -* -***/ - -#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTCMD_H -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTCMD_H - -#include "Pch.h" -#include "pnUtArray.h" -#include "pnUtStr.h" - -/***************************************************************************** -* -* Constants -* -***/ - -// Sets of mutually exclusive flags -const unsigned kCmdArgFlagged = 0x0 << 0; // default -const unsigned kCmdArgOptional = 0x1 << 0; -const unsigned kCmdArgRequired = 0x2 << 0; -const unsigned kCmdMaskArg = 0xf << 0; - -const unsigned kCmdTypeBool = 0x0 << 4; // default -const unsigned kCmdTypeInt = 0x1 << 4; -const unsigned kCmdTypeUnsigned = 0x2 << 4; -const unsigned kCmdTypeFloat = 0x3 << 4; -const unsigned kCmdTypeString = 0x4 << 4; -const unsigned kCmdMaskType = 0xf << 4; - -const unsigned kCmdBoolSet = 0x0 << 8; // default -const unsigned kCmdBoolUnset = 0x1 << 8; -const unsigned kCmdMaskBool = 0xf << 8; - -// Other flags -const unsigned kCmdCaseSensitive = 0x1 << 28; - - -// Error codes -enum ECmdError { - kCmdErrorInvalidArg, - kCmdErrorInvalidValue, - kCmdErrorTooFewArgs, - kCmdErrorTooManyArgs, - kNumCmdErrors -}; - - -/***************************************************************************** -* -* Types -* -***/ - -struct CmdArgDef { - unsigned flags; - const wchar_t * name; // must be compile-time constant - unsigned id; -}; - -class CCmdParser { - class CICmdParser * fParser; - - static void DispatchError (const wchar_t str[], ECmdError errorCode, const wchar_t arg[], const wchar_t value[], void * param); - static bool DispatchExtra (const wchar_t str[], void * param); - -protected: - CCmdParser (); - void Initialize (const CmdArgDef def[], unsigned defCount); - -public: - CCmdParser (const CmdArgDef def[], unsigned defCount); - virtual ~CCmdParser (); - - bool GetBool (unsigned id) const; - bool GetBool (const wchar_t name[]) const; - float GetFloat (unsigned id) const; - float GetFloat (const wchar_t name[]) const; - int GetInt (unsigned id) const; - int GetInt (const wchar_t name[]) const; - const wchar_t * GetString (unsigned id) const; - const wchar_t * GetString (const wchar_t name[]) const; - unsigned GetUnsigned (unsigned id) const; - unsigned GetUnsigned (const wchar_t name[]) const; - bool IsSpecified (unsigned id) const; - bool IsSpecified (const wchar_t name[]) const; - - virtual void OnError (const wchar_t str[], ECmdError errorCode, const wchar_t arg[], const wchar_t value[]); - virtual bool OnExtra (const wchar_t str[]); - - bool Parse (const wchar_t cmdLine[] = nil); -}; -#endif From 507dc14c894872d09b369c6f52e901d5752f9ce2 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 6 Feb 2015 21:56:45 -0800 Subject: [PATCH 2/9] Remove now-unused pnUtStr functions. --- Sources/Plasma/NucleusLib/pnUtils/pnUtStr.cpp | 169 ------------------ Sources/Plasma/NucleusLib/pnUtils/pnUtStr.h | 22 --- 2 files changed, 191 deletions(-) diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtStr.cpp b/Sources/Plasma/NucleusLib/pnUtils/pnUtStr.cpp index 3e2a8f1a..0043d6e3 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtStr.cpp +++ b/Sources/Plasma/NucleusLib/pnUtils/pnUtStr.cpp @@ -98,16 +98,6 @@ static chartype * IStrDup (const chartype str[]) { return buffer; } -//=========================================================================== -template -static chartype * IStrChr (chartype * str, findchartype ch, unsigned chars) { - for (; chars--; ++str) - if (*str == ch) - return str; - else if (!*str) - break; - return nil; -} //=========================================================================== template @@ -179,85 +169,6 @@ static uint32_t IStrHashI (const chartype str[], unsigned chars) { return result; } -//=========================================================================== -template -static bool IStrTokenize (const chartype * source[], chartype * dest, unsigned chars, const chartype whitespace[], unsigned maxWhitespaceSkipCount) { - - // Skip past leading whitespace - bool inQuotes = false; - unsigned whitespaceSkipped = 0; - while (**source && IStrChr(whitespace, **source, (unsigned)-1) && whitespaceSkipped < maxWhitespaceSkipCount) { - inQuotes = (**source == '\"'); - ++*source; - ++whitespaceSkipped; - if (inQuotes) - break; - } - - // Copy the token - unsigned offset = 0; - while (**source && - ((inQuotes && (**source != '\"')) || !IStrChr(whitespace, **source, (unsigned)-1))) { - if (offset + 1 < chars) - dest[offset++] = **source; - ++*source; - } - - // Skip past the terminating quote - if (inQuotes && (**source == '\"')) - ++*source; - - // Null terminate the destination buffer - if (chars) { - ASSERT(offset < chars); - dest[offset] = 0; - } - - // Upon return, 'source' is guaranteed to point to the first character - // following the returned token (and following any closing quotes) - - return (offset || inQuotes); -} - -//=========================================================================== -template -static bool IStrTokenize (const chartype * source[], ARRAY(chartype) * destArray, const chartype whitespace[], unsigned maxWhitespaceSkipCount) { - - // Verify that the destination array is empty - ASSERT(!destArray->Count()); - - // Skip past leading whitespace - bool inQuotes = false; - unsigned whitespaceSkipped = 0; - while (**source && IStrChr(whitespace, **source, (unsigned)-1) && whitespaceSkipped < maxWhitespaceSkipCount) { - inQuotes = (**source == '\"'); - ++*source; - ++whitespaceSkipped; - if (inQuotes) - break; - } - - // Copy the token - bool added = false; - while (**source && - ((inQuotes && (**source != '\"')) || !IStrChr(whitespace, **source, (unsigned)-1))) { - destArray->Add(**source); - added = true; - ++*source; - } - - // Skip past the terminating quote - if (inQuotes && (**source == '\"')) - ++*source; - - // Null terminate the destination array - destArray->Add(0); - - // Upon return, 'source' is guaranteed to point to the first character - // following the returned token (and following any closing quotes) - - return (added || inQuotes); -} /**************************************************************************** @@ -276,26 +187,6 @@ wchar_t * StrDup (const wchar_t str[]) { return IStrDup(str); } -//=========================================================================== -char * StrChr (char * str, char ch, unsigned chars) { - return IStrChr(str, ch, chars); -} - -//=========================================================================== -wchar_t * StrChr (wchar_t * str, wchar_t ch, unsigned chars) { - return IStrChr(str, ch, chars); -} - -//=========================================================================== -const char * StrChr (const char str[], char ch, unsigned chars) { - return IStrChr(str, ch, chars); -} - -//=========================================================================== -const wchar_t * StrChr (const wchar_t str[], wchar_t ch, unsigned chars) { - return IStrChr(str, ch, chars); -} - //=========================================================================== unsigned StrPrintf (char * dest, unsigned count, const char format[], ...) { va_list argList; @@ -366,46 +257,6 @@ unsigned StrLen (const wchar_t str[]) { return IStrLen(str); } -//=========================================================================== -float StrToFloat (const char source[], const char ** endptr) { - return (float) strtod(source, const_cast(endptr)); -} - -//=========================================================================== -float StrToFloat (const wchar_t source[], const wchar_t ** endptr) { - return (float) wcstod(source, const_cast(endptr)); -} - -//=========================================================================== -int StrToInt (const char source[], const char ** endptr) { - return strtol(source, const_cast(endptr), 0); -} - -//=========================================================================== -int StrToInt (const wchar_t source[], const wchar_t ** endptr) { - return wcstol(source, const_cast(endptr), 0); -} - -//=========================================================================== -unsigned StrToUnsigned (char source[], char ** endptr, int radix) { - return strtoul(source, const_cast(endptr), radix); -} - -//=========================================================================== -unsigned StrToUnsigned (wchar_t source[], wchar_t ** endptr, int radix) { - return wcstoul(source, const_cast(endptr), radix); -} - -//=========================================================================== -unsigned StrToUnsigned (const char source[], const char ** endptr, int radix) { - return strtoul(source, const_cast(endptr), radix); -} - -//=========================================================================== -unsigned StrToUnsigned (const wchar_t source[], const wchar_t ** endptr, int radix) { - return wcstoul(source, const_cast(endptr), radix); -} - //=========================================================================== uint32_t StrHash (const char str[], unsigned chars) { return IStrHash(str, chars); @@ -425,23 +276,3 @@ uint32_t StrHashI (const char str[], unsigned chars) { uint32_t StrHashI (const wchar_t str[], unsigned chars) { return IStrHashI(str, chars); } - -//=========================================================================== -bool StrTokenize (const char * source[], char * dest, unsigned chars, const char whitespace[], unsigned maxWhitespaceSkipCount) { - return IStrTokenize(source, dest, chars, whitespace, maxWhitespaceSkipCount); -} - -//=========================================================================== -bool StrTokenize (const wchar_t * source[], wchar_t * dest, unsigned chars, const wchar_t whitespace[], unsigned maxWhitespaceSkipCount) { - return IStrTokenize(source, dest, chars, whitespace, maxWhitespaceSkipCount); -} - -//=========================================================================== -bool StrTokenize (const char * source[], ARRAY(char) * destArray, const char whitespace[], unsigned maxWhitespaceSkipCount) { - return IStrTokenize(source, destArray, whitespace, maxWhitespaceSkipCount); -} - -//=========================================================================== -bool StrTokenize (const wchar_t * source[], ARRAY(wchar_t) * destArray, const wchar_t whitespace[], unsigned maxWhitespaceSkipCount) { - return IStrTokenize(source, destArray, whitespace, maxWhitespaceSkipCount); -} diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtStr.h b/Sources/Plasma/NucleusLib/pnUtils/pnUtStr.h index 2102c4e1..46b54238 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtStr.h +++ b/Sources/Plasma/NucleusLib/pnUtils/pnUtStr.h @@ -55,7 +55,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com // Got Damn eap... // Duplicate Symbols in shlwapi! #ifdef _INC_SHLWAPI -# undef StrChr # undef StrDup #endif // _INC_SHLWAPI @@ -68,11 +67,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com inline char CharLowerFast (char ch) { return ((ch >= 'A') && (ch <= 'Z')) ? (char )(ch + 'a' - 'A') : ch; } inline wchar_t CharLowerFast (wchar_t ch) { return ((ch >= L'A') && (ch <= L'Z')) ? (wchar_t)(ch + L'a' - L'A') : ch; } -char * StrChr (char * str, char ch, unsigned chars = (unsigned)-1); -wchar_t * StrChr (wchar_t * str, wchar_t ch, unsigned chars = (unsigned)-1); -const char * StrChr (const char str[], char ch, unsigned chars = (unsigned)-1); -const wchar_t * StrChr (const wchar_t str[], wchar_t ch, unsigned chars = (unsigned)-1); - unsigned StrPrintf (char * dest, unsigned count, const char format[], ...); unsigned StrPrintf (wchar_t * dest, unsigned count, const wchar_t format[], ...); @@ -94,25 +88,9 @@ int StrCmpI (const wchar_t str1[], const wchar_t str2[], unsigned chars = (unsig void StrCopy (char * dest, const char source[], unsigned chars); void StrCopy (wchar_t * dest, const wchar_t source[], unsigned chars); -float StrToFloat (const char source[], const char ** endptr); -float StrToFloat (const wchar_t source[], const wchar_t ** endptr); - -int StrToInt (const char source[], const char ** endptr); -int StrToInt (const wchar_t source[], const wchar_t ** endptr); - -unsigned StrToUnsigned (char source[], char ** endptr, int radix); -unsigned StrToUnsigned (wchar_t source[], wchar_t ** endptr, int radix); -unsigned StrToUnsigned (const char source[], const char ** endptr, int radix); -unsigned StrToUnsigned (const wchar_t source[], const wchar_t ** endptr, int radix); - uint32_t StrHash (const char str[], unsigned chars = (unsigned)-1); uint32_t StrHash (const wchar_t str[], unsigned chars = (unsigned)-1); uint32_t StrHashI (const char str[], unsigned chars = (unsigned)-1); uint32_t StrHashI (const wchar_t str[], unsigned chars = (unsigned)-1); - -bool StrTokenize (const char * source[], char * dest, unsigned chars, const char whitespace[], unsigned maxWhitespaceSkipCount = (unsigned)-1); -bool StrTokenize (const wchar_t * source[], wchar_t * dest, unsigned chars, const wchar_t whitespace[], unsigned maxWhitespaceSkipCount = (unsigned)-1); -bool StrTokenize (const char * source[], ARRAY(char) * destArray, const char whitespace[], unsigned maxWhitespaceSkipCount = (unsigned)-1); -bool StrTokenize (const wchar_t * source[], ARRAY(wchar_t) * destArray, const wchar_t whitespace[], unsigned maxWhitespaceSkipCount = (unsigned)-1); #endif From a750616530fd0576620c2d24d6f71002500f4163 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Sat, 7 Feb 2015 15:33:04 -0800 Subject: [PATCH 3/9] Remove unused pnUtMisc code. --- .../Plasma/NucleusLib/pnUtils/CMakeLists.txt | 13 +-- .../NucleusLib/pnUtils/Win32/pnUtW32Misc.cpp | 60 ------------ .../Plasma/NucleusLib/pnUtils/pnUtMisc.cpp | 91 ------------------- Sources/Plasma/NucleusLib/pnUtils/pnUtMisc.h | 72 --------------- 4 files changed, 1 insertion(+), 235 deletions(-) delete mode 100644 Sources/Plasma/NucleusLib/pnUtils/Win32/pnUtW32Misc.cpp delete mode 100644 Sources/Plasma/NucleusLib/pnUtils/pnUtMisc.cpp delete mode 100644 Sources/Plasma/NucleusLib/pnUtils/pnUtMisc.h diff --git a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt index b1fac80f..03610c9d 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt +++ b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt @@ -10,7 +10,6 @@ set(pnUtils_HEADERS pnUtCrypt.h pnUtHash.h pnUtList.h - pnUtMisc.h pnUtPragma.h pnUtPriQ.h pnUtSort.h @@ -23,21 +22,11 @@ set(pnUtils_SOURCES pnUtCrypt.cpp pnUtHash.cpp pnUtList.cpp - pnUtMisc.cpp pnUtStr.cpp pnUtTime.cpp ) -if(WIN32) - set(pnUtils_WIN32 - Win32/pnUtW32Misc.cpp - ) -endif(WIN32) - -add_library(pnUtils STATIC ${pnUtils_HEADERS} ${pnUtils_SOURCES} ${pnUtils_WIN32}) +add_library(pnUtils STATIC ${pnUtils_HEADERS} ${pnUtils_SOURCES}) source_group("Header Files" FILES ${pnUtils_HEADERS}) source_group("Source Files" FILES ${pnUtils_SOURCES}) -if(WIN32) - source_group("Win32" FILES ${pnUtils_WIN32}) -endif(WIN32) diff --git a/Sources/Plasma/NucleusLib/pnUtils/Win32/pnUtW32Misc.cpp b/Sources/Plasma/NucleusLib/pnUtils/Win32/pnUtW32Misc.cpp deleted file mode 100644 index 645e4c1d..00000000 --- a/Sources/Plasma/NucleusLib/pnUtils/Win32/pnUtW32Misc.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/Win32/pnUtW32Misc.cpp -* -***/ - -#include "../pnUtils.h" - -/***************************************************************************** -* -* Exports -* -***/ - -//============================================================================ -const wchar_t * AppGetCommandLine () { - return GetCommandLineW(); -} - diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtMisc.cpp b/Sources/Plasma/NucleusLib/pnUtils/pnUtMisc.cpp deleted file mode 100644 index 76ad8bd2..00000000 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtMisc.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMisc.cpp -* -***/ - -#include "pnUtMisc.h" - - -/***************************************************************************** -* -* Private data -* -***/ - -static void * s_moduleInstance; - - -/***************************************************************************** -* -* Public functions -* -***/ - -//============================================================================ -void ModuleSetInstance (void * instance) { - s_moduleInstance = instance; -} - -//============================================================================ -void * ModuleGetInstance () { - return s_moduleInstance; -} - - -/***************************************************************************** -* -* Dll initialization -* -***/ - -//============================================================================ -#if HS_BUILD_FOR_WIN32 -BOOL WINAPI PreDllMain (HANDLE handle, DWORD reason, LPVOID) { - if (reason == DLL_PROCESS_ATTACH) { - ModuleSetInstance(handle); - } - return true; -} -#endif diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtMisc.h b/Sources/Plasma/NucleusLib/pnUtils/pnUtMisc.h deleted file mode 100644 index a416fce0..00000000 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtMisc.h +++ /dev/null @@ -1,72 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ -/***************************************************************************** -* -* $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtMisc.h -* -***/ - -#ifndef PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTMISC_H -#define PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTMISC_H - -#include "Pch.h" -#include "pnUtArray.h" - -/***************************************************************************** -* -* Module instance functions -* -***/ - -void ModuleSetInstance (void * instance); -void * ModuleGetInstance (); - - -/***************************************************************************** -* -* Command line functions -* -***/ - -const wchar_t * AppGetCommandLine (); - -#endif From 2e42d76ff20dca29e1d19af743f8133023f2a4a5 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 6 Feb 2015 21:57:28 -0800 Subject: [PATCH 4/9] Added plCmdParser class. --- .../Plasma/NucleusLib/pnUtils/CMakeLists.txt | 6 + .../Plasma/NucleusLib/pnUtils/plCmdParser.cpp | 617 ++++++++++++++++++ .../Plasma/NucleusLib/pnUtils/plCmdParser.h | 136 ++++ Sources/Tests/NucleusTests/CMakeLists.txt | 1 + .../NucleusTests/pnUtilsTest/CMakeLists.txt | 16 + .../pnUtilsTest/test_plCmdParser.cpp | 547 ++++++++++++++++ 6 files changed, 1323 insertions(+) create mode 100644 Sources/Plasma/NucleusLib/pnUtils/plCmdParser.cpp create mode 100644 Sources/Plasma/NucleusLib/pnUtils/plCmdParser.h create mode 100644 Sources/Tests/NucleusTests/pnUtilsTest/CMakeLists.txt create mode 100644 Sources/Tests/NucleusTests/pnUtilsTest/test_plCmdParser.cpp diff --git a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt index 03610c9d..349c2e40 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt +++ b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt @@ -15,6 +15,8 @@ set(pnUtils_HEADERS pnUtSort.h pnUtStr.h pnUtTime.h + + plCmdParser.h ) set(pnUtils_SOURCES @@ -24,9 +26,13 @@ set(pnUtils_SOURCES pnUtList.cpp pnUtStr.cpp pnUtTime.cpp + + plCmdParser.cpp ) add_library(pnUtils STATIC ${pnUtils_HEADERS} ${pnUtils_SOURCES}) +target_link_libraries(pnUtils CoreLib) + source_group("Header Files" FILES ${pnUtils_HEADERS}) source_group("Source Files" FILES ${pnUtils_SOURCES}) diff --git a/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.cpp b/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.cpp new file mode 100644 index 00000000..375d9e10 --- /dev/null +++ b/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.cpp @@ -0,0 +1,617 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +#include "plCmdParser.h" + +#include + +#define WHITESPACE " \"\t\r\n\x1A" +#define FLAGS "-/" +#define SEPARATORS "=:" +#define TOGGLES "+-" +#define ALL WHITESPACE FLAGS SEPARATORS TOGGLES + +#define hsCheckFlagBits(f,c,m) ((f & m)==c) + + +struct plCmdArgData +{ + plCmdArgDef def; + + union { + bool boolVal; + float floatVal; + int32_t intVal; + const char* strVal; + uint32_t uintVal; + } val; + + plString buffer; + size_t nameChars; + bool isSpecified; +}; + +struct plCmdTokenState { + size_t fPendingIndex; + size_t fUnflaggedIndex; +}; + + +class plCmdParserImpl +{ +protected: + plString fProgramName; + std::vector fArgArray; + std::vector fLookupArray; + std::vector fUnflaggedArray; + uint32_t fRequiredCount; + CmdError fError; + + void SetDefaultValue(plCmdArgData& arg); + bool ProcessValue(plCmdTokenState* state, size_t index, const plString& str); + bool TokenizeFlags(plCmdTokenState* state, const plString& str); + bool LookupFlagged(plString& name, size_t* lastIndex, bool force=false) const; + +public: + plCmdParserImpl(const plCmdArgDef* defs, size_t defCount); + + bool Tokenize(plCmdTokenState* state, std::vector& strs); + const plCmdArgData* FindArgByName(const plString& name) const; + const plCmdArgData* FindArgById(size_t id) const; + bool CheckAllRequiredArguments(plCmdTokenState* state); + + const plString GetProgramName() const { return fProgramName; } + + CmdError GetError() const { return fError; } +}; + + +plCmdParserImpl::plCmdParserImpl(const plCmdArgDef* defs, size_t defCount) +{ + size_t loop; + fError = kCmdErrorSuccess; + + // Save the argument definitions + size_t maxId = 0; + size_t unflaggedCount = 0; + + fArgArray.resize(defCount); + + for (loop = 0; loop < defCount; ++loop) { + plCmdArgDef def = defs[loop]; + + // Check whether this argument is flagged + bool flagged = hsCheckFlagBits(def.flags, + kCmdArgFlagged, + kCmdArgMask); + + // Disallow names on unflagged arguments + ASSERT(flagged || !def.name.IsEmpty()); + + // Store the argument data + plCmdArgData& arg = fArgArray[loop]; + arg.def = def; + arg.buffer = ""; + arg.nameChars = def.name.GetSize(); + arg.isSpecified = false; + + SetDefaultValue(arg); + maxId = std::max(maxId, def.id); + + // Track the number of unflagged arguments + if (!flagged) { + ++unflaggedCount; + } + } + + + // Build the id lookup table + size_t idTableSize = std::min(maxId + 1, defCount * 2); + fLookupArray.resize(idTableSize); + + for (loop = 0; loop < defCount; ++loop) { + if (defs[loop].id < idTableSize) { + fLookupArray[defs[loop].id] = loop; + } + } + + + // Build the unflagged array + size_t unflaggedIndex = 0; + fUnflaggedArray.resize(unflaggedCount); + + for (loop = 0; loop < defCount; ++loop) { + bool req = hsCheckFlagBits(defs[loop].flags, + kCmdArgRequired, + kCmdArgMask); + + if (req) { + fUnflaggedArray[unflaggedIndex++] = loop; + } + } + + fRequiredCount = unflaggedIndex; + + for (loop = 0; loop < defCount; ++loop) { + bool flagged = hsCheckFlagBits(defs[loop].flags, + kCmdArgFlagged, + kCmdArgMask); + + bool req = hsCheckFlagBits(defs[loop].flags, + kCmdArgRequired, + kCmdArgMask); + + if (!flagged && !req) { + fUnflaggedArray[unflaggedIndex++] = loop; + } + } +} + + +void plCmdParserImpl::SetDefaultValue(plCmdArgData& arg) +{ + uint32_t argType = arg.def.flags & kCmdTypeMask; + + switch (argType) { + case kCmdTypeBool: + arg.val.boolVal = !hsCheckFlagBits(arg.def.flags, + kCmdBoolSet, + kCmdBoolMask); + break; + + case kCmdTypeInt: + arg.val.intVal = 0; + break; + + case kCmdTypeUint: + arg.val.uintVal = 0; + break; + + case kCmdTypeFloat: + arg.val.floatVal = 0.0f; + break; + + case kCmdTypeString: + arg.val.strVal = ""; + break; + + DEFAULT_FATAL(argType); + } +} + + +bool plCmdParserImpl::Tokenize(plCmdTokenState* state, std::vector& strs) +{ + bool result = true; + + for (auto it = strs.begin(); result && it != strs.end(); ++it) { + if (fProgramName.IsEmpty()) { + fProgramName = *it; + continue; + } + + // If the previous argument is awaiting a value, then use this token + // as the value + if (state->fPendingIndex != size_t(-1)) { + result = ProcessValue(state, state->fPendingIndex, *it); + state->fPendingIndex = size_t(-1); + continue; + } + + // Identify and process flagged parameters + if ((*it).REMatch("[" FLAGS "].+") && TokenizeFlags(state, *it)) { + continue; + } + + // Process unflagged parameters + if (state->fUnflaggedIndex < fUnflaggedArray.size()) { + result = ProcessValue(state, fUnflaggedArray[state->fUnflaggedIndex++], *it); + continue; + } + + // Process invalid parameters + if (!fError) { + fError = kCmdErrorTooManyArgs; + } + result = false; + break; + } + + return result; +} + + +bool plCmdParserImpl::ProcessValue(plCmdTokenState* state, size_t index, const plString& str) +{ + plCmdArgData& arg = fArgArray[index]; + arg.isSpecified = true; + uint32_t argType = arg.def.flags & kCmdTypeMask; + + switch (argType) { + case kCmdTypeBool: + if (str.CompareI("true") == 0) + arg.val.boolVal = true; + else if (str.CompareI("false") == 0) + arg.val.boolVal = false; + else if (str.IsEmpty()) + arg.val.boolVal = hsCheckFlagBits(arg.def.flags, + kCmdBoolSet, + kCmdBoolMask); + else + fError = kCmdErrorInvalidValue; + break; + + case kCmdTypeFloat: + arg.val.floatVal = str.ToFloat(); + break; + + case kCmdTypeInt: + arg.val.intVal = str.ToInt(); + break; + + case kCmdTypeString: + arg.buffer = str; + arg.val.strVal = arg.buffer.c_str(); + break; + + case kCmdTypeUint: + arg.val.uintVal = str.ToUInt(10); + break; + + DEFAULT_FATAL(argType); + + } + return true; +} + +bool plCmdParserImpl::TokenizeFlags(plCmdTokenState* state, const plString& str) +{ + bool result = true; + std::vector tokens = str.Tokenize(ALL); + + for (auto it = tokens.begin(); result && it != tokens.end(); ++it) { + size_t lastIndex = size_t(-1); + plString buffer = *it; + + if (buffer.IsEmpty()) { + continue; + } + + while (result) { + // Lookup the argument name + result = LookupFlagged(buffer, &lastIndex); + if (!result) { + fError = kCmdErrorInvalidArg; + result = false; + } + + break; + } + + if (!result) { + break; + } + + // Check for an argument value provided using a separator + if (str.REMatch(".+[" SEPARATORS "].+") && !(*(++it)).IsEmpty()) { + result = ProcessValue(state, lastIndex, *it); + break; + } + + bool isBool = hsCheckFlagBits(fArgArray[lastIndex].def.flags, + kCmdTypeBool, + kCmdTypeMask); + + // Process values for boolean arguments + if (isBool) { + result = ProcessValue(state, lastIndex, plString::Null); + continue; + } + + // Process values for non-boolean arguments + else { + // Check for an argument value immediately following the name + if (!buffer.IsEmpty()) { + result = ProcessValue(state, lastIndex, buffer); + break; + } + + // Check for an argument value in the next token + else { + state->fPendingIndex = lastIndex; + break; + } + } + } + + return result; +} + +bool plCmdParserImpl::LookupFlagged(plString& name, size_t* lastIndex, bool force) const +{ + size_t argCount = fArgArray.size(); + size_t chars = name.GetSize(); + size_t bestIndex = size_t(-1); + size_t bestChars = 0; + + + size_t prevChars = 0; + if (*lastIndex != size_t(-1)) { + prevChars = fArgArray[*lastIndex].def.name.GetSize(); + } + + for (; prevChars != size_t(-1) && !bestChars; --prevChars) { + // Find this argument in the list + for (size_t index = 0; index < argCount; ++index) { + const plCmdArgData& arg = fArgArray[index]; + + // Ignore non-flagged arguments + bool flagged = hsCheckFlagBits(arg.def.flags, + kCmdArgFlagged, + kCmdArgMask); + if (!flagged && !force) + continue; + + // Ignore this arg if it wouldn't beat the previous best match + if (arg.def.name.GetSize() < bestChars + prevChars) + continue; + + // Ignore this argument if it doesn't match the prefix + bool caseSensitive = hsCheckBits(arg.def.flags, + kCmdCaseSensitive); + + if (prevChars) { + const plCmdArgData& prev = fArgArray[*lastIndex]; + + if (prevChars >= arg.def.name.GetSize()) + continue; + + if (caseSensitive && + arg.def.name.CompareN(prev.def.name, prevChars)) + continue; + + if (!caseSensitive && + arg.def.name.CompareNI(prev.def.name, prevChars)) + continue; + } + + // Ignore this argument if it doesn't match the suffix + plString suffix = arg.def.name.Substr(prevChars); + if (caseSensitive && suffix.CompareN(name, std::min(name.GetSize(), suffix.GetSize()))) + continue; + + if (!caseSensitive && suffix.CompareNI(name, std::min(name.GetSize(), suffix.GetSize()))) + continue; + + // Track the best match + bestIndex = index; + bestChars = arg.def.name.GetSize() - prevChars; + if (bestChars == chars) + break; + } + } + + // Return the result + name = name.Substr(bestChars); + *lastIndex = bestIndex; + return bestChars != 0; +} + +const plCmdArgData* plCmdParserImpl::FindArgByName(const plString& name) const +{ + // Search for an argument with this name + size_t index = size_t(-1); + plString arg = name; + if (!LookupFlagged(arg, &index, true)) { + return nullptr; + } + + // Return the argument data + return &fArgArray[index]; +} + +const plCmdArgData* plCmdParserImpl::FindArgById(size_t id) const +{ + // Search for the argument with this id + size_t index; + if (id < fLookupArray.size()) { + index = fLookupArray[id]; + } else { + for (index = 0; index < fArgArray.size(); ++index) { + if (fArgArray[index].def.id == id) { + break; + } + } + } + + // Verify that we found the correct argument + if ((index >= fArgArray.size()) || (fArgArray[index].def.id != id)) { + return nullptr; + } + + // Return the argument data + return &fArgArray[index]; +} + +bool plCmdParserImpl::CheckAllRequiredArguments(plCmdTokenState* state) +{ + bool result = (state->fUnflaggedIndex >= fRequiredCount); + + if (!result) { + fError = kCmdErrorTooFewArgs; + } + + return result; +} + + + +plCmdParser::plCmdParser(const plCmdArgDef* defs, size_t defCount) +{ + Initialize(defs, defCount); +} + +plCmdParser::~plCmdParser() +{ + delete fParser; +} + +void plCmdParser::Initialize(const plCmdArgDef* defs, size_t defCount) +{ + fParser = new plCmdParserImpl(defs, defCount); +} + +bool plCmdParser::Parse(const plString& cmdLine) +{ + // Process the command line + plCmdTokenState state = { + size_t(-1), // pending index + 0 // unflagged index + }; + + std::vector tokens = cmdLine.Tokenize(WHITESPACE); + + bool result = fParser->Tokenize(&state, tokens); + + if (result) { + result = fParser->CheckAllRequiredArguments(&state); + } + + return result; +} + +bool plCmdParser::Parse(std::vector& argv) +{ + // Process the command line + plCmdTokenState state = { + size_t(-1), // pending index + 0 // unflagged index + }; + + bool result = fParser->Tokenize(&state, argv); + + if (result) { + result = fParser->CheckAllRequiredArguments(&state); + } + + return result; +} + + +const plString plCmdParser::GetProgramName() const +{ + return fParser->GetProgramName(); +} + + +bool plCmdParser::GetBool(size_t id) const +{ + return fParser->FindArgById(id)->val.boolVal; +} + +bool plCmdParser::GetBool(const plString& name) const +{ + return fParser->FindArgByName(name)->val.boolVal; +} + +float plCmdParser::GetFloat(size_t id) const +{ + return fParser->FindArgById(id)->val.floatVal; +} + +float plCmdParser::GetFloat(const plString& name) const +{ + return fParser->FindArgByName(name)->val.floatVal; +} + +int32_t plCmdParser::GetInt(size_t id) const +{ + return fParser->FindArgById(id)->val.intVal; +} + +int32_t plCmdParser::GetInt(const plString& name) const +{ + return fParser->FindArgByName(name)->val.intVal; +} + +const plString plCmdParser::GetString(size_t id) const +{ + return fParser->FindArgById(id)->val.strVal; +} + +const plString plCmdParser::GetString(const plString& name) const +{ + return fParser->FindArgByName(name)->val.strVal; +} + +uint32_t plCmdParser::GetUint(size_t id) const +{ + return fParser->FindArgById(id)->val.uintVal; +} + +uint32_t plCmdParser::GetUint(const plString& name) const +{ + return fParser->FindArgByName(name)->val.uintVal; +} + +bool plCmdParser::IsSpecified(size_t id) const +{ + if (const plCmdArgData* data = fParser->FindArgById(id)) { + return data->isSpecified; + } + + return false; +} + +bool plCmdParser::IsSpecified(const plString& name) const +{ + if (const plCmdArgData* data = fParser->FindArgByName(name)) { + return data->isSpecified; + } + + return false; +} + +CmdError plCmdParser::GetError() const +{ + return fParser->GetError(); +} diff --git a/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.h b/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.h new file mode 100644 index 00000000..8c84a584 --- /dev/null +++ b/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.h @@ -0,0 +1,136 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +#ifndef _plCmdParser_h_ +#define _plCmdParser_h_ + +#include "plString.h" + +enum CmdArg +{ + kCmdArgFlagged = 0x0, // default + kCmdArgOptional = 0x1, + kCmdArgRequired = 0x2, + kCmdArgMask = 0xF +}; + +enum CmdType +{ + kCmdTypeBool = 0x0 << 4, // default + kCmdTypeInt = 0x1 << 4, + kCmdTypeUint = 0x2 << 4, + kCmdTypeFloat = 0x3 << 4, + kCmdTypeString = 0x4 << 4, + kCmdTypeMask = 0xF << 4 +}; + +enum CmdBool +{ + kCmdBoolSet = 0x0 << 8, // default + kCmdBoolUnset = 0x1 << 8, + kCmdBoolMask = 0xF << 8 +}; + +enum CmdCase +{ + kCmdCaseSensitive = 0x1 << 28 +}; + +// Error codes +enum CmdError +{ + kCmdErrorSuccess, + kCmdErrorInvalidArg, + kCmdErrorInvalidValue, + kCmdErrorTooFewArgs, + kCmdErrorTooManyArgs, + kNumCmdErrors +}; + + +struct plCmdArgDef +{ + uint32_t flags; + plString name; // must be compile-time constant + size_t id; +}; + + +class plCmdParser +{ +protected: + class plCmdParserImpl* fParser; + + plCmdParser() : fParser(nullptr) { } + void Initialize(const plCmdArgDef* defs, size_t defCount); + +public: + plCmdParser(const plCmdArgDef* defs, size_t defCount); + virtual ~plCmdParser(); + + bool Parse(const plString& cmdLine); + bool Parse(std::vector& argv); + + const plString GetProgramName() const; + + bool GetBool(size_t id) const; + bool GetBool(const plString& name) const; + + float GetFloat(size_t id) const; + float GetFloat(const plString& name) const; + + int32_t GetInt(size_t id) const; + int32_t GetInt(const plString& name) const; + + const plString GetString(size_t id) const; + const plString GetString(const plString& name) const; + + uint32_t GetUint(size_t id) const; + uint32_t GetUint(const plString& name) const; + + bool IsSpecified(size_t id) const; + bool IsSpecified(const plString& name) const; + + CmdError GetError() const; +}; + +#endif //_plCmdParser_h_ diff --git a/Sources/Tests/NucleusTests/CMakeLists.txt b/Sources/Tests/NucleusTests/CMakeLists.txt index 56df15ee..6abd34a5 100644 --- a/Sources/Tests/NucleusTests/CMakeLists.txt +++ b/Sources/Tests/NucleusTests/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(pnEncryptionTest) +add_subdirectory(pnUtilsTest) diff --git a/Sources/Tests/NucleusTests/pnUtilsTest/CMakeLists.txt b/Sources/Tests/NucleusTests/pnUtilsTest/CMakeLists.txt new file mode 100644 index 00000000..f96fc670 --- /dev/null +++ b/Sources/Tests/NucleusTests/pnUtilsTest/CMakeLists.txt @@ -0,0 +1,16 @@ +include_directories(${GTEST_INCLUDE_DIR}) +include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) +include_directories(../../../Plasma/CoreLib) +include_directories(../../../Plasma/NucleusLib) + +set(pnUtilsTest_SOURCES + test_plCmdParser.cpp + ) + +add_executable(test_pnUtils ${pnUtilsTest_SOURCES}) +target_link_libraries(test_pnUtils gtest gtest_main) +target_link_libraries(test_pnUtils pnUtils) + +add_test(NAME test_pnUtils COMMAND test_pnUtils) +add_dependencies(check test_pnUtils) + diff --git a/Sources/Tests/NucleusTests/pnUtilsTest/test_plCmdParser.cpp b/Sources/Tests/NucleusTests/pnUtilsTest/test_plCmdParser.cpp new file mode 100644 index 00000000..85d28cf9 --- /dev/null +++ b/Sources/Tests/NucleusTests/pnUtilsTest/test_plCmdParser.cpp @@ -0,0 +1,547 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +#include +#include +#include "pnUtils/plCmdParser.h" + +TEST(plCmdParser, basic_parsing) +{ + const plCmdArgDef cmds[] = { + { kCmdArgRequired | kCmdTypeString, "path", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + bool success = parser.Parse("plCmdParser ~/.plasma/config.dat"); + + plString prog = parser.GetProgramName(); + plString path = parser.GetString(0); + + EXPECT_EQ(success, true); + EXPECT_STREQ(prog.c_str(), "plCmdParser"); + EXPECT_STREQ(path.c_str(), "~/.plasma/config.dat"); + EXPECT_EQ(parser.GetError(), kCmdErrorSuccess); +} + +TEST(plCmdParser, argv_parsing) +{ + const plCmdArgDef cmds[] = { + { kCmdArgRequired | kCmdTypeString, "path", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + + const char* args[] = {"plCmdParser", "~/.plasma/config.dat"}; + int argc = 2; + + std::vector tokens(args, args+argc); + + bool success = parser.Parse(tokens); + + plString prog = parser.GetProgramName(); + plString path = parser.GetString(0); + + EXPECT_EQ(success, true); + EXPECT_STREQ(prog.c_str(), "plCmdParser"); + EXPECT_STREQ(path.c_str(), "~/.plasma/config.dat"); + EXPECT_EQ(parser.GetError(), kCmdErrorSuccess); +} + +TEST(plCmdParser, argv_preserving_spaces) +{ + const plCmdArgDef cmds[] = { + { kCmdArgRequired | kCmdTypeString, "path", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + + const char* args[] = {"plCmdParser", "~/.plasma/Uru Live/config.dat"}; + int argc = 2; + + std::vector tokens(args, args+argc); + + bool success = parser.Parse(tokens); + + plString prog = parser.GetProgramName(); + plString path = parser.GetString(0); + + EXPECT_EQ(success, true); + EXPECT_STREQ(prog.c_str(), "plCmdParser"); + EXPECT_STREQ(path.c_str(), "~/.plasma/Uru Live/config.dat"); + EXPECT_EQ(parser.GetError(), kCmdErrorSuccess); +} + +TEST(plCmdParser, wchar_argv_parsing) +{ + const plCmdArgDef cmds[] = { + { kCmdArgRequired | kCmdTypeString, "path", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + + const wchar_t* args[] = {L"plCmdParser", L"~/.plasma/config.dat"}; + int argc = 2; + + std::vector tokens(argc); + for (int i = 0; i < argc; i++) { + tokens.push_back(plString::FromWchar(args[i])); + } + + bool success = parser.Parse(tokens); + + plString prog = parser.GetProgramName(); + plString path = parser.GetString(0); + + EXPECT_EQ(success, true); + EXPECT_STREQ(prog.c_str(), "plCmdParser"); + EXPECT_STREQ(path.c_str(), "~/.plasma/config.dat"); + EXPECT_EQ(parser.GetError(), kCmdErrorSuccess); +} + + +TEST(plCmdParser, flagged_int) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt, "size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --size 5"); + + int32_t size = parser.GetInt(0); + + EXPECT_EQ(size, 5); +} + +TEST(plCmdParser, flagged_int_short) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt, "size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser -s 5"); + + int32_t size = parser.GetInt(0); + + EXPECT_EQ(size, 5); +} + +TEST(plCmdParser, flagged_int_assign) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt, "size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --size=5"); + + int32_t size = parser.GetInt(0); + + EXPECT_EQ(size, 5); +} + +TEST(plCmdParser, flagged_int_slash) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt, "size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser /size -5"); + + int32_t size = parser.GetInt(0); + + EXPECT_EQ(size, -5); +} + +TEST(plCmdParser, flagged_int_bystring) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt, "size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --size 5"); + + int32_t size = parser.GetInt("size"); + + EXPECT_EQ(size, 5); +} + + +TEST(plCmdParser, flagged_uint) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeUint, "size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --size 5"); + + uint32_t size = parser.GetUint(0); + + EXPECT_EQ(size, 5); +} + +TEST(plCmdParser, flagged_uint_bystring) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeUint, "size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --size 5"); + + uint32_t size = parser.GetUint("size"); + + EXPECT_EQ(size, 5); +} + + +TEST(plCmdParser, flagged_float) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeFloat, "volume", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --volume 0.5"); + + float vol = parser.GetFloat(0); + + EXPECT_EQ(vol, 0.5); +} + +TEST(plCmdParser, flagged_float_bystring) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeFloat, "volume", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --volume 0.5"); + + float vol = parser.GetFloat("volume"); + + EXPECT_EQ(vol, 0.5); +} + + +TEST(plCmdParser, flagged_string) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeString, "path", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --path foo"); + + plString path = parser.GetString(0); + + EXPECT_STREQ(path.c_str(), "foo"); +} + +TEST(plCmdParser, flagged_string_bystring) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeString, "path", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --path foo"); + + plString path = parser.GetString("path"); + + EXPECT_STREQ(path.c_str(), "foo"); +} + + +TEST(plCmdParser, flagged_bool_default) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeBool, "verbose", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --verbose"); + + bool verbose = parser.GetBool(0); + + EXPECT_EQ(verbose, true); +} + +TEST(plCmdParser, flagged_bool_true) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeBool, "verbose", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --verbose=TRUE"); + + bool verbose = parser.GetBool(0); + + EXPECT_EQ(verbose, true); +} + +TEST(plCmdParser, flagged_bool_false) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeBool, "verbose", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --verbose=FALSE"); + + bool verbose = parser.GetBool(0); + + EXPECT_EQ(verbose, false); +} + +TEST(plCmdParser, flagged_bool_invalid) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeBool, "verbose", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --verbose=foo"); + + bool verbose = parser.GetBool(0); + + EXPECT_EQ(verbose, false); + EXPECT_EQ(parser.GetError(), kCmdErrorInvalidValue); +} + +TEST(plCmdParser, flagged_bool_bystring) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeBool, "verbose", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --verbose"); + + bool verbose = parser.GetBool("verbose"); + + EXPECT_EQ(verbose, true); +} + + +TEST(plCmdParser, optional_unspecified) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt | kCmdArgOptional, "speed", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser"); + + bool specified = parser.IsSpecified(0); + int32_t speed = parser.GetInt(0); + + EXPECT_EQ(specified, false); + EXPECT_EQ(speed, 0); +} + +TEST(plCmdParser, optional_specified) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt | kCmdArgOptional, "speed", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser 1"); + + bool specified = parser.IsSpecified(0); + int32_t speed = parser.GetInt(0); + + EXPECT_EQ(specified, true); + EXPECT_EQ(speed, 1); +} + +TEST(plCmdParser, optional_specified_bystring) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt | kCmdArgOptional, "speed", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser 1"); + + bool specified = parser.IsSpecified("speed"); + int32_t speed = parser.GetInt("speed"); + + EXPECT_EQ(specified, true); + EXPECT_EQ(speed, 1); +} + + +TEST(plCmdParser, specified_invalid) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt | kCmdArgOptional, "speed", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser 1"); + + bool specified = parser.IsSpecified(1); + + EXPECT_EQ(specified, false); +} + +TEST(plCmdParser, specified_invalid_bystring) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt | kCmdArgOptional, "speed", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser 1"); + + bool specified = parser.IsSpecified("path"); + + EXPECT_EQ(specified, false); +} + + +TEST(plCmdParser, flagged_weird_id) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt, "size", 10} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --size 5"); + + int32_t size = parser.GetInt(10); + + EXPECT_EQ(size, 5); +} + + +TEST(plCmdParser, fake_flag) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt, "size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + bool success = parser.Parse("plCmdParser --speed 5"); + + EXPECT_EQ(success, false); + EXPECT_EQ(parser.GetError(), kCmdErrorInvalidArg); +} + + +TEST(plCmdParser, too_many_args) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt, "size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + bool success = parser.Parse("plCmdParser --size 10 foo"); + + EXPECT_EQ(success, false); + EXPECT_EQ(parser.GetError(), kCmdErrorTooManyArgs); +} + + +TEST(plCmdParser, missing_required) +{ + const plCmdArgDef cmds[] = { + { kCmdArgRequired | kCmdTypeString, "path", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + bool success = parser.Parse("plCmdParser"); + + EXPECT_EQ(success, false); + EXPECT_EQ(parser.GetError(), kCmdErrorTooFewArgs); +} + + +TEST(plCmdParser, combined_assign) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt, "size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser --size5"); + + int32_t size = parser.GetInt(0); + + EXPECT_EQ(size, 5); +} + + +TEST(plCmdParser, case_sensitive_nomatch) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt | kCmdCaseSensitive, "Size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser -s 5"); + + bool specified = parser.IsSpecified(0); + + EXPECT_EQ(specified, false); +} + +TEST(plCmdParser, case_sensitive_match) +{ + const plCmdArgDef cmds[] = { + { kCmdTypeInt | kCmdCaseSensitive, "Size", 0} + }; + + plCmdParser parser(cmds, arrsize(cmds)); + parser.Parse("plCmdParser -S 5"); + + bool specified = parser.IsSpecified(0); + + EXPECT_EQ(specified, true); +} From 47f92ef73dc127b1a135cbdc9ae1fe805a5f0032 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 5 Jun 2015 21:14:51 -0700 Subject: [PATCH 5/9] Remove unused header. --- .../Plasma/NucleusLib/pnUtils/Win32/W32Int.h | 41 ------------------- 1 file changed, 41 deletions(-) delete mode 100644 Sources/Plasma/NucleusLib/pnUtils/Win32/W32Int.h diff --git a/Sources/Plasma/NucleusLib/pnUtils/Win32/W32Int.h b/Sources/Plasma/NucleusLib/pnUtils/Win32/W32Int.h deleted file mode 100644 index 19828919..00000000 --- a/Sources/Plasma/NucleusLib/pnUtils/Win32/W32Int.h +++ /dev/null @@ -1,41 +0,0 @@ -/*==LICENSE==* - -CyanWorlds.com Engine - MMOG client, server and tools -Copyright (C) 2011 Cyan Worlds, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -Additional permissions under GNU GPL version 3 section 7 - -If you modify this Program, or any covered work, by linking or -combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, -NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent -JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK -(or a modified version of those libraries), -containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, -PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG -JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the -licensors of this Program grant you additional -permission to convey the resulting work. Corresponding Source for a -non-source form of such a combination shall include the source code for -the parts of OpenSSL and IJG JPEG Library used as well as that of the covered -work. - -You can contact Cyan Worlds, Inc. by email legal@cyan.com - or by snail mail at: - Cyan Worlds, Inc. - 14617 N Newport Hwy - Mead, WA 99021 - -*==LICENSE==*/ From e801eadc8daedce9c9a31e194cf7308a6ac07387 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 5 Jun 2015 21:59:05 -0700 Subject: [PATCH 6/9] Fix compilation of plCmdParser on Windows. --- Sources/Plasma/NucleusLib/pnUtils/plCmdParser.cpp | 1 + Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.cpp b/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.cpp index 375d9e10..57356a8f 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.cpp +++ b/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.cpp @@ -43,6 +43,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plCmdParser.h" #include +#include #define WHITESPACE " \"\t\r\n\x1A" #define FLAGS "-/" diff --git a/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h b/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h index f36cfd36..9da38868 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h +++ b/Sources/Plasma/NucleusLib/pnUtils/pnUtAllIncludes.h @@ -58,7 +58,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "pnUtPriQ.h" #include "pnUtTime.h" #include "pnUtStr.h" -#include "pnUtMisc.h" #include "pnUtCrypt.h" #endif // PLASMA20_SOURCES_PLASMA_NUCLEUSLIB_PNUTILS_PRIVATE_PNUTALLINCLUDES_H From 24b20b718f444691b2f0db3a5399feff60efdf6b Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 5 Jun 2015 22:00:45 -0700 Subject: [PATCH 7/9] Updated uses of CCmdParser to plCmdParser. --- Sources/Plasma/Apps/plClient/winmain.cpp | 23 ++++++++++----- .../Apps/plUruLauncher/plClientLauncher.cpp | 29 ++++++++++++------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/Sources/Plasma/Apps/plClient/winmain.cpp b/Sources/Plasma/Apps/plClient/winmain.cpp index 0ec2804c..d5d967d8 100644 --- a/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/Sources/Plasma/Apps/plClient/winmain.cpp @@ -66,6 +66,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plProduct.h" #include "plNetGameLib/plNetGameLib.h" #include "plPhysX/plSimulationMgr.h" +#include "pnUtils/plCmdParser.h" #include "res/resource.h" @@ -96,11 +97,11 @@ enum kArgSkipPreload }; -static const CmdArgDef s_cmdLineArgs[] = { - { kCmdArgFlagged | kCmdTypeBool, L"SkipLoginDialog", kArgSkipLoginDialog }, - { kCmdArgFlagged | kCmdTypeString, L"ServerIni", kArgServerIni }, - { kCmdArgFlagged | kCmdTypeBool, L"LocalData", kArgLocalData }, - { kCmdArgFlagged | kCmdTypeBool, L"SkipPreload", kArgSkipPreload }, +static const plCmdArgDef s_cmdLineArgs[] = { + { kCmdArgFlagged | kCmdTypeBool, "SkipLoginDialog", kArgSkipLoginDialog }, + { kCmdArgFlagged | kCmdTypeString, "ServerIni", kArgServerIni }, + { kCmdArgFlagged | kCmdTypeBool, "LocalData", kArgLocalData }, + { kCmdArgFlagged | kCmdTypeBool, "SkipPreload", kArgSkipPreload }, }; /// Made globals now, so we can set them to zero if we take the border and @@ -1132,8 +1133,14 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC // Set global handle gHInst = hInst; - CCmdParser cmdParser(s_cmdLineArgs, arrsize(s_cmdLineArgs)); - cmdParser.Parse(); + std::vector args; + args.reserve(__argc); + for (size_t i = 0; i < __argc; i++) { + args.push_back(plString::FromWchar(__wargv[i])); + } + + plCmdParser cmdParser(s_cmdLineArgs, arrsize(s_cmdLineArgs)); + cmdParser.Parse(args); bool doIntroDialogs = true; #ifndef PLASMA_EXTERNAL_RELEASE @@ -1150,7 +1157,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC plFileName serverIni = "server.ini"; if (cmdParser.IsSpecified(kArgServerIni)) - serverIni = plString::FromWchar(cmdParser.GetString(kArgServerIni)); + serverIni = cmdParser.GetString(kArgServerIni); // check to see if we were launched from the patcher bool eventExists = false; diff --git a/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp b/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp index c7bb7346..a9a53063 100644 --- a/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp +++ b/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp @@ -47,7 +47,8 @@ Mead, WA 99021 #include "hsThread.h" #include "hsTimer.h" -#include "pnUtils/pnUtils.h" // for CCmdParser +#include "pnUtils/pnUtils.h" +#include "pnUtils/plCmdParser.h" #include "pnAsyncCore/pnAsyncCore.h" #include "plNetGameLib/plNetGameLib.h" #include "plStatusLog/plStatusLog.h" @@ -432,21 +433,27 @@ void plClientLauncher::ParseArguments() enum { kArgServerIni, kArgNoSelfPatch, kArgImage, kArgRepairGame, kArgPatchOnly, kArgSkipLoginDialog }; - const CmdArgDef cmdLineArgs[] = { - { kCmdArgFlagged | kCmdTypeString, L"ServerIni", kArgServerIni }, - { kCmdArgFlagged | kCmdTypeBool, L"NoSelfPatch", kArgNoSelfPatch }, - { kCmdArgFlagged | kCmdTypeBool, L"Image", kArgImage }, - { kCmdArgFlagged | kCmdTypeBool, L"Repair", kArgRepairGame }, - { kCmdArgFlagged | kCmdTypeBool, L"PatchOnly", kArgPatchOnly }, - { kCmdArgFlagged | kCmdTypeBool, L"SkipLoginDialog", kArgSkipLoginDialog } + const plCmdArgDef cmdLineArgs[] = { + { kCmdArgFlagged | kCmdTypeString, "ServerIni", kArgServerIni }, + { kCmdArgFlagged | kCmdTypeBool, "NoSelfPatch", kArgNoSelfPatch }, + { kCmdArgFlagged | kCmdTypeBool, "Image", kArgImage }, + { kCmdArgFlagged | kCmdTypeBool, "Repair", kArgRepairGame }, + { kCmdArgFlagged | kCmdTypeBool, "PatchOnly", kArgPatchOnly }, + { kCmdArgFlagged | kCmdTypeBool, "SkipLoginDialog", kArgSkipLoginDialog } }; - CCmdParser cmdParser(cmdLineArgs, arrsize(cmdLineArgs)); - cmdParser.Parse(); + std::vector args; + args.reserve(__argc); + for (size_t i = 0; i < __argc; i++) { + args.push_back(plString::FromWchar(__wargv[i])); + } + + plCmdParser cmdParser(cmdLineArgs, arrsize(cmdLineArgs)); + cmdParser.Parse(args); // cache 'em if (cmdParser.IsSpecified(kArgServerIni)) - fServerIni = plString::FromWchar(cmdParser.GetString(kArgServerIni)); + fServerIni = cmdParser.GetString(kArgServerIni); APPLY_FLAG(kArgNoSelfPatch, kHaveSelfPatched); APPLY_FLAG(kArgImage, kClientImage); APPLY_FLAG(kArgRepairGame, kRepairGame); From 6ba58221171e8bac9282feda1dd67dc3a79c5a64 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Sat, 6 Jun 2015 16:20:16 -0700 Subject: [PATCH 8/9] Move plCmdParser to CoreLib. --- Sources/Plasma/Apps/plClient/winmain.cpp | 2 +- .../Apps/plUruLauncher/plClientLauncher.cpp | 2 +- Sources/Plasma/CoreLib/CMakeLists.txt | 2 ++ .../pnUtils => CoreLib}/plCmdParser.cpp | 0 .../pnUtils => CoreLib}/plCmdParser.h | 0 Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt | 4 ---- Sources/Tests/CoreTests/CMakeLists.txt | 1 + .../test_plCmdParser.cpp | 2 +- Sources/Tests/NucleusTests/CMakeLists.txt | 1 - .../NucleusTests/pnUtilsTest/CMakeLists.txt | 16 ---------------- 10 files changed, 6 insertions(+), 24 deletions(-) rename Sources/Plasma/{NucleusLib/pnUtils => CoreLib}/plCmdParser.cpp (100%) rename Sources/Plasma/{NucleusLib/pnUtils => CoreLib}/plCmdParser.h (100%) rename Sources/Tests/{NucleusTests/pnUtilsTest => CoreTests}/test_plCmdParser.cpp (99%) delete mode 100644 Sources/Tests/NucleusTests/pnUtilsTest/CMakeLists.txt diff --git a/Sources/Plasma/Apps/plClient/winmain.cpp b/Sources/Plasma/Apps/plClient/winmain.cpp index d5d967d8..0b37e3a9 100644 --- a/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/Sources/Plasma/Apps/plClient/winmain.cpp @@ -50,6 +50,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include #include "hsStream.h" +#include "plCmdParser.h" #include "plClient.h" #include "plClientResMgr/plClientResMgr.h" #include "pfCrashHandler/plCrashCli.h" @@ -66,7 +67,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plProduct.h" #include "plNetGameLib/plNetGameLib.h" #include "plPhysX/plSimulationMgr.h" -#include "pnUtils/plCmdParser.h" #include "res/resource.h" diff --git a/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp b/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp index a9a53063..40e678d0 100644 --- a/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp +++ b/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp @@ -46,9 +46,9 @@ Mead, WA 99021 #include "plProduct.h" #include "hsThread.h" #include "hsTimer.h" +#include "plCmdParser.h" #include "pnUtils/pnUtils.h" -#include "pnUtils/plCmdParser.h" #include "pnAsyncCore/pnAsyncCore.h" #include "plNetGameLib/plNetGameLib.h" #include "plStatusLog/plStatusLog.h" diff --git a/Sources/Plasma/CoreLib/CMakeLists.txt b/Sources/Plasma/CoreLib/CMakeLists.txt index 8de8b9e2..21abff68 100644 --- a/Sources/Plasma/CoreLib/CMakeLists.txt +++ b/Sources/Plasma/CoreLib/CMakeLists.txt @@ -28,6 +28,7 @@ set(CoreLib_SOURCES hsTemplates.cpp hsWide.cpp pcSmallRect.cpp + plCmdParser.cpp plFileSystem.cpp plFormat.cpp plGeneric.cpp @@ -74,6 +75,7 @@ set(CoreLib_HEADERS hsWide.h hsWindows.h pcSmallRect.h + plCmdParser.h plFileSystem.h plFormat.h plGeneric.h diff --git a/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.cpp b/Sources/Plasma/CoreLib/plCmdParser.cpp similarity index 100% rename from Sources/Plasma/NucleusLib/pnUtils/plCmdParser.cpp rename to Sources/Plasma/CoreLib/plCmdParser.cpp diff --git a/Sources/Plasma/NucleusLib/pnUtils/plCmdParser.h b/Sources/Plasma/CoreLib/plCmdParser.h similarity index 100% rename from Sources/Plasma/NucleusLib/pnUtils/plCmdParser.h rename to Sources/Plasma/CoreLib/plCmdParser.h diff --git a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt index 349c2e40..80612e1c 100644 --- a/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt +++ b/Sources/Plasma/NucleusLib/pnUtils/CMakeLists.txt @@ -15,8 +15,6 @@ set(pnUtils_HEADERS pnUtSort.h pnUtStr.h pnUtTime.h - - plCmdParser.h ) set(pnUtils_SOURCES @@ -26,8 +24,6 @@ set(pnUtils_SOURCES pnUtList.cpp pnUtStr.cpp pnUtTime.cpp - - plCmdParser.cpp ) add_library(pnUtils STATIC ${pnUtils_HEADERS} ${pnUtils_SOURCES}) diff --git a/Sources/Tests/CoreTests/CMakeLists.txt b/Sources/Tests/CoreTests/CMakeLists.txt index 3f58acdd..c10e7796 100644 --- a/Sources/Tests/CoreTests/CMakeLists.txt +++ b/Sources/Tests/CoreTests/CMakeLists.txt @@ -4,6 +4,7 @@ include_directories(../../Plasma/CoreLib) SET(CoreLibTest_SOURCES test_plString.cpp + test_plCmdParser.cpp ) add_executable(test_CoreLib ${CoreLibTest_SOURCES}) diff --git a/Sources/Tests/NucleusTests/pnUtilsTest/test_plCmdParser.cpp b/Sources/Tests/CoreTests/test_plCmdParser.cpp similarity index 99% rename from Sources/Tests/NucleusTests/pnUtilsTest/test_plCmdParser.cpp rename to Sources/Tests/CoreTests/test_plCmdParser.cpp index 85d28cf9..e0df9fc1 100644 --- a/Sources/Tests/NucleusTests/pnUtilsTest/test_plCmdParser.cpp +++ b/Sources/Tests/CoreTests/test_plCmdParser.cpp @@ -42,7 +42,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include #include -#include "pnUtils/plCmdParser.h" +#include "plCmdParser.h" TEST(plCmdParser, basic_parsing) { diff --git a/Sources/Tests/NucleusTests/CMakeLists.txt b/Sources/Tests/NucleusTests/CMakeLists.txt index 6abd34a5..56df15ee 100644 --- a/Sources/Tests/NucleusTests/CMakeLists.txt +++ b/Sources/Tests/NucleusTests/CMakeLists.txt @@ -1,2 +1 @@ add_subdirectory(pnEncryptionTest) -add_subdirectory(pnUtilsTest) diff --git a/Sources/Tests/NucleusTests/pnUtilsTest/CMakeLists.txt b/Sources/Tests/NucleusTests/pnUtilsTest/CMakeLists.txt deleted file mode 100644 index f96fc670..00000000 --- a/Sources/Tests/NucleusTests/pnUtilsTest/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -include_directories(${GTEST_INCLUDE_DIR}) -include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) -include_directories(../../../Plasma/CoreLib) -include_directories(../../../Plasma/NucleusLib) - -set(pnUtilsTest_SOURCES - test_plCmdParser.cpp - ) - -add_executable(test_pnUtils ${pnUtilsTest_SOURCES}) -target_link_libraries(test_pnUtils gtest gtest_main) -target_link_libraries(test_pnUtils pnUtils) - -add_test(NAME test_pnUtils COMMAND test_pnUtils) -add_dependencies(check test_pnUtils) - From d04dc64bd9afd855fed411cf5573450efbda2a75 Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Sun, 7 Jun 2015 19:38:01 -0700 Subject: [PATCH 9/9] Fix Access Violation due to __wargv. --- Sources/Plasma/Apps/plClient/winmain.cpp | 2 +- Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Plasma/Apps/plClient/winmain.cpp b/Sources/Plasma/Apps/plClient/winmain.cpp index 0b37e3a9..458d5b6d 100644 --- a/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/Sources/Plasma/Apps/plClient/winmain.cpp @@ -1136,7 +1136,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC std::vector args; args.reserve(__argc); for (size_t i = 0; i < __argc; i++) { - args.push_back(plString::FromWchar(__wargv[i])); + args.push_back(plString::FromUtf8(__argv[i])); } plCmdParser cmdParser(s_cmdLineArgs, arrsize(s_cmdLineArgs)); diff --git a/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp b/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp index 40e678d0..f2ae1866 100644 --- a/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp +++ b/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp @@ -445,7 +445,7 @@ void plClientLauncher::ParseArguments() std::vector args; args.reserve(__argc); for (size_t i = 0; i < __argc; i++) { - args.push_back(plString::FromWchar(__wargv[i])); + args.push_back(plString::FromUtf8(__argv[i])); } plCmdParser cmdParser(cmdLineArgs, arrsize(cmdLineArgs));