Skip to content

Commit b8661e3

Browse files
authored
Args #155 (#283)
1 parent 6fbc24f commit b8661e3

File tree

20 files changed

+392
-96
lines changed

20 files changed

+392
-96
lines changed

.gitignore

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,7 @@ cmake_install.cmake
4848
CMakeCache.txt
4949

5050
# Clion
51-
cmake-build-release/
52-
cmake-build-release-visual-studio/
53-
cmake-build-release-cygwin/
54-
cmake-build-debug/
55-
cmake-build-debug-visual-studio/
56-
cmake-build-debug-cygwin/
57-
cmake-build-minsizerel/
58-
cmake-build-relwithdebinfo/
51+
cmake-build*
5952
.idea/
6053

6154
# cmake

cpp-terminal/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ configure_file(version.cpp.in version.cpp)
44
add_subdirectory(platforms)
55

66
# create and configure library target
7-
add_library(cpp-terminal buffer.cpp iostream.cpp stream.cpp prompt.cpp window.cpp input.cpp terminal.cpp color.cpp key.cpp event.cpp screen.cpp options.cpp cursor.cpp style.cpp "${CMAKE_CURRENT_BINARY_DIR}/version.cpp")
7+
add_library(cpp-terminal args.cpp buffer.cpp iostream.cpp stream.cpp prompt.cpp window.cpp input.cpp terminal.cpp color.cpp key.cpp event.cpp screen.cpp options.cpp cursor.cpp style.cpp "${CMAKE_CURRENT_BINARY_DIR}/version.cpp")
88
target_link_libraries(cpp-terminal PRIVATE Warnings::Warnings cpp-terminal::cpp-terminal-platforms)
99
target_compile_options(cpp-terminal PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/utf-8>)
1010
target_include_directories(cpp-terminal PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}> $<INSTALL_INTERFACE:include>)

cpp-terminal/args.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include "cpp-terminal/args.hpp"
2+
namespace Term
3+
{
4+
5+
Term::Argc::Argc() {}
6+
7+
Term::Argc::operator long unsigned int() { return static_cast<int>(Term::Arguments::argc()); }
8+
9+
Term::Argc::operator long unsigned int() const { return static_cast<int>(Term::Arguments::argc()); }
10+
11+
Term::Arguments::Arguments() {}
12+
13+
std::string Term::Arguments::operator[](const std::size_t& i) const { return m_args[i]; }
14+
15+
} // namespace Term

cpp-terminal/args.hpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <vector>
5+
6+
namespace Term
7+
{
8+
9+
class Arguments
10+
{
11+
public:
12+
Arguments();
13+
static std::size_t argc();
14+
static std::vector<std::string> argv();
15+
std::string operator[](const std::size_t&) const;
16+
17+
private:
18+
static void parse();
19+
static std::vector<std::string> m_args;
20+
static bool m_parsed;
21+
};
22+
23+
class Argc
24+
{
25+
public:
26+
Argc();
27+
operator long unsigned int();
28+
operator long unsigned int() const;
29+
};
30+
31+
static const Arguments argv;
32+
static const Argc argc;
33+
34+
} // namespace Term

