aboutsummaryrefslogtreecommitdiff
path: root/riscv/interactive.cc
diff options
context:
space:
mode:
authorElmar Melcher <elmar@dsc.ufcg.edu.br>2021-07-02 11:38:25 -0300
committeremelcher <elmar@dsc.ufcg.edu.br>2021-08-03 10:19:27 -0300
commit0014a1ec3202550896c502686a1907d1784aba8e (patch)
tree3651c857e1ce9b787ea2ff20caec35334acd0536 /riscv/interactive.cc
parent08ed2fab4f627dad4c77ee41d93deddde68817fe (diff)
downloadspike-0014a1ec3202550896c502686a1907d1784aba8e.zip
spike-0014a1ec3202550896c502686a1907d1784aba8e.tar.gz
spike-0014a1ec3202550896c502686a1907d1784aba8e.tar.bz2
functions needed for socket input/output
Diffstat (limited to 'riscv/interactive.cc')
-rw-r--r--riscv/interactive.cc71
1 files changed, 71 insertions, 0 deletions
diff --git a/riscv/interactive.cc b/riscv/interactive.cc
index 81809b3..b9da95c 100644
--- a/riscv/interactive.cc
+++ b/riscv/interactive.cc
@@ -8,6 +8,7 @@
#include <termios.h>
#include <map>
#include <iostream>
+#include <iomanip>
#include <climits>
#include <cinttypes>
#include <assert.h>
@@ -19,6 +20,19 @@
#include <algorithm>
#include <math.h>
+using std::ostream;
+using std::cerr;
+using std::hex;
+using std::dec;
+using std::setfill;
+using std::left;
+using std::right;
+using std::setw;
+using std::endl;
+
+#define STR_(X) #X // these definitions allow to use a macro as a string
+#define STR(X) STR_(X)
+
DECLARE_TRAP(-1, interactive)
processor_t *sim_t::get_core(const std::string& i)
@@ -58,6 +72,63 @@ static std::string readline(int fd)
return s;
}
+#ifdef HAVE_BOOST_ASIO
+// read input command string
+std::string sim_t::rin(streambuf *bout_ptr) {
+ std::string s;
+ if (acceptor_ptr) { // if we are listening, get commands from socket
+ try
+ {
+ socket_ptr = new tcp::socket(*io_service_ptr);
+ acceptor_ptr->accept(*socket_ptr); // wait for someone to open connection
+ boost::asio::streambuf buf;
+ boost::asio::read_until(*socket_ptr, buf, "\n"); // wait for command
+ s = buffer_cast<const char*>(buf.data());
+ erase_all(s, "\r"); // get rid off any cr and lf
+ erase_all(s, "\n");
+ // The socket client is a web server and it appends the IP of the computer
+ // that sent the command from its web browser.
+
+ // For now, erase the IP if it is there.
+ regex re(" ((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}"
+ "(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$");
+ s = regex_replace(s, re, (std::string)"");
+
+ // TODO: check the IP against the IP used to upload RISC-V source files
+ }
+ catch (std::exception& e)
+ {
+ cerr << e.what() << endl;
+ }
+ // output goes to socket
+ sout.rdbuf(bout_ptr);
+ } else { // if we are not listening on a socket, get commands from terminal
+ cerr << ": " << std::flush;
+ s = readline(2); // 2 is stderr which in turn is stdin
+ // output goes to stderr
+ sout.rdbuf(cerr.rdbuf());
+ }
+ return s;
+}
+
+// write sout to socket (via bout)
+void sim_t::wout(streambuf *bout_ptr) {
+ if (acceptor_ptr) { // only if a socket has been created
+ try
+ {
+ boost::system::error_code ignored_error;
+ boost::asio::write(*socket_ptr, *bout_ptr, transfer_all(), ignored_error);
+ socket_ptr->close(); // close the socket after each command input/ouput
+ // This is need to in order to make the socket interface
+ } // acessible by HTML GET via a socket client in a web server.
+ catch (std::exception& e)
+ {
+ cerr << e.what() << endl;
+ }
+ }
+}
+#endif
+
void sim_t::interactive()
{
typedef void (sim_t::*interactive_func)(const std::string&, const std::vector<std::string>&);