repl indenting

This commit is contained in:
Ben Burdette 2020-06-24 13:10:41 -06:00
parent 6fe660acf9
commit b18ed02b76
4 changed files with 183 additions and 190 deletions

View file

@ -16,7 +16,7 @@ makefiles = \
misc/upstart/local.mk \ misc/upstart/local.mk \
doc/manual/local.mk \ doc/manual/local.mk \
tests/local.mk \ tests/local.mk \
tests/plugins/local.mk tests/plugins/local.mk
-include Makefile.config -include Makefile.config

View file

@ -10,8 +10,6 @@ namespace nix {
const std::string nativeSystem = SYSTEM; const std::string nativeSystem = SYSTEM;
// Traces show the chain of calls in nix code. If an ErrPos is included the surrounding
// lines of code will print.
BaseError & BaseError::addTrace(std::optional<ErrPos> e, hintformat hint) BaseError & BaseError::addTrace(std::optional<ErrPos> e, hintformat hint)
{ {
err.traces.push_front(Trace { .pos = e, .hint = hint}); err.traces.push_front(Trace { .pos = e, .hint = hint});

View file

@ -119,9 +119,6 @@ protected:
// string prefix_; // used for location traces etc. // string prefix_; // used for location traces etc.
mutable ErrorInfo err; mutable ErrorInfo err;
// mutable std::optional<string> trace_;
// const string& calcTrace() const;
mutable std::optional<string> what_; mutable std::optional<string> what_;
const string& calcWhat() const; const string& calcWhat() const;
@ -167,11 +164,9 @@ public:
#endif #endif
const string & msg() const { return calcWhat(); } const string & msg() const { return calcWhat(); }
// const string & trace() const { return calcTrace(); }
// BaseError & addPrefix(const FormatOrString & fs);
BaseError & addTrace(std::optional<ErrPos> e, hintformat hint);
const ErrorInfo & info() { calcWhat(); return err; } const ErrorInfo & info() { calcWhat(); return err; }
BaseError & addTrace(std::optional<ErrPos> e, hintformat hint);
}; };
#define MakeError(newClass, superClass) \ #define MakeError(newClass, superClass) \

View file

@ -101,74 +101,74 @@ NixRepl::~NixRepl()
static NixRepl * curRepl; // ugly static NixRepl * curRepl; // ugly
static char * completionCallback(char * s, int *match) { static char * completionCallback(char * s, int *match) {
auto possible = curRepl->completePrefix(s); auto possible = curRepl->completePrefix(s);
if (possible.size() == 1) { if (possible.size() == 1) {
*match = 1;
auto *res = strdup(possible.begin()->c_str() + strlen(s));
if (!res) throw Error("allocation failure");
return res;
} else if (possible.size() > 1) {
auto checkAllHaveSameAt = [&](size_t pos) {
auto &first = *possible.begin();
for (auto &p : possible) {
if (p.size() <= pos || p[pos] != first[pos])
return false;
}
return true;
};
size_t start = strlen(s);
size_t len = 0;
while (checkAllHaveSameAt(start + len)) ++len;
if (len > 0) {
*match = 1; *match = 1;
auto *res = strdup(possible.begin()->c_str() + strlen(s)); auto *res = strdup(std::string(*possible.begin(), start, len).c_str());
if (!res) throw Error("allocation failure"); if (!res) throw Error("allocation failure");
return res; return res;
} else if (possible.size() > 1) { }
auto checkAllHaveSameAt = [&](size_t pos) { }
auto &first = *possible.begin();
for (auto &p : possible) {
if (p.size() <= pos || p[pos] != first[pos])
return false;
}
return true;
};
size_t start = strlen(s);
size_t len = 0;
while (checkAllHaveSameAt(start + len)) ++len;
if (len > 0) {
*match = 1;
auto *res = strdup(std::string(*possible.begin(), start, len).c_str());
if (!res) throw Error("allocation failure");
return res;
}
}
*match = 0; *match = 0;
return nullptr; return nullptr;
} }
static int listPossibleCallback(char *s, char ***avp) { static int listPossibleCallback(char *s, char ***avp) {
auto possible = curRepl->completePrefix(s); auto possible = curRepl->completePrefix(s);
if (possible.size() > (INT_MAX / sizeof(char*))) if (possible.size() > (INT_MAX / sizeof(char*)))
throw Error("too many completions"); throw Error("too many completions");
int ac = 0; int ac = 0;
char **vp = nullptr; char **vp = nullptr;
auto check = [&](auto *p) { auto check = [&](auto *p) {
if (!p) { if (!p) {
if (vp) { if (vp) {
while (--ac >= 0) while (--ac >= 0)
free(vp[ac]); free(vp[ac]);
free(vp); free(vp);
} }
throw Error("allocation failure"); throw Error("allocation failure");
} }
return p; return p;
}; };
vp = check((char **)malloc(possible.size() * sizeof(char*))); vp = check((char **)malloc(possible.size() * sizeof(char*)));
for (auto & p : possible) for (auto & p : possible)
vp[ac++] = check(strdup(p.c_str())); vp[ac++] = check(strdup(p.c_str()));
*avp = vp; *avp = vp;
return ac; return ac;
} }
namespace { namespace {
// Used to communicate to NixRepl::getLine whether a signal occurred in ::readline. // Used to communicate to NixRepl::getLine whether a signal occurred in ::readline.
volatile sig_atomic_t g_signal_received = 0; volatile sig_atomic_t g_signal_received = 0;
void sigintHandler(int signo) { void sigintHandler(int signo) {
g_signal_received = signo; g_signal_received = signo;
} }
} }
void NixRepl::mainLoop(const std::vector<std::string> & files) void NixRepl::mainLoop(const std::vector<std::string> & files)
@ -235,24 +235,24 @@ bool NixRepl::getLine(string & input, const std::string &prompt)
sigset_t savedSignalMask, set; sigset_t savedSignalMask, set;
auto setupSignals = [&]() { auto setupSignals = [&]() {
act.sa_handler = sigintHandler; act.sa_handler = sigintHandler;
sigfillset(&act.sa_mask); sigfillset(&act.sa_mask);
act.sa_flags = 0; act.sa_flags = 0;
if (sigaction(SIGINT, &act, &old)) if (sigaction(SIGINT, &act, &old))
throw SysError("installing handler for SIGINT"); throw SysError("installing handler for SIGINT");
sigemptyset(&set); sigemptyset(&set);
sigaddset(&set, SIGINT); sigaddset(&set, SIGINT);
if (sigprocmask(SIG_UNBLOCK, &set, &savedSignalMask)) if (sigprocmask(SIG_UNBLOCK, &set, &savedSignalMask))
throw SysError("unblocking SIGINT"); throw SysError("unblocking SIGINT");
}; };
auto restoreSignals = [&]() { auto restoreSignals = [&]() {
if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr)) if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr))
throw SysError("restoring signals"); throw SysError("restoring signals");
if (sigaction(SIGINT, &old, 0)) if (sigaction(SIGINT, &old, 0))
throw SysError("restoring handler for SIGINT"); throw SysError("restoring handler for SIGINT");
}; };
setupSignals(); setupSignals();
char * s = readline(prompt.c_str()); char * s = readline(prompt.c_str());
@ -266,7 +266,7 @@ bool NixRepl::getLine(string & input, const std::string &prompt)
} }
if (!s) if (!s)
return false; return false;
input += s; input += s;
input += '\n'; input += '\n';
return true; return true;
@ -399,21 +399,21 @@ bool NixRepl::processLine(string line)
if (command == ":?" || command == ":help") { if (command == ":?" || command == ":help") {
std::cout std::cout
<< "The following commands are available:\n" << "The following commands are available:\n"
<< "\n" << "\n"
<< " <expr> Evaluate and print expression\n" << " <expr> Evaluate and print expression\n"
<< " <x> = <expr> Bind expression to variable\n" << " <x> = <expr> Bind expression to variable\n"
<< " :a <expr> Add attributes from resulting set to scope\n" << " :a <expr> Add attributes from resulting set to scope\n"
<< " :b <expr> Build derivation\n" << " :b <expr> Build derivation\n"
<< " :e <expr> Open the derivation in $EDITOR\n" << " :e <expr> Open the derivation in $EDITOR\n"
<< " :i <expr> Build derivation, then install result into current profile\n" << " :i <expr> Build derivation, then install result into current profile\n"
<< " :l <path> Load Nix expression and add it to scope\n" << " :l <path> Load Nix expression and add it to scope\n"
<< " :p <expr> Evaluate and print expression recursively\n" << " :p <expr> Evaluate and print expression recursively\n"
<< " :q Exit nix-repl\n" << " :q Exit nix-repl\n"
<< " :r Reload all files\n" << " :r Reload all files\n"
<< " :s <expr> Build dependencies of derivation, then start nix-shell\n" << " :s <expr> Build dependencies of derivation, then start nix-shell\n"
<< " :t <expr> Describe result of evaluation\n" << " :t <expr> Describe result of evaluation\n"
<< " :u <expr> Build derivation, then start nix-shell\n"; << " :u <expr> Build derivation, then start nix-shell\n";
} }
else if (command == ":a" || command == ":add") { else if (command == ":a" || command == ":add") {
@ -639,118 +639,118 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
switch (v.type) { switch (v.type) {
case tInt: case tInt:
str << ANSI_CYAN << v.integer << ANSI_NORMAL; str << ANSI_CYAN << v.integer << ANSI_NORMAL;
break; break;
case tBool: case tBool:
str << ANSI_CYAN << (v.boolean ? "true" : "false") << ANSI_NORMAL; str << ANSI_CYAN << (v.boolean ? "true" : "false") << ANSI_NORMAL;
break; break;
case tString: case tString:
str << ANSI_YELLOW; str << ANSI_YELLOW;
printStringValue(str, v.string.s); printStringValue(str, v.string.s);
str << ANSI_NORMAL; str << ANSI_NORMAL;
break; break;
case tPath: case tPath:
str << ANSI_GREEN << v.path << ANSI_NORMAL; // !!! escaping? str << ANSI_GREEN << v.path << ANSI_NORMAL; // !!! escaping?
break; break;
case tNull: case tNull:
str << ANSI_CYAN "null" ANSI_NORMAL; str << ANSI_CYAN "null" ANSI_NORMAL;
break; break;
case tAttrs: { case tAttrs: {
seen.insert(&v); seen.insert(&v);
bool isDrv = state->isDerivation(v); bool isDrv = state->isDerivation(v);
if (isDrv) { if (isDrv) {
str << "«derivation "; str << "«derivation ";
Bindings::iterator i = v.attrs->find(state->sDrvPath); Bindings::iterator i = v.attrs->find(state->sDrvPath);
PathSet context; PathSet context;
Path drvPath = i != v.attrs->end() ? state->coerceToPath(*i->pos, *i->value, context) : "???"; Path drvPath = i != v.attrs->end() ? state->coerceToPath(*i->pos, *i->value, context) : "???";
str << drvPath << "»"; str << drvPath << "»";
}
else if (maxDepth > 0) {
str << "{ ";
typedef std::map<string, Value *> Sorted;
Sorted sorted;
for (auto & i : *v.attrs)
sorted[i.name] = i.value;
for (auto & i : sorted) {
if (isVarName(i.first))
str << i.first;
else
printStringValue(str, i.first.c_str());
str << " = ";
if (seen.find(i.second) != seen.end())
str << "«repeated»";
else
try {
printValue(str, *i.second, maxDepth - 1, seen);
} catch (AssertionError & e) {
str << ANSI_RED "«error: " << e.msg() << "»" ANSI_NORMAL;
}
str << "; ";
} }
else if (maxDepth > 0) { str << "}";
str << "{ "; } else
str << "{ ... }";
typedef std::map<string, Value *> Sorted; break;
Sorted sorted; }
for (auto & i : *v.attrs)
sorted[i.name] = i.value;
for (auto & i : sorted) { case tList1:
if (isVarName(i.first)) case tList2:
str << i.first; case tListN:
else seen.insert(&v);
printStringValue(str, i.first.c_str());
str << " = ";
if (seen.find(i.second) != seen.end())
str << "«repeated»";
else
try {
printValue(str, *i.second, maxDepth - 1, seen);
} catch (AssertionError & e) {
str << ANSI_RED "«error: " << e.msg() << "»" ANSI_NORMAL;
}
str << "; ";
}
str << "}"; str << "[ ";
} else if (maxDepth > 0)
str << "{ ... }"; for (unsigned int n = 0; n < v.listSize(); ++n) {
if (seen.find(v.listElems()[n]) != seen.end())
str << "«repeated»";
else
try {
printValue(str, *v.listElems()[n], maxDepth - 1, seen);
} catch (AssertionError & e) {
str << ANSI_RED "«error: " << e.msg() << "»" ANSI_NORMAL;
}
str << " ";
}
else
str << "... ";
str << "]";
break;
break; case tLambda: {
} std::ostringstream s;
s << v.lambda.fun->pos;
str << ANSI_BLUE "«lambda @ " << filterANSIEscapes(s.str()) << "»" ANSI_NORMAL;
break;
}
case tList1: case tPrimOp:
case tList2: str << ANSI_MAGENTA "«primop»" ANSI_NORMAL;
case tListN: break;
seen.insert(&v);
str << "[ "; case tPrimOpApp:
if (maxDepth > 0) str << ANSI_BLUE "«primop-app»" ANSI_NORMAL;
for (unsigned int n = 0; n < v.listSize(); ++n) { break;
if (seen.find(v.listElems()[n]) != seen.end())
str << "«repeated»";
else
try {
printValue(str, *v.listElems()[n], maxDepth - 1, seen);
} catch (AssertionError & e) {
str << ANSI_RED "«error: " << e.msg() << "»" ANSI_NORMAL;
}
str << " ";
}
else
str << "... ";
str << "]";
break;
case tLambda: { case tFloat:
std::ostringstream s; str << v.fpoint;
s << v.lambda.fun->pos; break;
str << ANSI_BLUE "«lambda @ " << filterANSIEscapes(s.str()) << "»" ANSI_NORMAL;
break;
}
case tPrimOp: default:
str << ANSI_MAGENTA "«primop»" ANSI_NORMAL; str << ANSI_RED "«unknown»" ANSI_NORMAL;
break; break;
case tPrimOpApp:
str << ANSI_BLUE "«primop-app»" ANSI_NORMAL;
break;
case tFloat:
str << v.fpoint;
break;
default:
str << ANSI_RED "«unknown»" ANSI_NORMAL;
break;
} }
return str; return str;
@ -773,10 +773,10 @@ struct CmdRepl : StoreCommand, MixEvalArgs
Examples examples() override Examples examples() override
{ {
return { return {
Example{ Example{
"Display all special commands within the REPL:", "Display all special commands within the REPL:",
"nix repl\n nix-repl> :?" "nix repl\n nix-repl> :?"
} }
}; };
} }