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-2025 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 #pragma warning( pop )
21 #include <processenv.h>
23// clang-format on
24#elif defined(__APPLE__)
25 #include <crt_externs.h>
26#else
27 #include <algorithm>
28 #include <cstddef>
29 #include <fstream>
30 #include <limits>
31#endif
32
34{
35 if(m_parsed) { return; }
36#if defined(_WIN32)
37 int argc{0};
38 std::unique_ptr<LPWSTR[], void (*)(wchar_t**)> wargv = std::unique_ptr<LPWSTR[], void (*)(wchar_t**)>(CommandLineToArgvW(GetCommandLineW(), &argc), [](wchar_t** ptr) { LocalFree(ptr); });
39 if(wargv == nullptr)
40 {
41 m_parsed = false;
42 return;
43 }
44 else
45 {
46 m_args.reserve(static_cast<std::size_t>(argc));
47 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])); }
48 m_parsed = true;
49 }
50#elif defined(__APPLE__)
51 std::size_t argc{static_cast<std::size_t>(*_NSGetArgc())};
52 m_args.reserve(argc);
53 char** argv{*_NSGetArgv()};
54 for(std::size_t i = 0; i != argc; ++i) { m_args.push_back(argv[i]); }
55 m_parsed = true;
56#else
57 std::string cmdline;
58 std::fstream file_stream;
59 const std::fstream::iostate old_iostate{file_stream.exceptions()};
60 try
61 {
62 file_stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
63 file_stream.open("/proc/self/cmdline", std::fstream::in | std::fstream::binary);
64 file_stream.ignore(std::numeric_limits<std::streamsize>::max());
65 cmdline.resize(static_cast<std::size_t>(file_stream.gcount()));
66 file_stream.seekg(0, std::ios_base::beg);
67 file_stream.get(&cmdline[0], static_cast<std::streamsize>(cmdline.size())); //NOLINT(readability-container-data-pointer)
68 file_stream.exceptions(old_iostate);
69 if(file_stream.is_open()) { file_stream.close(); }
70 m_args.reserve(static_cast<std::size_t>(std::count(cmdline.begin(), cmdline.end(), '\0')));
71 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())); }
72 m_parsed = true;
73 }
74 catch(...)
75 {
76 file_stream.exceptions(old_iostate);
77 if(file_stream.is_open()) { file_stream.close(); }
78 m_args.clear();
79 m_parsed = false;
80 }
81#endif
82}
83
85{
86 parse();
87 return m_args.size();
88}
89
90std::vector<std::string> Term::Arguments::argv()
91{
92 parse();
93 return m_args;
94}
95
96bool Term::Arguments::m_parsed = false;
97
98std::vector<std::string> Term::Arguments::m_args = std::vector<std::string>(); //NOLINT(fuchsia-statically-constructed-objects)
static void parse()
Definition args.cpp:33
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:90
static std::size_t argc()
Definition args.cpp:84
std::string to_narrow(const std::wstring &wstr)
Definition unicode.cpp:26