Skip to content

Commit 87d2aa8

Browse files
authored
Merge pull request jupyter-xeus#172 from MCWertGaming/include-fix
added functions for reading stdin
2 parents 49f3f61 + 460649c commit 87d2aa8

File tree

18 files changed

+137
-30
lines changed

18 files changed

+137
-30
lines changed

.github/workflows/windows.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ jobs:
1212
- name: Checkout code
1313
uses: actions/checkout@v2
1414

15-
- name: Build and test
15+
- name: Build
1616
run: |
17-
ci\compile_test.bat
18-
examples\Release\colors.exe
17+
ci\compile_test.ps1
18+
- name: Test
19+
run: ci\test.ps1

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ cmake-build-release-cygwin/
5454
cmake-build-debug/
5555
cmake-build-debug-visual-studio/
5656
cmake-build-debug-cygwin/
57+
cmake-build-minsizerel/
58+
cmake-build-relwithdebinfo/
5759
.idea/
5860

5961
# cmake

ci/compile_test.bat

Lines changed: 0 additions & 8 deletions
This file was deleted.

ci/compile_test.ps1

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#cmake -DCMAKE_INSTALL_PREFIX=.\inst .
2+
cmake .
3+
cmake --build . --config Release
4+
cmake --install . --config Release
5+
ctest --output-on-failure
6+
7+
# Install on windows is complicated and not like on linux
8+
#cd tests\test-standalone
9+
#cmake -DCMAKE_PREFIX_PATH=%cd%\..\inst .
10+
#cmake --build . --config Release
11+
#cd

ci/test.ps1

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
echo "running example programs"
2+
.\examples\Release\colors.exe
3+
.\tests\Release\test_terminal.exe
4+
.\examples\Release\read_stdin.exe
5+
6+
echo "testing read_stind"
7+
if ((echo test | .\examples\Release\read_stdin.exe) -ne "Input from stdin: test") {
8+
echo "read_stdin gave wrong output"
9+
exit 1
10+
}

ci/tests.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ set -ex
44

55
./tests/test_terminal
66
./examples/colors
7+
./examples/read_stdin
8+
9+
echo "testing stdin example"
10+
if [[ $(echo test | ./examples/read_stdin) != "Input from stdin: test" ]]; then
11+
echo "stdin example returned wrong input"
12+
exit 1
13+
fi
714

815
echo "Expected to succeed:"
916
./examples/colors < README.md

cpp-terminal/input.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <chrono>
2+
#include <cpp-terminal/base.hpp>
23
#include <cpp-terminal/input.hpp>
34
#include <thread>
45
#include "private/platform.hpp"
@@ -183,3 +184,22 @@ int Term::read_key0() {
183184
return c;
184185
}
185186
}
187+
188+
// returns the whole input from STDIN as string
189+
std::string Term::read_stdin() {
190+
std::string file;
191+
char c;
192+
while (true) {
193+
c = Private::read_raw_stdin();
194+
if (c == 0x04) { // check for end of transmission signal
195+
return file;
196+
} else {
197+
file += c;
198+
}
199+
}
200+
}
201+
std::string Term::read_stdin_alone() {
202+
// temporarily enable raw mode
203+
Term::Terminal term(false, true, false, false);
204+
return Term::read_stdin();
205+
}

cpp-terminal/input.hpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#pragma once
2+
#include <string>
23

34
namespace Term {
45
enum Key {
@@ -40,11 +41,24 @@ enum Key {
4041
};
4142

4243
// Waits for a key press, translates escape codes
44+
// if Term:Terminal is not enabling the keyboard it'll loop for infinity
4345
int read_key();
4446

4547
// If there was a key press, returns the translated key from escape codes,
46-
// otherwise returns 0. If the escape code is not supported, returns a
48+
// otherwise returns 0. If the escape code is not supported it returns a
4749
// negative number.
50+
// if Term::Terminal is not enabling the keyboard it'll always return 0
4851
int read_key0();
4952

53+
// returns the stdin as a string
54+
// waits until the EOT signal is send
55+
// if Term::Terminal is not enabling the keyboard this function will wait until
56+
// the user presses CTRL+D (which sends the EOT signal)
57+
std::string read_stdin();
58+
59+
// returns stdin as a string, Term::Terminal is used to enable input to make the
60+
// function non-blocking, use Term::read_stdin() when Term::Terminal is already
61+
// created
62+
std::string read_stdin_alone();
63+
5064
} // namespace Term

cpp-terminal/private/platform.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,22 +68,24 @@ bool Term::Private::get_term_size(int& rows, int& cols) {
6868
}
6969
#endif
7070
}
71+
char Term::Private::read_raw_stdin() {
72+
int c = getchar();
73+
if (c >= 0) {
74+
return c;
75+
} else if (c == EOF) {
76+
// In non-raw (blocking) mode this happens when the input file
77+
// ends. In such a case, return the End of Transmission (EOT)
78+
// character (Ctrl-D)
79+
return 0x04;
80+
} else {
81+
throw std::runtime_error("getchar() failed");
82+
}
83+
}
7184

7285
bool Term::Private::read_raw(char* s) {
73-
// TODO: What if the keyboard is not initialized?
74-
if (false) {
75-
int c = getchar();
76-
if (c >= 0) {
77-
*s = c;
78-
} else if (c == EOF) {
79-
// In non-raw (blocking) mode this happens when the input file
80-
// ends. In such a case, return the End of Transmission (EOT)
81-
// character (Ctrl-D)
82-
*s = 0x04;
83-
} else {
84-
throw std::runtime_error("getchar() failed");
85-
}
86-
return true;
86+
// do nothing when TTY is not connected
87+
if (!is_stdin_a_tty()) {
88+
return false;
8789
}
8890
#ifdef _WIN32
8991
HANDLE hin = GetStdHandle(STD_INPUT_HANDLE);
@@ -144,8 +146,9 @@ Term::Private::BaseTerminal::~BaseTerminal() noexcept(false) {
144146
Term::Private::BaseTerminal::BaseTerminal(bool enable_keyboard,
145147
bool /*disable_ctrl_c*/)
146148
: keyboard_enabled{enable_keyboard} {
147-
// Uncomment this to silently disable raw mode for non-tty
148-
// if (keyboard_enabled) keyboard_enabled = is_stdin_a_tty();
149+
// silently disable raw mode for non-tty
150+
if (keyboard_enabled)
151+
keyboard_enabled = is_stdin_a_tty();
149152
out_console = is_stdout_a_tty();
150153
if (out_console) {
151154
hout = GetStdHandle(STD_OUTPUT_HANDLE);
@@ -187,8 +190,9 @@ Term::Private::BaseTerminal::BaseTerminal(bool enable_keyboard,
187190
bool disable_ctrl_c)
188191
: orig_termios{std::make_unique<termios>()},
189192
keyboard_enabled{enable_keyboard} {
190-
// Uncomment this to silently disable raw mode for non-tty
191-
// if (keyboard_enabled) keyboard_enabled = is_stdin_a_tty();
193+
// silently disable raw mode for non-tty
194+
if (keyboard_enabled)
195+
keyboard_enabled = is_stdin_a_tty();
192196
if (keyboard_enabled) {
193197
if (tcgetattr(STDIN_FILENO, orig_termios.get()) == -1) {
194198
throw std::runtime_error("tcgetattr() failed");

cpp-terminal/private/platform.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,6 @@ class BaseTerminal {
6464
virtual ~BaseTerminal() noexcept(false);
6565
};
6666

67+
char read_raw_stdin();
68+
6769
} // namespace Term::Private

0 commit comments

Comments
 (0)