// ************************************************************************** /** @class Console @brief This is an extension to the Readline class provding buffered output This in an extension to the Readline class. It's purpose is to keep a buffered output stream and flush the stream either between readline entries (non continous mode) or continously, keeping the readline prompt as intact as possible. */ // ************************************************************************** #include "Console.h" #include #include #include "tools.h" #include "ReadlineColor.h" using namespace std; // -------------------------------------------------------------------------- // //! Instantiate a console stream. It will create a WindowLog object //! and immediatel switch off its output to the console. The default more //! is non-continous. //! //! @param name //! The name of the program passed to the Readline constructor //! Console::Console(const char *name) : Readline(name), fContinous(false) { fLogO.SetNullOutput(); fLogI.SetNullOutput(); fLogO.SetBacklog(true); fLogI.SetBacklog(true); } // -------------------------------------------------------------------------- // //! Flush the contents of the buffer before it is destroyed. // Console::~Console() { // flush buffer to display before it is destroyed in its destructor fLogO.Display(); fLogI.Display(); } // -------------------------------------------------------------------------- // //! Wrapper to call the correspnding function from ReadlineColor // bool Console::PrintGeneralHelp() { return ReadlineColor::PrintGeneralHelp(fLogI, GetName()); } // -------------------------------------------------------------------------- // //! Wrapper to call the correspnding function from ReadlineColor // bool Console::PrintCommands() { return ReadlineColor::PrintCommands(fLogI); } // -------------------------------------------------------------------------- // //! Wrapper to call the correspnding function from ReadlineColor // bool Console::PrintKeyBindings() { return ReadlineColor::PrintKeyBindings(fLogI); } // -------------------------------------------------------------------------- // //! Processes the command provided by the Shell-class. //! //! @returns //! whether a command was successfully processed or could not be found // bool Console::Process(const string &str) { if (ReadlineColor::Process(fLogI, str)) return true; if (str.substr(0, 3)==".w ") { fLogO.Display(true); fLogO.SetBacklog(false); fLogO.SetNullOutput(false); usleep(atoi(str.c_str()+3)*1000); fLogO.SetNullOutput(true); fLogO.SetBacklog(true); return true; } if (Readline::Process(str)) return true; return false; } // -------------------------------------------------------------------------- // //! Before readline starts flush the buffer to display all stuff which was //! buffered since the last readline call returned. // void Console::Startup() { // Call readline's startup (just in case, it is empty) Readline::Startup(); // First flush the buffer of the stream which is synchronous // with the prompt fLogI.Display(true); // Now flush the stream which is asychronous fLogO.Display(true); // The order has the advantage that output initiated by the prompt // is not interrupter by the synchronous stream } // -------------------------------------------------------------------------- // //! Flush the buffer if we are in continous mode, and call Readline's //! EventHook to update the prompt. // void Console::EventHook() { // If the output is continous and we are going to output something // first jump back to the beginning of the line (well, that // doesn't work well if the input line is already two lines) // and then flush the buffer. if (fContinous && fLogO.GetSizeBacklog()>0) { // Clear the line we are going to overwrite std::cout << "\r\033[0K"; fLogO.Display(true); } // Call Readline's EventHook to update the prompt Readline::EventHook(); } string Console::GetLinePrompt() const { const string siz = fLogO.GetSizeStr(); ostringstream str; str << '[' << GetLine(); return fContinous ? str.str()+']' : str.str()+':'+siz+']'; } // -------------------------------------------------------------------------- // //! Before Readline::Run() is called the buffer is flushed as well as //! after the Run() loop has exited. //! command processing. This keeps things as seperated as possible, //! although there is no gurantee. // void Console::Run(const char *) { ReadlineColor::PrintBootMsg(fLogI, GetName()); // Flush the buffer before we start out readline loop fLogI.Display(true); fLogO.Display(true); // Now run readlines main loop Readline::Run(); // flush buffer to display fLogI.Display(true); fLogO.Display(true); }