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
2013-09-05 18:43:20 +04:00
# include "cling/Interpreter/RuntimeExceptions.h"
2013-05-24 19:50:13 +04:00
# include "cling/Interpreter/StoredValueRef.h"
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"
2013-01-22 17:56:38 +04:00
# include "llvm/Config/config.h"
2012-09-05 13:37:39 +04:00
2013-01-18 13:02:46 +04:00
// Fragment copied from LLVM's raw_ostream.cpp
2013-01-18 20:20:34 +04:00
# if defined(HAVE_UNISTD_H)
# include <unistd.h>
# endif
2013-01-18 13:02:46 +04:00
# if defined(_MSC_VER)
# ifndef STDIN_FILENO
# define STDIN_FILENO 0
# endif
# ifndef STDOUT_FILENO
# define STDOUT_FILENO 1
# endif
# ifndef STDERR_FILENO
# define STDERR_FILENO 2
# endif
# endif
2013-01-17 20:40:33 +04:00
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 ;
2013-08-28 01:40:49 +04:00
while ( true ) {
try {
2013-08-28 01:00:35 +04:00
m_MetaProcessor - > getOuts ( ) . flush ( ) ;
TextInput : : EReadResult RR = TI . ReadInput ( ) ;
TI . TakeInput ( line ) ;
if ( RR = = TextInput : : kRREOF ) {
break ;
}
cling : : Interpreter : : CompilationResult compRes ;
int indent
= m_MetaProcessor - > process ( line . c_str ( ) , compRes , 0 /*result*/ ) ;
// Quit requested
if ( indent < 0 )
break ;
std : : string Prompt = " [cling] " ;
if ( m_MetaProcessor - > getInterpreter ( ) . isRawInputEnabled ( ) )
Prompt . append ( " ! " ) ;
else
Prompt . append ( " $ " ) ;
if ( indent > 0 )
// Continuation requested.
Prompt . append ( ' ? ' + std : : string ( indent * 3 , ' ' ) ) ;
TI . SetPrompt ( Prompt . c_str ( ) ) ;
2012-12-06 13:54:20 +04:00
}
2013-09-07 01:23:45 +04:00
catch ( runtime : : NullDerefException & e ) {
2013-09-05 18:43:20 +04:00
// The diagnostic goes here:
2013-09-07 01:02:00 +04:00
e . what ( ) ;
2013-09-05 18:43:20 +04:00
}
2013-08-28 01:40:49 +04:00
catch ( . . . ) {
llvm : : errs ( ) < < " Exception occurred. Recovering... \n " ;
}
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