C++ Utilities  4.6.1
Common C++ classes and routines used by my applications such as argument parser, IO and conversion utilities
commandlineutils.cpp
Go to the documentation of this file.
1 #include "./commandlineutils.h"
2 
3 #include <string>
4 #include <iostream>
5 
6 #ifdef PLATFORM_WINDOWS
7 # include <windows.h>
8 # include <fcntl.h>
9 #endif
10 
11 using namespace std;
12 
13 namespace ApplicationUtilities {
14 
18 bool confirmPrompt(const char *message, Response defaultResponse)
19 {
20  cout << message;
21  cout << ' ' << '[';
22  cout << (defaultResponse == Response::Yes ? 'Y' : 'y');
23  cout << '/' << (defaultResponse == Response::No ? 'N' : 'n');
24  cout << ']' << ' ';
25  cout.flush();
26  for(string line; ;) {
27  getline(cin, line);
28  if(line == "y" || line == "Y" || (defaultResponse == Response::Yes && line.empty())) {
29  return true;
30  } else if(line == "n" || line == "N" || (defaultResponse == Response::No && line.empty())) {
31  return false;
32  } else {
33  cout << "Please enter [y] or [n]: ";
34  cout.flush();
35  }
36  }
37 }
38 
39 #ifdef PLATFORM_WINDOWS
40 
44 void stopConsole()
45 {
46  fclose(stdout);
47  fclose(stdin);
48  fclose(stderr);
49  if(auto *consoleWindow = GetConsoleWindow()) {
50  PostMessage(consoleWindow, WM_KEYUP, VK_RETURN, 0);
51  FreeConsole();
52  }
53 }
54 
62 void startConsole()
63 {
64  if(!AttachConsole(ATTACH_PARENT_PROCESS) && !AllocConsole()) {
65  return;
66  }
67  // redirect stdout
68  auto stdHandle = reinterpret_cast<intptr_t>(GetStdHandle(STD_OUTPUT_HANDLE));
69  auto conHandle = _open_osfhandle(stdHandle, _O_TEXT);
70  auto fp = _fdopen(conHandle, "w");
71  *stdout = *fp;
72  setvbuf(stdout, NULL, _IONBF, 0);
73  // redirect stdin
74  stdHandle = reinterpret_cast<intptr_t>(GetStdHandle(STD_INPUT_HANDLE));
75  conHandle = _open_osfhandle(stdHandle, _O_TEXT);
76  fp = _fdopen(conHandle, "r");
77  *stdin = *fp;
78  setvbuf(stdin, NULL, _IONBF, 0);
79  // redirect stderr
80  stdHandle = reinterpret_cast<intptr_t>(GetStdHandle(STD_ERROR_HANDLE));
81  conHandle = _open_osfhandle(stdHandle, _O_TEXT);
82  fp = _fdopen(conHandle, "w");
83  *stderr = *fp;
84  setvbuf(stderr, NULL, _IONBF, 0);
85 #ifdef CPP_UTILITIES_FORCE_UTF8_CODEPAGE
86  // set console to handle UTF-8 IO correctly
87  // however, this doesn't work as intended and is therefore disabled by default
88  SetConsoleCP(CP_UTF8);
89  SetConsoleOutputCP(CP_UTF8);
90 #endif
91  // sync
92  ios::sync_with_stdio(true);
93  // ensure the console prompt is shown again when app terminates
94  atexit(stopConsole);
95 }
96 
101 pair<vector<unique_ptr<char[]> >, vector<char *> > convertArgsToUtf8()
102 {
103  pair<vector<unique_ptr<char[]> >, vector<char *> > res;
104  int argc;
105 
106  LPWSTR *argv_w = CommandLineToArgvW(GetCommandLineW(), &argc);
107  if(!argv_w || argc <= 0) {
108  return res;
109  }
110 
111  res.first.reserve(static_cast<size_t>(argc));
112  res.second.reserve(static_cast<size_t>(argc));
113  for(LPWSTR *i = argv_w, *end = argv_w + argc; i != end; ++i) {
114  int requiredSize = WideCharToMultiByte(CP_UTF8, 0, *i, -1, nullptr, 0, 0, 0);
115  if(requiredSize <= 0) {
116  break; // just stop on error
117  }
118 
119  auto argv = make_unique<char[]>(static_cast<size_t>(requiredSize));
120  requiredSize = WideCharToMultiByte(CP_UTF8, 0, *i, -1, argv.get(), requiredSize, 0, 0);
121  if(requiredSize <= 0) {
122  break;
123  }
124 
125  res.second.emplace_back(argv.get());
126  res.first.emplace_back(move(argv));
127  }
128 
129  LocalFree(argv_w);
130  return res;
131 }
132 #endif
133 
134 } // namespace ApplicationUtilities
Contains currently only ArgumentParser and related classes.
STL namespace.
bool CPP_UTILITIES_EXPORT confirmPrompt(const char *message, Response defaultResponse=Response::None)
Prompts for confirmation displaying the specified message.
Response
The Response enum is used to specify the default response for the confirmPrompt() method...