cpp-terminal/buffer.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,25 @@
77
namespace Term
88
{
99

10-
class Buffer : public std::streambuf
10+
class Buffer final : public std::streambuf
1111
{
1212
public:
1313
enum class Type : std::uint8_t
1414
{
1515
Unbuffered,
1616
LineBuffered,
17-
FullBuffered,
17+
FullBuffered
1818
};
1919
explicit Buffer(const Term::Buffer::Type& type = Term::Buffer::Type::LineBuffered, const std::streamsize& size = BUFSIZ);
20-
virtual ~Buffer() = default;
20+
virtual ~Buffer() final = default;
21+
Buffer(const Buffer&) = delete;
22+
Buffer& operator=(const Buffer&) = delete;
23+
Buffer(Buffer&&) = delete;
24+
Buffer& operator=(Buffer&&) = delete;
2125

2226
protected:
2327
virtual Term::Buffer::int_type underflow() final;
24-
virtual Term::Buffer::int_type overflow(int c = std::char_traits<Term::Buffer::char_type>::eof());
28+
virtual Term::Buffer::int_type overflow(int c = std::char_traits<Term::Buffer::char_type>::eof()) final;
2529
virtual int sync() final;
2630

2731
private:

cpp-terminal/color.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class Color
1919
Bit3,
2020
Bit4,
2121
Bit8,
22-
Bit24,
22+
Bit24
2323
};
2424
/*
2525
* The 3bit/4bit colors for the terminal

cpp-terminal/exception.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Term
1010
class Exception : public std::exception
1111
{
1212
public:
13-
Exception(const std::string& what) : m_what(what){};
13+
Exception(const std::string& what) : m_what(what) {}
1414
virtual const char* what() const noexcept override { return m_what.c_str(); }
1515

1616
private:

cpp-terminal/options.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ enum class Option : int
1717
SignalKeys = 3,
1818
NoSignalKeys = -3,
1919
Cursor = 4,
20-
NoCursor = -4,
20+
NoCursor = -4
2121
};
2222

2323
class Options

cpp-terminal/platforms/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
add_library(cpp-terminal-platforms STATIC terminal.cpp tty.cpp terminfo.cpp input.cpp screen.cpp cursor.cpp file.cpp env.cpp)
1+
add_library(cpp-terminal-platforms STATIC conversion.cpp args.cpp terminal.cpp tty.cpp terminfo.cpp input.cpp screen.cpp cursor.cpp file.cpp env.cpp)
22
target_link_libraries(cpp-terminal-platforms PRIVATE Warnings::Warnings)
33
target_compile_options(cpp-terminal-platforms PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/utf-8 /wd4668 /wd4514>)
44
target_include_directories(cpp-terminal-platforms PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}> $<INSTALL_INTERFACE:include>)

cpp-terminal/platforms/args.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#include "cpp-terminal/args.hpp"
2+
3+
#include "cpp-terminal/platforms/conversion.hpp"
4+
5+
#if defined(_WIN32)
6+
#include <memory>
7+
// clang-format off
8+
#include <windows.h>
9+
#include <processenv.h>
10+
// clang-format on
11+
#elif defined(__APPLE__)
12+
#include <crt_externs.h>
13+
#else
14+
#include <algorithm>
15+
#include <fstream>
16+
#include <limits>
17+
#endif
18+
19+
void Term::Arguments::parse()
20+
{
21+
if(m_parsed == true) return;
22+
#if defined(_WIN32)
23+
int argc{0};
24+
std::unique_ptr<LPWSTR[], void (*)(wchar_t**)> wargv = std::unique_ptr<LPWSTR[], void (*)(wchar_t**)>(CommandLineToArgvW(GetCommandLineW(), &argc), [](wchar_t** ptr) { LocalFree(ptr); });
25+
if(wargv == nullptr)
26+
{
27+
m_parsed = false;
28+
return;
29+
}
30+
else
31+
{
32+
m_args.reserve(static_cast<std::size_t>(argc));
33+
for(std::size_t i = 0; i != static_cast<std::size_t>(argc); ++i) { m_args.push_back(Term::Private::to_utf8(&wargv.get()[i][0])); }
34+
m_parsed = true;
35+
}
36+
#elif defined(__APPLE__)
37+
int argc{*_NSGetArgc()};
38+
m_args.reserve(argc);
39+
char** argv{*_NSGetArgv()};
40+
for(std::size_t i = 0; i != argc; ++i) { m_args.push_back(argv[i]); }
41+
m_parsed = true;
42+
#else
43+
std::string cmdline;
44+
std::fstream fs;
45+
std::fstream::iostate old_iostate{fs.exceptions()};
46+
try
47+
{
48+
fs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
49+
fs.open("/proc/self/cmdline", std::fstream::in | std::fstream::binary);
50+
fs.ignore(std::numeric_limits<std::streamsize>::max());
51+
cmdline.resize(fs.gcount());
52+
fs.seekg(0, std::ios_base::beg);
53+
fs.get(&cmdline[0], cmdline.size());
54+
fs.exceptions(old_iostate);
55+
if(fs.is_open()) fs.close();
56+
const std::size_t argc = static_cast<std::size_t>(std::count(cmdline.begin(), cmdline.end(), '\0'));
57+
m_args.reserve(argc);
58+
for(std::string::iterator it = cmdline.begin(); it != cmdline.end(); it = std::find(it, cmdline.end(), '\0') + 1) { m_args.push_back(cmdline.data() + (it - cmdline.begin())); }
59+
m_parsed = true;
60+
}
61+
catch(...)
62+
{
63+
fs.exceptions(old_iostate);
64+
if(fs.is_open()) fs.close();
65+
m_parsed = false;
66+
m_args.clear();
67+
m_parsed = false;
68+
}
69+
#endif
70+
}
71+
72+
std::size_t Term::Arguments::argc()
73+
{
74+
parse();
75+
return m_args.size();
76+
}
77+
78+
std::vector<std::string> Term::Arguments::argv()
79+
{
80+
parse();
81+
return m_args;
82+
}
83+
84+
bool Term::Arguments::m_parsed = false;
85+
86+
std::vector<std::string> Term::Arguments::m_args = std::vector<std::string>();

0 commit comments

Comments
 (0)