Skip to content

Commit

Permalink
Added recursive print depth meta command.
Browse files Browse the repository at this point in the history
Implemented corresponding print behaviour.
  • Loading branch information
Boris Perovic committed Sep 9, 2015
1 parent 72446c5 commit e0ff729
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 58 deletions.
7 changes: 7 additions & 0 deletions interpreter/cling/include/cling/Interpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ namespace cling {
///
bool m_RawInputEnabled;

///\brief Depth up to which to recursively print collections.
///
unsigned int m_RecursivePrintDepth;

///\brief Interpreter callbacks.
///
std::unique_ptr<InterpreterCallbacks> m_Callbacks;
Expand Down Expand Up @@ -545,6 +549,9 @@ namespace cling {
bool isRawInputEnabled() const { return m_RawInputEnabled; }
void enableRawInput(bool raw = true) { m_RawInputEnabled = raw; }

unsigned int getRecursivePrintDepth() const { return m_RecursivePrintDepth; }
void setRecursivePrintDepth(unsigned int depth) { m_RecursivePrintDepth = depth; }

clang::CompilerInstance* getCI() const;
clang::Sema& getSema() const;

Expand Down
82 changes: 48 additions & 34 deletions interpreter/cling/include/cling/Interpreter/RuntimePrintValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,69 +16,69 @@ namespace cling {
class Value;

// General fallback - prints the address
std::string printValue(const void *ptr);
std::string printValue(const void *ptr, unsigned int);

// void pointer
std::string printValue(const void **ptr);
std::string printValue(const void **ptr, unsigned int);

// Bool
std::string printValue(const bool *val);
std::string printValue(const bool *val, unsigned int);

// Chars
std::string printValue(const char *val);
std::string printValue(const char *val, unsigned int);

std::string printValue(const signed char *val);
std::string printValue(const signed char *val, unsigned int);

std::string printValue(const unsigned char *val);
std::string printValue(const unsigned char *val, unsigned int);

// Ints
std::string printValue(const short *val);
std::string printValue(const short *val, unsigned int);

std::string printValue(const unsigned short *val);
std::string printValue(const unsigned short *val, unsigned);

std::string printValue(const int *val);
std::string printValue(const int *val, unsigned int);

std::string printValue(const unsigned int *val);
std::string printValue(const unsigned int *val, unsigned int);

std::string printValue(const long *val);
std::string printValue(const long *val, unsigned int);

std::string printValue(const unsigned long *val);
std::string printValue(const unsigned long *val, unsigned int);

std::string printValue(const long long *val);
std::string printValue(const long long *val, unsigned int);

std::string printValue(const unsigned long long *val);
std::string printValue(const unsigned long long *val, unsigned int);

// Reals
std::string printValue(const float *val);
std::string printValue(const float *val, unsigned int);

std::string printValue(const double *val);
std::string printValue(const double *val, unsigned int);

std::string printValue(const long double *val);
std::string printValue(const long double *val, unsigned int);

// Char pointers
std::string printValue(const char *const *val);
std::string printValue(const char *const *val, unsigned int);

std::string printValue(const char **val);
std::string printValue(const char **val, unsigned int);

// std::string
std::string printValue(const std::string *val);
std::string printValue(const std::string *val, unsigned int);

// cling::Value
std::string printValue(const Value *value);
std::string printValue(const Value *value, unsigned int);

// Collections internal declaration
namespace collectionPrinterInternal {
// Maps declaration
template<typename CollectionType>
auto printValue_impl(const CollectionType *obj, short)
auto printValue_impl(const CollectionType *obj, unsigned int recurseDepth, short)
-> decltype(
++(obj->begin()), obj->end(),
obj->begin()->first, obj->begin()->second,
std::string());

// Vector, set, deque etc. declaration
template<typename CollectionType>
auto printValue_impl(const CollectionType *obj, int)
auto printValue_impl(const CollectionType *obj, unsigned int recurseDepth, int)
-> decltype(
++(obj->begin()), obj->end(),
*(obj->begin()),
Expand All @@ -89,19 +89,23 @@ namespace cling {

// Collections
template<typename CollectionType>
auto printValue(const CollectionType *obj)
-> decltype(collectionPrinterInternal::printValue_impl(obj, 0), std::string())
auto printValue(const CollectionType *obj, unsigned int recurseDepth)
-> decltype(collectionPrinterInternal::printValue_impl(obj, recurseDepth, 0), std::string())
{
return collectionPrinterInternal::printValue_impl(obj, (short)0); // short -> int -> long = priority order
return collectionPrinterInternal::printValue_impl(obj, recurseDepth, (short)0); // short -> int -> long = priority order
}

// Arrays
template<typename T, size_t N>
std::string printValue(const T (*obj)[N]) {
std::string printValue(const T (*obj)[N], unsigned int recurseDepth) {
std::string str = "{ ";

for (int i = 0; i < N; ++i) {
str += printValue(*obj + i);
if (recurseDepth > 0) {
str += printValue(*obj + i, recurseDepth - 1);
} else {
str += printValue((void *) (*obj + i), recurseDepth - 1);
}
if (i < N - 1) str += ", ";
}

Expand All @@ -112,7 +116,7 @@ namespace cling {
namespace collectionPrinterInternal {
// Maps
template<typename CollectionType>
auto printValue_impl(const CollectionType *obj, short)
auto printValue_impl(const CollectionType *obj, unsigned int recurseDepth, short)
-> decltype(
++(obj->begin()), obj->end(),
obj->begin()->first, obj->begin()->second,
Expand All @@ -123,9 +127,15 @@ namespace cling {
auto iter = obj->begin();
auto iterEnd = obj->end();
while (iter != iterEnd) {
str += printValue(&iter->first);
str += " => ";
str += printValue(&iter->second);
if (recurseDepth > 0) {
str += printValue(&iter->first, recurseDepth-1);
str += " => ";
str += printValue(&iter->second, recurseDepth-1);
} else {
str += printValue((void*)&iter->first, recurseDepth-1);
str += " => ";
str += printValue((void*)&iter->second, recurseDepth-1);
}
++iter;
if (iter != iterEnd) {
str += ", ";
Expand All @@ -137,7 +147,7 @@ namespace cling {

// Vector, set, deque etc.
template<typename CollectionType>
auto printValue_impl(const CollectionType *obj, int)
auto printValue_impl(const CollectionType *obj, unsigned int recurseDepth, int)
-> decltype(
++(obj->begin()), obj->end(),
*(obj->begin()),
Expand All @@ -148,7 +158,11 @@ namespace cling {
auto iter = obj->begin();
auto iterEnd = obj->end();
while (iter != iterEnd) {
str += printValue(&(*iter));
if (recurseDepth > 0) {
str += printValue(&(*iter), recurseDepth-1);
} else {
str += printValue((void*)&(*iter), recurseDepth-1);
}
++iter;
if (iter != iterEnd) {
str += ", ";
Expand Down
2 changes: 1 addition & 1 deletion interpreter/cling/lib/Interpreter/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ namespace cling {
Interpreter::Interpreter(int argc, const char* const *argv,
const char* llvmdir /*= 0*/, bool noRuntime) :
m_UniqueCounter(0), m_PrintDebug(false), m_DynamicLookupDeclared(false),
m_DynamicLookupEnabled(false), m_RawInputEnabled(false) {
m_DynamicLookupEnabled(false), m_RawInputEnabled(false), m_RecursivePrintDepth(2) {

m_LLVMContext.reset(new llvm::LLVMContext);
std::vector<unsigned> LeftoverArgsIdx;
Expand Down
46 changes: 24 additions & 22 deletions interpreter/cling/lib/Interpreter/ValuePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ static std::string executePrintValue(const Value &V, const T &val) {
printValueSS << "cling::printValue(";
printValueSS << getTypeString(V);
printValueSS << (const void *) &val;
printValueSS << ", ";
printValueSS << Interp->getRecursivePrintDepth();
printValueSS << ");";
Value printValueV;
Interp->evaluate(printValueSS.str(), printValueV);
Expand Down Expand Up @@ -362,7 +364,7 @@ static std::string printUnpackedClingValue(const Value &V) {
namespace cling {

// General fallback - prints the address
std::string printValue(const void *ptr) {
std::string printValue(const void *ptr, unsigned int) {
if (!ptr) {
return "nullptr";
} else {
Expand All @@ -375,7 +377,7 @@ namespace cling {
}

// void pointer
std::string printValue(const void **ptr) {
std::string printValue(const void **ptr, unsigned int) {
if (!*ptr) {
return "nullptr";
} else {
Expand All @@ -388,7 +390,7 @@ namespace cling {
}

// Bool
std::string printValue(const bool *val) {
std::string printValue(const bool *val, unsigned int) {
return *val ? "true" : "false";
}

Expand All @@ -407,88 +409,88 @@ namespace cling {
return strm.str();
}

std::string printValue(const char *val) {
std::string printValue(const char *val, unsigned int) {
return printChar(*val, true);
}

std::string printValue(const signed char *val) {
std::string printValue(const signed char *val, unsigned int) {
return printChar(*val, true);
}

std::string printValue(const unsigned char *val) {
std::string printValue(const unsigned char *val, unsigned int) {
return printChar(*val, true);
}

// Ints
std::string printValue(const short *val) {
std::string printValue(const short *val, unsigned int) {
std::ostringstream strm;
strm << *val;
return strm.str();
}

std::string printValue(const unsigned short *val) {
std::string printValue(const unsigned short *val, unsigned int) {
std::ostringstream strm;
strm << *val;
return strm.str();
}

std::string printValue(const int *val) {
std::string printValue(const int *val, unsigned int) {
std::ostringstream strm;
strm << *val;
return strm.str();
}

std::string printValue(const unsigned int *val) {
std::string printValue(const unsigned int *val, unsigned int) {
std::ostringstream strm;
strm << *val;
return strm.str();
}

std::string printValue(const long *val) {
std::string printValue(const long *val, unsigned int) {
std::ostringstream strm;
strm << *val;
return strm.str();
}

std::string printValue(const unsigned long *val) {
std::string printValue(const unsigned long *val, unsigned int) {
std::ostringstream strm;
strm << *val;
return strm.str();
}

std::string printValue(const long long *val) {
std::string printValue(const long long *val, unsigned int) {
std::ostringstream strm;
strm << *val;
return strm.str();
}

std::string printValue(const unsigned long long *val) {
std::string printValue(const unsigned long long *val, unsigned int) {
std::ostringstream strm;
strm << *val;
return strm.str();
}

// Reals
std::string printValue(const float *val) {
std::string printValue(const float *val, unsigned int) {
std::ostringstream strm;
strm << std::showpoint << *val << "f";
return strm.str();
}

std::string printValue(const double *val) {
std::string printValue(const double *val, unsigned int) {
std::ostringstream strm;
strm << std::showpoint << *val;
return strm.str();
}

std::string printValue(const long double *val) {
std::string printValue(const long double *val, unsigned int) {
std::ostringstream strm;
strm << *val << "L";
return strm.str();
}

// Char pointers
std::string printValue(const char *const *val) {
std::string printValue(const char *const *val, unsigned int) {
if (!*val) {
return "nullptr";
} else {
Expand All @@ -503,17 +505,17 @@ namespace cling {
}
}

std::string printValue(const char **val) {
return printValue((const char *const *) val);
std::string printValue(const char **val, unsigned int recurseDepth) {
return printValue((const char *const *) val, recurseDepth);
}

// std::string
std::string printValue(const std::string *val) {
std::string printValue(const std::string *val, unsigned int) {
return "\"" + *val + "\"";
}

// cling::Value
std::string printValue(const Value *value) {
std::string printValue(const Value *value, unsigned int) {
std::ostringstream strm;

if (!value->isValid()) {
Expand Down
22 changes: 21 additions & 1 deletion interpreter/cling/lib/MetaProcessor/MetaParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ namespace cling {
|| isXCommand(actionResult, resultValue) ||isTCommand(actionResult)
|| isAtCommand()
|| isqCommand() || isUCommand(actionResult) || isICommand()
|| isOCommand() || israwInputCommand()
|| isOCommand() || israwInputCommand() || isRecursivePrintDepthCommand()
|| isdebugCommand() || isprintDebugCommand()
|| isdynamicExtensionsCommand() || ishelpCommand() || isfileExCommand()
|| isfilesCommand() || isClassCommand() || isNamespaceCommand() || isgCommand()
Expand Down Expand Up @@ -380,6 +380,26 @@ namespace cling {
return false;
}

bool MetaParser::isRecursivePrintDepthCommand() {
if (getCurTok().is(tok::ident) &&
getCurTok().getIdent().equals("printDepth")) {
consumeToken();
skipWhitespace();
if (getCurTok().is(tok::constant)) {
unsigned short depth = getCurTok().getConstant();
m_Actions->actOnRecursivePrintDepthCommand(depth);
return true;
} else if (getCurTok().is(tok::eof)){
m_Actions->actOnRecursivePrintDepthCommand((unsigned int)-1);
return true;
} else {
m_Actions->getMetaProcessor().getOuts() << "ERROR: \""
<< getCurTok().getBufStart() << "\" is not a natural number.\n";
}
}
return false;
}

bool MetaParser::isdebugCommand() {
if (getCurTok().is(tok::ident) &&
getCurTok().getIdent().equals("debug")) {
Expand Down
Loading

0 comments on commit e0ff729

Please sign in to comment.