summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bx/src/commandline.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bx/src/commandline.cpp')
-rw-r--r--3rdparty/bx/src/commandline.cpp322
1 files changed, 322 insertions, 0 deletions
diff --git a/3rdparty/bx/src/commandline.cpp b/3rdparty/bx/src/commandline.cpp
new file mode 100644
index 00000000000..400e4965a0e
--- /dev/null
+++ b/3rdparty/bx/src/commandline.cpp
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#include <bx/commandline.h>
+#include <bx/string.h>
+
+namespace bx
+{
+ // Reference:
+ // http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
+ const char* tokenizeCommandLine(const char* _commandLine, char* _buffer, uint32_t& _bufferSize, int32_t& _argc, char* _argv[], int32_t _maxArgvs, char _term)
+ {
+ int32_t argc = 0;
+ const char* curr = _commandLine;
+ char* currOut = _buffer;
+ char term = ' ';
+ bool sub = false;
+
+ enum ParserState
+ {
+ SkipWhitespace,
+ SetTerm,
+ Copy,
+ Escape,
+ End,
+ };
+
+ ParserState state = SkipWhitespace;
+
+ while ('\0' != *curr
+ && _term != *curr
+ && argc < _maxArgvs)
+ {
+ switch (state)
+ {
+ case SkipWhitespace:
+ for (; isSpace(*curr); ++curr) {}; // skip whitespace
+ state = SetTerm;
+ break;
+
+ case SetTerm:
+ if ('"' == *curr)
+ {
+ term = '"';
+ ++curr; // skip begining quote
+ }
+ else
+ {
+ term = ' ';
+ }
+
+ _argv[argc] = currOut;
+ ++argc;
+
+ state = Copy;
+ break;
+
+ case Copy:
+ if ('\\' == *curr)
+ {
+ state = Escape;
+ }
+ else if ('"' == *curr
+ && '"' != term)
+ {
+ sub = !sub;
+ }
+ else if (isSpace(*curr) && !sub)
+ {
+ state = End;
+ }
+ else if (term != *curr || sub)
+ {
+ *currOut = *curr;
+ ++currOut;
+ }
+ else
+ {
+ state = End;
+ }
+ ++curr;
+ break;
+
+ case Escape:
+ {
+ const char* start = --curr;
+ for (; '\\' == *curr; ++curr) {};
+
+ if ('"' != *curr)
+ {
+ int32_t count = (int32_t)(curr-start);
+
+ curr = start;
+ for (int32_t ii = 0; ii < count; ++ii)
+ {
+ *currOut = *curr;
+ ++currOut;
+ ++curr;
+ }
+ }
+ else
+ {
+ curr = start+1;
+ *currOut = *curr;
+ ++currOut;
+ ++curr;
+ }
+ }
+ state = Copy;
+ break;
+
+ case End:
+ *currOut = '\0';
+ ++currOut;
+ state = SkipWhitespace;
+ break;
+ }
+ }
+
+ *currOut = '\0';
+ if (0 < argc
+ && '\0' == _argv[argc-1][0])
+ {
+ --argc;
+ }
+
+ _bufferSize = (uint32_t)(currOut - _buffer);
+ _argc = argc;
+
+ if ('\0' != *curr)
+ {
+ ++curr;
+ }
+
+ return curr;
+ }
+
+ CommandLine::CommandLine(int32_t _argc, char const* const* _argv)
+ : m_argc(_argc)
+ , m_argv(_argv)
+ {
+ }
+
+ const char* CommandLine::findOption(const char* _long, const char* _default) const
+ {
+ const char* result = find(0, '\0', _long, 1);
+ return result == NULL ? _default : result;
+ }
+
+ const char* CommandLine::findOption(const char _short, const char* _long, const char* _default) const
+ {
+ const char* result = find(0, _short, _long, 1);
+ return result == NULL ? _default : result;
+ }
+
+ const char* CommandLine::findOption(const char* _long, int32_t _numParams) const
+ {
+ const char* result = find(0, '\0', _long, _numParams);
+ return result;
+ }
+
+ const char* CommandLine::findOption(const char _short, const char* _long, int32_t _numParams) const
+ {
+ const char* result = find(0, _short, _long, _numParams);
+ return result;
+ }
+
+ const char* CommandLine::findOption(int32_t _skip, const char _short, const char* _long, int32_t _numParams) const
+ {
+ const char* result = find(_skip, _short, _long, _numParams);
+ return result;
+ }
+
+ bool CommandLine::hasArg(const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 0);
+ return NULL != arg;
+ }
+
+ bool CommandLine::hasArg(const char* _long) const
+ {
+ const char* arg = findOption('\0', _long, 0);
+ return NULL != arg;
+ }
+
+ bool CommandLine::hasArg(const char*& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ _value = arg;
+ return NULL != arg;
+ }
+
+ bool CommandLine::hasArg(int32_t& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ if (NULL != arg)
+ {
+ _value = atoi(arg);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool CommandLine::hasArg(uint32_t& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ if (NULL != arg)
+ {
+ _value = atoi(arg);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool CommandLine::hasArg(float& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ if (NULL != arg)
+ {
+ _value = float(atof(arg));
+ return true;
+ }
+
+ return false;
+ }
+
+ bool CommandLine::hasArg(double& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ if (NULL != arg)
+ {
+ _value = atof(arg);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool CommandLine::hasArg(bool& _value, const char _short, const char* _long) const
+ {
+ const char* arg = findOption(_short, _long, 1);
+ if (NULL != arg)
+ {
+ if ('0' == *arg || (0 == strincmp(arg, "false") ) )
+ {
+ _value = false;
+ }
+ else if ('0' != *arg || (0 == strincmp(arg, "true") ) )
+ {
+ _value = true;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ const char* CommandLine::find(int32_t _skip, const char _short, const char* _long, int32_t _numParams) const
+ {
+ for (int32_t ii = 0; ii < m_argc; ++ii)
+ {
+ const char* arg = m_argv[ii];
+ if ('-' == *arg)
+ {
+ ++arg;
+ if (_short == *arg)
+ {
+ if (1 == strnlen(arg) )
+ {
+ if (0 == _skip)
+ {
+ if (0 == _numParams)
+ {
+ return "";
+ }
+ else if (ii+_numParams < m_argc
+ && '-' != *m_argv[ii+1] )
+ {
+ return m_argv[ii+1];
+ }
+
+ return NULL;
+ }
+
+ --_skip;
+ ii += _numParams;
+ }
+ }
+ else if (NULL != _long
+ && '-' == *arg
+ && 0 == strincmp(arg+1, _long) )
+ {
+ if (0 == _skip)
+ {
+ if (0 == _numParams)
+ {
+ return "";
+ }
+ else if (ii+_numParams < m_argc
+ && '-' != *m_argv[ii+1] )
+ {
+ return m_argv[ii+1];
+ }
+
+ return NULL;
+ }
+
+ --_skip;
+ ii += _numParams;
+ }
+ }
+ }
+
+ return NULL;
+ }
+
+} // namespace bx