mirror of
https://github.com/NixOS/nix
synced 2025-06-26 15:51:15 +02:00
* More primops.
This commit is contained in:
parent
c3aa615a5f
commit
c9170be2bd
4 changed files with 92 additions and 184 deletions
|
@ -405,21 +405,35 @@ void EvalState::eval(Env & env, Expr e, Value & v)
|
|||
}
|
||||
|
||||
if (matchConcatStrings(e, es)) {
|
||||
unsigned int n = ATgetLength(es), j = 0;
|
||||
Value vs[n];
|
||||
unsigned int len = 0;
|
||||
for (ATermIterator i(es); i; ++i, ++j) {
|
||||
eval(env, *i, vs[j]);
|
||||
if (vs[j].type != tString) throw TypeError("string expected");
|
||||
len += strlen(vs[j].string.s);
|
||||
PathSet context;
|
||||
std::ostringstream s;
|
||||
|
||||
bool first = true, isPath;
|
||||
|
||||
for (ATermIterator i(es); i; ++i) {
|
||||
eval(env, *i, v);
|
||||
|
||||
/* If the first element is a path, then the result will
|
||||
also be a path, we don't copy anything (yet - that's
|
||||
done later, since paths are copied when they are used
|
||||
in a derivation), and none of the strings are allowed
|
||||
to have contexts. */
|
||||
if (first) {
|
||||
isPath = v.type == tPath;
|
||||
first = false;
|
||||
}
|
||||
|
||||
s << coerceToString(v, context, false, !isPath);
|
||||
}
|
||||
char * s = new char[len + 1], * t = s;
|
||||
for (unsigned int i = 0; i < j; ++i) {
|
||||
strcpy(t, vs[i].string.s);
|
||||
t += strlen(vs[i].string.s);
|
||||
}
|
||||
*t = 0;
|
||||
mkString(v, s);
|
||||
|
||||
if (isPath && !context.empty())
|
||||
throw EvalError(format("a string that refers to a store path cannot be appended to a path, in `%1%'")
|
||||
% s.str());
|
||||
|
||||
if (isPath)
|
||||
mkPath(v, strdup(s.str().c_str()));
|
||||
else
|
||||
mkString(v, strdup(s.str().c_str())); // !!! context
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -969,116 +983,6 @@ ATermList flattenList(EvalState & state, Expr e)
|
|||
}
|
||||
|
||||
|
||||
string coerceToString(EvalState & state, Expr e, PathSet & context,
|
||||
bool coerceMore, bool copyToStore)
|
||||
{
|
||||
e = evalExpr(state, e);
|
||||
|
||||
string s;
|
||||
|
||||
if (matchStr(e, s, context)) return s;
|
||||
|
||||
ATerm s2;
|
||||
if (matchPath(e, s2)) {
|
||||
Path path(canonPath(aterm2String(s2)));
|
||||
|
||||
if (!copyToStore) return path;
|
||||
|
||||
if (isDerivation(path))
|
||||
throw EvalError(format("file names are not allowed to end in `%1%'")
|
||||
% drvExtension);
|
||||
|
||||
Path dstPath;
|
||||
if (state.srcToStore[path] != "")
|
||||
dstPath = state.srcToStore[path];
|
||||
else {
|
||||
dstPath = readOnlyMode
|
||||
? computeStorePathForPath(path).first
|
||||
: store->addToStore(path);
|
||||
state.srcToStore[path] = dstPath;
|
||||
printMsg(lvlChatty, format("copied source `%1%' -> `%2%'")
|
||||
% path % dstPath);
|
||||
}
|
||||
|
||||
context.insert(dstPath);
|
||||
return dstPath;
|
||||
}
|
||||
|
||||
ATermList es;
|
||||
if (matchAttrs(e, es)) {
|
||||
Expr e2 = queryAttr(e, "outPath");
|
||||
if (!e2) throwTypeError("cannot coerce an attribute set (except a derivation) to a string");
|
||||
return coerceToString(state, e2, context, coerceMore, copyToStore);
|
||||
}
|
||||
|
||||
if (coerceMore) {
|
||||
|
||||
/* Note that `false' is represented as an empty string for
|
||||
shell scripting convenience, just like `null'. */
|
||||
if (e == eTrue) return "1";
|
||||
if (e == eFalse) return "";
|
||||
int n;
|
||||
if (matchInt(e, n)) return int2String(n);
|
||||
if (matchNull(e)) return "";
|
||||
|
||||
if (matchList(e, es)) {
|
||||
string result;
|
||||
es = flattenList(state, e);
|
||||
bool first = true;
|
||||
for (ATermIterator i(es); i; ++i) {
|
||||
if (!first) result += " "; else first = false;
|
||||
result += coerceToString(state, *i,
|
||||
context, coerceMore, copyToStore);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
throwTypeError("cannot coerce %1% to a string", showType(e));
|
||||
}
|
||||
|
||||
|
||||
/* Common implementation of `+', ConcatStrings and `~'. */
|
||||
static ATerm concatStrings(EvalState & state, ATermVector & args,
|
||||
string separator = "")
|
||||
{
|
||||
if (args.empty()) return makeStr("", PathSet());
|
||||
|
||||
PathSet context;
|
||||
std::ostringstream s;
|
||||
|
||||
/* If the first element is a path, then the result will also be a
|
||||
path, we don't copy anything (yet - that's done later, since
|
||||
paths are copied when they are used in a derivation), and none
|
||||
of the strings are allowed to have contexts. */
|
||||
ATerm dummy;
|
||||
args.front() = evalExpr(state, args.front());
|
||||
bool isPath = matchPath(args.front(), dummy);
|
||||
|
||||
for (ATermVector::const_iterator i = args.begin(); i != args.end(); ++i) {
|
||||
if (i != args.begin()) s << separator;
|
||||
s << coerceToString(state, *i, context, false, !isPath);
|
||||
}
|
||||
|
||||
if (isPath && !context.empty())
|
||||
throw EvalError(format("a string that refers to a store path cannot be appended to a path, in `%1%'")
|
||||
% s.str());
|
||||
|
||||
return isPath
|
||||
? makePath(toATerm(s.str()))
|
||||
: makeStr(s.str(), context);
|
||||
}
|
||||
|
||||
|
||||
Path coerceToPath(EvalState & state, Expr e, PathSet & context)
|
||||
{
|
||||
string path = coerceToString(state, e, context, false, false);
|
||||
if (path == "" || path[0] != '/')
|
||||
throw EvalError(format("string `%1%' doesn't represent an absolute path") % path);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
Expr autoCallFunction(Expr e, const ATermMap & args)
|
||||
{
|
||||
Pattern pat;
|
||||
|
@ -1515,16 +1419,16 @@ Expr strictEvalExpr(EvalState & state, Expr e)
|
|||
#endif
|
||||
|
||||
|
||||
void printEvalStats(EvalState & state)
|
||||
void EvalState::printStats()
|
||||
{
|
||||
char x;
|
||||
bool showStats = getEnv("NIX_SHOW_STATS", "0") != "0";
|
||||
printMsg(showStats ? lvlInfo : lvlDebug,
|
||||
format("evaluated %1% expressions, used %2% bytes of stack space, allocated %3% values, allocated %4% environments")
|
||||
% state.nrEvaluated
|
||||
% nrEvaluated
|
||||
% (&x - deepestStack)
|
||||
% state.nrValues
|
||||
% state.nrEnvs);
|
||||
% nrValues
|
||||
% nrEnvs);
|
||||
if (showStats)
|
||||
printATermMapStats();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue