Skip to content

Commit a79daf7

Browse files
committed
To adopt PR avrdudes#1264 approach of using Readline replacement for MinGW build
1 parent 2bb36b9 commit a79daf7

File tree

6 files changed

+148
-1
lines changed

6 files changed

+148
-1
lines changed

CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ if(HAVE_LIBREADLINE)
225225
find_library(LIB_NCURSES NAMES ncurses)
226226
elseif(MSVC)
227227
set(HAVE_LIBREADLINE 1)
228+
elseif(MINGW)
229+
set(HAVE_LIBREADLINE 1)
228230
endif()
229231

230232
#-------------------------------------

src/CMakeLists.txt

+9
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ if(MSVC)
7575
set(EXTRA_WINDOWS_INCLUDES ${EXTRA_WINDOWS_INCLUDES}
7676
"msvc"
7777
)
78+
elseif(MINGW)
79+
set(LIB_MATH m)
80+
add_compile_options(-Wall -Wextra -Wno-unused-parameter)
81+
set(EXTRA_WINDOWS_SOURCES ${EXTRA_WINDOWS_SOURCES}
82+
"mingw/readline.cpp"
83+
)
84+
set(EXTRA_WINDOWS_INCLUDES ${EXTRA_WINDOWS_INCLUDES}
85+
"mingw"
86+
)
7887
else()
7988
set(LIB_MATH m)
8089
add_compile_options(-Wall -Wextra -Wno-unused-parameter)

src/mingw/readline.cpp

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//
2+
// readline.cpp
3+
// Copyright (C) 2022 Marius Greuel
4+
// SPDX-License-Identifier: GPL-2.0-or-later
5+
//
6+
7+
#include <string.h>
8+
#include <iostream>
9+
#include <memory>
10+
#include <mutex>
11+
#include <string>
12+
#include <thread>
13+
#include "readline/readline.h"
14+
#include "readline/history.h"
15+
16+
int rl_readline_version = 0x0502;
17+
18+
static rl_vcpfunc_t* rl_handler;
19+
static std::unique_ptr<std::thread> rl_thread;
20+
static std::mutex rl_mutex;
21+
static std::string rl_line;
22+
static bool rl_has_line = false;
23+
24+
static void get_line_thread()
25+
{
26+
std::string line;
27+
std::getline(std::cin, line);
28+
29+
const std::lock_guard<std::mutex> lock(rl_mutex);
30+
rl_line = line;
31+
rl_has_line = true;
32+
}
33+
34+
static void call_handler(const char* string)
35+
{
36+
if (rl_thread)
37+
{
38+
rl_thread->join();
39+
rl_thread = nullptr;
40+
}
41+
42+
if (rl_handler != nullptr)
43+
{
44+
if (string == nullptr)
45+
{
46+
rl_handler(nullptr);
47+
}
48+
else
49+
{
50+
rl_handler(_strdup(string));
51+
}
52+
}
53+
}
54+
55+
int rl_input_available(void)
56+
{
57+
return 1;
58+
}
59+
60+
void rl_callback_read_char(void)
61+
{
62+
if (std::cin.eof())
63+
{
64+
call_handler(nullptr);
65+
}
66+
else if (!rl_thread)
67+
{
68+
rl_thread = std::make_unique<std::thread>(get_line_thread);
69+
}
70+
else
71+
{
72+
const std::lock_guard<std::mutex> lock(rl_mutex);
73+
if (rl_has_line)
74+
{
75+
rl_has_line = false;
76+
call_handler(rl_line.c_str());
77+
}
78+
}
79+
}
80+
81+
void rl_callback_handler_install(char* prompt, rl_vcpfunc_t* handler)
82+
{
83+
rl_handler = handler;
84+
85+
std::cout << prompt;
86+
}
87+
88+
void rl_callback_handler_remove(void)
89+
{
90+
rl_handler = nullptr;
91+
}
92+
93+
void add_history(const char*)
94+
{
95+
}

src/mingw/readline/history.h

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// history.h
3+
// Copyright (C) 2022 Marius Greuel
4+
// SPDX-License-Identifier: GPL-2.0-or-later
5+
//
6+
7+
#pragma once
8+
9+
#ifdef __cplusplus
10+
extern "C" {
11+
#endif
12+
13+
void add_history(const char* string);
14+
15+
#ifdef __cplusplus
16+
}
17+
#endif

src/mingw/readline/readline.h

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// readline.h
3+
// Copyright (C) 2022 Marius Greuel
4+
// SPDX-License-Identifier: GPL-2.0-or-later
5+
//
6+
7+
#pragma once
8+
9+
#ifdef __cplusplus
10+
extern "C" {
11+
#endif
12+
13+
typedef void (rl_vcpfunc_t)(char* line);
14+
15+
extern int rl_readline_version;
16+
17+
int rl_input_available(void);
18+
void rl_callback_read_char(void);
19+
void rl_callback_handler_install(char* prompt, rl_vcpfunc_t* handler);
20+
void rl_callback_handler_remove(void);
21+
22+
#ifdef __cplusplus
23+
}
24+
#endif

src/term.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2089,7 +2089,7 @@ static int term_running;
20892089

20902090
// Any character in standard input available (without sleeping)?
20912091
static int readytoread() {
2092-
#ifdef _MSC_VER
2092+
#ifdef _MSC_VER || MINGW
20932093
return rl_input_available();
20942094
#elif defined(WIN32)
20952095
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);

0 commit comments

Comments
 (0)