cpp-terminal 1.0.0
Small C++ library for writing multiplatform terminal applications
Loading...
Searching...
No Matches
args.cpp
Go to the documentation of this file.
1/*
2* cpp-terminal
3* C++ library for writing multi-platform terminal applications.
4*
5* SPDX-FileCopyrightText: 2019-2024 cpp-terminal
6*
7* SPDX-License-Identifier: MIT
8*/
9
10#include "cpp-terminal/args.hpp"
11
12#include <ios>
13
14#if defined(_WIN32)
15 #include <memory>
16// clang-format off
17 #pragma warning( push )
18 #pragma warning( disable : 4668)
19 #include <windows.h>
20 #include <processenv.h>
22// clang-format on
23#elif defined(__APPLE__)
24 #include <crt_externs.h>
25#else
26 #include <algorithm>
27 #include <cstddef>
28 #include <fstream>
29 #include <limits>
30#endif
31
33{
34 if(m_parsed) { return; }
35#if defined(_WIN32)
36 int argc{0};
37 std::unique_ptr<LPWSTR[], void (*)(wchar_t**)> wargv = std::unique_ptr<LPWSTR[], void (*)(wchar_t**)>(CommandLineToArgvW(GetCommandLineW(), &argc), [](wchar_t** ptr) { LocalFree(ptr); });
38 if(wargv == nullptr)
39 {
40 m_parsed = false;
41 return;
42 }
43 else
44 {
45 m_args.reserve(static_cast<std::size_t>(argc));
46 for(std::size_t i = 0; i != static_cast<std::size_t>(argc); ++i) { m_args.push_back(Term::Private::to_narrow(&wargv.get()[i][0])); }
47 m_parsed = true;
48 }
49#elif defined(__APPLE__)
50 std::size_t argc{static_cast<std::size_t>(*_NSGetArgc())};
51 m_args.reserve(argc);
52 char** argv{*_NSGetArgv()};
53 for(std::size_t i = 0; i != argc; ++i) { m_args.push_back(argv[i]); }
54 m_parsed = true;
55#else
56 std::string cmdline;
57 std::fstream file_stream;
58 const std::fstream::iostate old_iostate{file_stream.exceptions()};
59 try
60 {
61 file_stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
62 file_stream.open("/proc/self/cmdline", std::fstream::in | std::fstream::binary);
63 file_stream.ignore(std::numeric_limits<std::streamsize>::max());
64 cmdline.resize(static_cast<std::size_t>(file_stream.gcount()));
65 file_stream.seekg(0, std::ios_base::beg);
66 file_stream.get(&cmdline[0], static_cast<std::streamsize>(cmdline.size())); //NOLINT(readability-container-data-pointer)
67 file_stream.exceptions(old_iostate);
68 if(file_stream.is_open()) { file_stream.close(); }
69 m_args.reserve(static_cast<std::size_t>(std::count(cmdline.begin(), cmdline.end(), '\0')));
70 for(std::string::iterator it = cmdline.begin(); it != cmdline.end(); it = std::find(it, cmdline.end(), '\0') + 1) { m_args.emplace_back(cmdline.data() + (it - cmdline.begin())); }
71 m_parsed = true;
72 }
73 catch(...)
74 {
75 file_stream.exceptions(old_iostate);
76 if(file_stream.is_open()) { file_stream.close(); }
77 m_args.clear();
78 m_parsed = false;
79 }
80#endif
81}
82
84{
85 parse();
86 return m_args.size();
87}
88
89std::vector<std::string> Term::Arguments::argv()
90{
91 parse();
92 return m_args;
93}
94
95bool Term::Arguments::m_parsed = false;
96
97std::vector<std::string> Term::Arguments::m_args = std::vector<std::string>(); //NOLINT(fuchsia-statically-constructed-objects)
static void parse()
Definition args.cpp:32
static std::vector< std::string > m_args
Definition args.hpp:28
static bool m_parsed
Definition args.hpp:29
static std::vector< std::string > argv()
Definition args.cpp:89
static std::size_t argc()
Definition args.cpp:83
std::string to_narrow(const std::wstring &wstr)
Definition unicode.cpp:26