Subversion Repositories spk

Rev

Rev 324 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#pragma once

#include "WString.h"
#include "WStringList.h"
#include "../File_IO.h"
#include "../DirIO.h"

#include <set>

#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#include <shlobj.h>
#else
#include <dirent.h> 
#include <sys/types.h> 
#include <sys/param.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#endif

namespace Utils
{
        class CommandLine
        {
        private:
                std::shared_ptr<CFileIO> _file;
                Utils::WStringList              _options;
                CDirIO                                  _myDoc;
                CDirIO                                  _tempDir;
                std::vector<Utils::WString> _args;
                std::set<unsigned char> _flags;
                CPackages                               _p;

        public:
                CommandLine(int argc, char* argv[], bool doFlags = false)
                {
                        _file = std::make_shared<CFileIO>(argv[0]);

                        for (int i = 1; i < argc; i++)
                        {
                                Utils::WString arg(argv[i]);
                                if (arg.startsWith(L"--"))
                                {
                                        arg = arg.substr(2);

                                        if (arg.contains(L":"))
                                        {
                                                Utils::WString a = arg.token(L":", 1);
                                                Utils::WString b = arg.tokens(L":", 2);
                                                _options.pushBack(a, b);
                                        }
                                        else
                                                _options.pushBack(arg);
                                }
                                else
                                {
                                        if (doFlags)
                                        {
                                                if (arg.startsWith(L"-") && !arg.startsWith(L"--"))
                                                {
                                                        Utils::WString flags = arg.substr(1);
                                                        for(int is = 0; is < flags.length(); is++)
                                                        {
                                                                unsigned char flag = std::toupper(flags[is]);
                                                                if (flag >= 'a' && flag <= 'z')
                                                                        flag -= 32; // convert to uppercase
                                                                if (flag >= 'A' && flag <= 'Z')
                                                                {
                                                                        if (_flags.size() < 256)
                                                                                _flags.insert(flag);
                                                                        else
                                                                                wprintf(L"Warning: Too many flags, ignoring %c\n", flag);
                                                                }
                                                        }
                                                        continue;
                                                }
                                        }
                                        _args.push_back(arg);
                                }
                        }

                        if (_file->dir().empty() || !_file->dir().contains("/"))
                        {
                                Utils::WString d;
#ifdef _WIN32
                                d = Utils::WString(_getcwd(NULL, 0));
#else
                                d = Utils::WString(getcwd(NULL, 0));
#endif
                                if (d.empty())
                                        d = L"./";
                                _file->setDir(d);
                        }

                        Utils::WString myDoc = L".";
#ifdef _WIN32
                        TCHAR pszPath[MAX_PATH];
                        if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, pszPath)))
                        {
                                myDoc = pszPath;
                        }
#endif
                        _myDoc.setDir(myDoc);
                        _tempDir.setDir(L".");

#ifdef _WIN32
                        TCHAR szPath[MAX_PATH + 1];
                        DWORD result = GetTempPath(MAX_PATH + 1, szPath);
                        if (result > 0)
                                _tempDir.setDir(szPath);
#endif

                        _p.startup(L".", _tempDir.dir(), _myDoc.dir());
                }

                const std::shared_ptr<CFileIO> file() const
                {
                        return _file;
                }

                const Utils::WString& cmdName() const
                {
                        return _file->filename();
                }

                const Utils::WString& cmdDir() const
                {
                        return _file->dir();
                }

                const Utils::WString& tempDir() const
                {
                        return _tempDir.dir();
                }

                const Utils::WString& myDoc() const
                {
                        return _myDoc.dir();
                }

                const Utils::WStringList options() const
                {
                        return _options;
                }

                const std::vector<Utils::WString>& args() const
                {
                        return _args;
                }

                size_t argCount() const
                {
                        return _args.size();
                }

                Utils::WString arg(size_t i) const
                {
                        if(i >= _args.size())
                                return Utils::WString::Null();
                        return _args[i];
                }

                bool hasSwitch(const Utils::WString& s) const
                {
                        return _options.contains(s);
                }
                bool hasFlag(unsigned char s) const
                {
                        return _flags.find(s) != _flags.end();
                }

                Utils::WString switchData(const Utils::WString& s) const
                {
                        if (_options.contains(s))
                                return _options[s]->data;
                        return Utils::WString::Null();
                }

                const CPackages& packages() const
                {
                        return _p;
                }

                CPackages& packages()
                {
                        return _p;
                }

                const CDirIO& dirIO() const
                {
                        return _file->dirIO();
                }

                Utils::WString fullFilename(const Utils::WString& s) const
                {
                        return (s.contains(L":")) ? s : _file->dirIO().file(s);
                }
        };
}