#include #include #include #ifndef WIN32 #include #endif #ifdef HAVE_READLINE # include # include // I don't know exactly what version of readline we need. I know the 4.2 version that ships on some macs is // missing some functions we require. We're developing against 6.3, but probably anything in the 6.x // series is fine # if RL_VERSION_MAJOR < 6 # ifdef _MSC_VER # pragma message("You have an old version of readline installed that might not support some of the features we need") # pragma message("Readline support will not be compiled in") # else # warning "You have an old version of readline installed that might not support some of the features we need" # warning "Readline support will not be compiled in" # endif # undef HAVE_READLINE # endif # ifdef WIN32 # include # endif #endif namespace fc { namespace rpc { void cli::getline( const fc::string& prompt, fc::string& line) { // getting file descriptor for C++ streams is near impossible // so we just assume it's the same as the C stream... #ifdef HAVE_READLINE #ifndef WIN32 if( isatty( fileno( stdin ) ) ) #else // it's implied by // https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx // that this is the proper way to do this on Windows, but I have // no access to a Windows compiler and thus, // no idea if this actually works if( _isatty( _fileno( stdin ) ) ) #endif { static fc::thread getline_thread("getline"); getline_thread.async( [&](){ char* line_read = nullptr; std::cout.flush(); //readline doesn't use cin, so we must manually flush _out line_read = readline(prompt.c_str()); if( line_read == nullptr ) FC_THROW_EXCEPTION( fc::eof_exception, "" ); if( *line_read ) add_history(line_read); line = line_read; free(line_read); }).wait(); } else #endif { std::cout << prompt; // sync_call( cin_thread, [&](){ std::getline( *input_stream, line ); }, "getline"); fc::getline( fc::cin, line ); return; } } } }