2012-09-05 13:37:39 +04:00
//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author: Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------
2012-12-06 13:54:20 +04:00
# include "cling/UserInterface/UserInterface.h"
2012-09-05 13:37:39 +04:00
2012-12-06 13:54:20 +04:00
# include "cling/MetaProcessor/MetaProcessor.h"
2012-09-05 13:37:39 +04:00
# include "textinput/TextInput.h"
# include "textinput/StreamReader.h"
# include "textinput/TerminalDisplay.h"
# include "llvm/Support/raw_ostream.h"
# include "llvm/Support/PathV1.h"
2012-12-06 13:54:20 +04:00
namespace cling {
UserInterface : : UserInterface ( Interpreter & interp ) {
2013-01-17 19:27:14 +04:00
// We need stream that doesn't close its file descriptor, thus we are not
// using llvm::outs. Keeping file descriptor open we will be able to use
// the results in pipes (Savannah #99234).
static llvm : : raw_fd_ostream m_MPOuts ( STDOUT_FILENO , /*ShouldClose*/ false ) ;
m_MetaProcessor . reset ( new MetaProcessor ( interp , m_MPOuts ) ) ;
2012-09-05 13:37:39 +04:00
}
2012-12-06 13:54:20 +04:00
UserInterface : : ~ UserInterface ( ) { }
2012-09-05 13:37:39 +04:00
2012-12-06 13:54:20 +04:00
void UserInterface : : runInteractively ( bool nologo /* = false */ ) {
if ( ! nologo ) {
PrintLogo ( ) ;
2012-09-05 13:37:39 +04:00
}
2012-12-06 13:54:20 +04:00
// History file is $HOME/.cling_history
static const char * histfile = " .cling_history " ;
llvm : : sys : : Path histfilePath = llvm : : sys : : Path : : GetUserHomeDirectory ( ) ;
histfilePath . appendComponent ( histfile ) ;
using namespace textinput ;
StreamReader * R = StreamReader : : Create ( ) ;
TerminalDisplay * D = TerminalDisplay : : Create ( ) ;
TextInput TI ( * R , * D , histfilePath . c_str ( ) ) ;
TI . SetPrompt ( " [cling]$ " ) ;
std : : string line ;
2012-12-06 15:47:24 +04:00
while ( true ) {
2013-01-17 19:27:14 +04:00
m_MetaProcessor - > getOuts ( ) . flush ( ) ;
2012-12-06 13:54:20 +04:00
TextInput : : EReadResult RR = TI . ReadInput ( ) ;
TI . TakeInput ( line ) ;
if ( RR = = TextInput : : kRREOF ) {
2012-12-06 15:47:24 +04:00
break ;
2012-12-06 13:54:20 +04:00
}
2012-12-06 15:47:24 +04:00
2012-12-06 13:54:20 +04:00
int indent = m_MetaProcessor - > process ( line . c_str ( ) ) ;
2012-12-06 15:47:24 +04:00
// Quit requested
if ( indent < 0 )
break ;
2012-12-06 13:54:20 +04:00
std : : string Prompt = " [cling] " ;
2012-12-06 14:52:01 +04:00
if ( m_MetaProcessor - > getInterpreter ( ) . isRawInputEnabled ( ) )
2012-12-06 13:54:20 +04:00
Prompt . append ( " ! " ) ;
else
Prompt . append ( " $ " ) ;
if ( indent > 0 )
// Continuation requested.
Prompt . append ( ' ? ' + std : : string ( indent * 3 , ' ' ) ) ;
TI . SetPrompt ( Prompt . c_str ( ) ) ;
2012-09-05 13:37:39 +04:00
2012-12-06 13:54:20 +04:00
}
2012-09-05 13:37:39 +04:00
}
2012-12-06 13:54:20 +04:00
void UserInterface : : PrintLogo ( ) {
2013-01-17 19:27:14 +04:00
llvm : : raw_ostream & outs = m_MetaProcessor - > getOuts ( ) ;
outs < < " \n " ;
outs < < " ****************** CLING ****************** " < < " \n " ;
outs < < " * Type C++ code and press enter to run it * " < < " \n " ;
outs < < " * Type .q to exit * " < < " \n " ;
outs < < " ******************************************* " < < " \n " ;
2012-12-06 13:54:20 +04:00
}
} // end namespace cling