Subversion Repositories spk

Rev

Rev 341 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
303 cycrow 1
#pragma once
2
 
3
#include "WString.h"
4
#include "WStringList.h"
5
#include "../File_IO.h"
6
#include "../DirIO.h"
7
 
328 cycrow 8
#include <set>
9
 
319 cycrow 10
#ifdef _WIN32
11
#include <windows.h>
12
#include <direct.h>
13
#include <shlobj.h>
14
#else
15
#include <dirent.h> 
16
#include <sys/types.h> 
17
#include <sys/param.h> 
18
#include <sys/stat.h> 
19
#include <unistd.h> 
20
#endif
21
 
303 cycrow 22
namespace Utils
23
{
24
	class CommandLine
25
	{
26
	private:
27
		std::shared_ptr<CFileIO> _file;
319 cycrow 28
		Utils::WStringList		_options;
29
		CDirIO 					_myDoc;
30
		CDirIO 					_tempDir;
303 cycrow 31
		std::vector<Utils::WString> _args;
328 cycrow 32
		std::set<unsigned char> _flags;
319 cycrow 33
		CPackages				_p;
303 cycrow 34
 
35
	public:
328 cycrow 36
		CommandLine(int argc, char* argv[], bool doFlags = false)
303 cycrow 37
		{
38
			_file = std::make_shared<CFileIO>(argv[0]);
39
 
40
			for (int i = 1; i < argc; i++)
41
			{
42
				Utils::WString arg(argv[i]);
344 cycrow 43
				doCommandLine(arg, doFlags);
303 cycrow 44
			}
309 cycrow 45
 
344 cycrow 46
			finaliseCommandLine();
47
		}
48
		CommandLine(int argc, wchar_t* argv[], bool doFlags = false)
49
		{
50
			_file = std::make_shared<CFileIO>(argv[0]);
319 cycrow 51
 
344 cycrow 52
			for (int i = 1; i < argc; i++)
319 cycrow 53
			{
344 cycrow 54
				Utils::WString arg(argv[i]);
55
				doCommandLine(arg, doFlags);
319 cycrow 56
			}
57
 
344 cycrow 58
			finaliseCommandLine();
303 cycrow 59
		}
60
 
61
		const std::shared_ptr<CFileIO> file() const
62
		{
63
			return _file;
64
		}
65
 
66
		const Utils::WString& cmdName() const
67
		{
68
			return _file->filename();
69
		}
70
 
71
		const Utils::WString& cmdDir() const
72
		{
73
			return _file->dir();
74
		}
75
 
319 cycrow 76
		const Utils::WString& tempDir() const
77
		{
78
			return _tempDir.dir();
79
		}
80
 
81
		const Utils::WString& myDoc() const
82
		{
83
			return _myDoc.dir();
84
		}
85
 
303 cycrow 86
		const Utils::WStringList options() const
87
		{
88
			return _options;
89
		}
90
 
91
		const std::vector<Utils::WString>& args() const
92
		{
93
			return _args;
94
		}
95
 
96
		size_t argCount() const
97
		{
98
			return _args.size();
99
		}
100
 
101
		Utils::WString arg(size_t i) const
102
		{
103
			if(i >= _args.size())
104
				return Utils::WString::Null();
105
			return _args[i];
106
		}
107
 
108
		bool hasSwitch(const Utils::WString& s) const
109
		{
110
			return _options.contains(s);
111
		}
328 cycrow 112
		bool hasFlag(unsigned char s) const
113
		{
114
			return _flags.find(s) != _flags.end();
115
		}
303 cycrow 116
 
117
		Utils::WString switchData(const Utils::WString& s) const
118
		{
119
			if (_options.contains(s))
120
				return _options[s]->data;
121
			return Utils::WString::Null();
122
		}
319 cycrow 123
 
124
		const CPackages& packages() const
125
		{
126
			return _p;
127
		}
128
 
328 cycrow 129
		CPackages& packages()
130
		{
131
			return _p;
132
		}
133
 
319 cycrow 134
		const CDirIO& dirIO() const
135
		{
136
			return _file->dirIO();
137
		}
324 cycrow 138
 
139
		Utils::WString fullFilename(const Utils::WString& s) const
140
		{
141
			return (s.contains(L":")) ? s : _file->dirIO().file(s);
142
		}
344 cycrow 143
 
144
	private:
145
		void doCommandLine(Utils::WString& arg, bool doFlags)
146
		{
147
			if (arg.startsWith(L"--"))
148
			{
149
				arg = arg.substr(2);
150
 
151
				if (arg.contains(L":"))
152
				{
153
					Utils::WString a = arg.token(L":", 1);
154
					Utils::WString b = arg.tokens(L":", 2);
155
					_options.pushBack(a, b);
156
				}
157
				else
158
					_options.pushBack(arg);
159
			}
160
			else
161
			{
162
				if (doFlags)
163
				{
164
					if (arg.startsWith(L"-") && !arg.startsWith(L"--"))
165
					{
166
						Utils::WString flags = arg.substr(1);
167
						for (size_t is = 0; is < flags.length(); is++)
168
						{
169
							unsigned char flag = std::toupper(flags[static_cast<int>(is)]);
170
							if (flag >= 'a' && flag <= 'z')
171
								flag -= 32; // convert to uppercase
172
							if (flag >= 'A' && flag <= 'Z')
173
							{
174
								if (_flags.size() < 256)
175
									_flags.insert(flag);
176
								else
177
									wprintf(L"Warning: Too many flags, ignoring %c\n", flag);
178
							}
179
						}
180
						return;
181
					}
182
				}
183
				_args.push_back(arg);
184
			}
185
		}
186
 
187
		void finaliseCommandLine()
188
		{
189
			if (_file->dir().empty() || !_file->dir().contains("/"))
190
			{
191
				Utils::WString d;
192
#ifdef _WIN32
193
				d = Utils::WString(_getcwd(NULL, 0));
194
#else
195
				d = Utils::WString(getcwd(NULL, 0));
196
#endif
197
				if (d.empty())
198
					d = L"./";
199
				_file->setDir(d);
200
			}
201
 
202
			Utils::WString myDoc = L".";
203
#ifdef _WIN32
204
			TCHAR pszPath[MAX_PATH];
205
			if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, pszPath)))
206
			{
207
				myDoc = pszPath;
208
			}
209
#endif
210
			_myDoc.setDir(myDoc);
211
			_tempDir.setDir(L".");
212
 
213
#ifdef _WIN32
214
			TCHAR szPath[MAX_PATH + 1];
215
			DWORD result = GetTempPath(MAX_PATH + 1, szPath);
216
			if (result > 0)
217
				_tempDir.setDir(szPath);
218
#endif
219
 
220
			_p.startup(L".", _tempDir.dir(), _myDoc.dir());
221
		}
303 cycrow 222
	};
223
}