2015-09-06 20:19:09 +02:00
|
|
|
#include "./commandlineutils.h"
|
2015-06-24 00:44:16 +02:00
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <iostream>
|
|
|
|
|
2015-09-01 20:05:38 +02:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2016-07-03 22:36:48 +02:00
|
|
|
# include <windows.h>
|
|
|
|
# include <fcntl.h>
|
2015-09-01 20:05:38 +02:00
|
|
|
#endif
|
|
|
|
|
2015-06-24 00:44:16 +02:00
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
namespace ApplicationUtilities {
|
|
|
|
|
2015-09-01 20:05:38 +02:00
|
|
|
/*!
|
|
|
|
* \brief Prompts for confirmation displaying the specified \a message.
|
|
|
|
*/
|
2015-06-24 00:44:16 +02:00
|
|
|
bool confirmPrompt(const char *message, Response defaultResponse)
|
|
|
|
{
|
|
|
|
cout << message;
|
|
|
|
cout << ' ' << '[';
|
|
|
|
cout << (defaultResponse == Response::Yes ? 'Y' : 'y');
|
|
|
|
cout << '/' << (defaultResponse == Response::No ? 'N' : 'n');
|
|
|
|
cout << ']' << ' ';
|
|
|
|
cout.flush();
|
|
|
|
for(string line; ;) {
|
|
|
|
getline(cin, line);
|
|
|
|
if(line == "y" || line == "Y" || (defaultResponse == Response::Yes && line.empty())) {
|
|
|
|
return true;
|
|
|
|
} else if(line == "n" || line == "N" || (defaultResponse == Response::No && line.empty())) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
cout << "Please enter [y] or [n]: ";
|
|
|
|
cout.flush();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-01 20:26:56 +02:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2015-09-01 20:05:38 +02:00
|
|
|
/*!
|
2016-12-24 16:08:09 +01:00
|
|
|
* \brief Starts the console and sets the console output code page to UTF-8 if this is configured.
|
2016-12-15 22:59:37 +01:00
|
|
|
* \remarks This method is only available on Windows and used to start a console from a GUI application.
|
2015-09-01 20:05:38 +02:00
|
|
|
*/
|
|
|
|
void startConsole()
|
|
|
|
{
|
|
|
|
AttachConsole(ATTACH_PARENT_PROCESS);
|
|
|
|
CONSOLE_SCREEN_BUFFER_INFO coninfo;
|
|
|
|
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
|
|
|
|
coninfo.dwSize.X = 200;
|
|
|
|
coninfo.dwSize.Y = 500;
|
|
|
|
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
|
|
|
|
// redirect stdout
|
|
|
|
auto stdHandle = reinterpret_cast<intptr_t>(GetStdHandle(STD_OUTPUT_HANDLE));
|
|
|
|
auto conHandle = _open_osfhandle(stdHandle, _O_TEXT);
|
|
|
|
auto fp = _fdopen(conHandle, "w");
|
|
|
|
*stdout = *fp;
|
|
|
|
setvbuf(stdout, NULL, _IONBF, 0);
|
|
|
|
// redirect stdin
|
|
|
|
stdHandle = reinterpret_cast<intptr_t>(GetStdHandle(STD_INPUT_HANDLE));
|
|
|
|
conHandle = _open_osfhandle(stdHandle, _O_TEXT);
|
|
|
|
fp = _fdopen(conHandle, "r");
|
|
|
|
*stdin = *fp;
|
|
|
|
setvbuf(stdin, NULL, _IONBF, 0);
|
|
|
|
// redirect stderr
|
|
|
|
stdHandle = reinterpret_cast<intptr_t>(GetStdHandle(STD_ERROR_HANDLE));
|
|
|
|
conHandle = _open_osfhandle(stdHandle, _O_TEXT);
|
|
|
|
fp = _fdopen(conHandle, "w");
|
|
|
|
*stderr = *fp;
|
|
|
|
setvbuf(stderr, NULL, _IONBF, 0);
|
2016-12-24 16:08:09 +01:00
|
|
|
#ifdef CPP_UTILITIES_FORCE_UTF8_CODEPAGE
|
2016-12-15 22:59:37 +01:00
|
|
|
// set console to handle UTF-8 IO correctly
|
|
|
|
SetConsoleCP(CP_UTF8);
|
|
|
|
SetConsoleOutputCP(CP_UTF8);
|
2016-12-24 16:08:09 +01:00
|
|
|
#endif
|
2015-09-01 20:05:38 +02:00
|
|
|
// sync
|
|
|
|
ios::sync_with_stdio(true);
|
|
|
|
}
|
2016-12-18 17:19:57 +01:00
|
|
|
|
2017-02-12 00:17:33 +01:00
|
|
|
#ifdef PLATFORM_UNIX
|
|
|
|
/*!
|
|
|
|
* \brief Executes the specified \a app with the specified \a args.
|
|
|
|
* \param app Specifies the null-terminated application path.
|
|
|
|
* \param args Specifies the arguments as null-terminated array of null-terminated strings.
|
|
|
|
* \param outstring Specifies a string to save the standard output.
|
|
|
|
* \param errstring Specifies a string to save the standard error.
|
|
|
|
* \param outstream Specifies a stream to forward the standard output.
|
|
|
|
* \param errstream Specifies a stream to forward the standard error.
|
|
|
|
* \return Returns the return code.
|
|
|
|
* \throws Throws a std::runtime_error in case an error occurs.
|
|
|
|
*/
|
|
|
|
int execApp(const char *app, const char *const *args, string *outstring, string *errstring, ostream *outstream, ostream *errstream)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-12-18 17:19:57 +01:00
|
|
|
/*!
|
|
|
|
* \brief Convert command line arguments to UTF-8.
|
|
|
|
* \remarks Only available on Windows (on other platforms we can assume passed arguments are already UTF-8 encoded).
|
|
|
|
*/
|
|
|
|
pair<vector<unique_ptr<char[]> >, vector<char *> > convertArgsToUtf8()
|
|
|
|
{
|
|
|
|
pair<vector<unique_ptr<char[]> >, vector<char *> > res;
|
|
|
|
int argc;
|
|
|
|
|
|
|
|
LPWSTR *argv_w = CommandLineToArgvW(GetCommandLineW(), &argc);
|
|
|
|
if(!argv_w || argc <= 0) {
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
res.first.reserve(static_cast<size_t>(argc));
|
|
|
|
res.second.reserve(static_cast<size_t>(argc));
|
|
|
|
for(; argv_w; ++argv_w) {
|
|
|
|
int requiredSize = WideCharToMultiByte(CP_UTF8, 0, *argv_w, -1, nullptr, 0, 0, 0);
|
|
|
|
if(requiredSize <= 0) {
|
|
|
|
break; // just stop on error
|
|
|
|
}
|
|
|
|
|
|
|
|
auto argv = make_unique<char[]>(static_cast<size_t>(requiredSize));
|
|
|
|
requiredSize = WideCharToMultiByte(CP_UTF8, 0, *argv_w, -1, argv.get(), requiredSize, 0, 0);
|
|
|
|
if(requiredSize <= 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
res.second.emplace_back(argv.get());
|
|
|
|
res.first.emplace_back(move(argv));
|
|
|
|
}
|
|
|
|
|
|
|
|
LocalFree(argv_w);
|
|
|
|
return res;
|
|
|
|
}
|
2015-09-01 20:26:56 +02:00
|
|
|
#endif
|
2015-06-24 00:44:16 +02:00
|
|
|
|
2015-09-01 20:05:38 +02:00
|
|
|
} // namespace ApplicationUtilities
|