diff options
Diffstat (limited to 'third_party/nix/src/libexpr/value.hh')
-rw-r--r-- | third_party/nix/src/libexpr/value.hh | 380 |
1 files changed, 173 insertions, 207 deletions
diff --git a/third_party/nix/src/libexpr/value.hh b/third_party/nix/src/libexpr/value.hh index e1ec87d3b84c..211b1669f8d4 100644 --- a/third_party/nix/src/libexpr/value.hh +++ b/third_party/nix/src/libexpr/value.hh @@ -8,28 +8,26 @@ namespace nix { - typedef enum { - tInt = 1, - tBool, - tString, - tPath, - tNull, - tAttrs, - tList1, - tList2, - tListN, - tThunk, - tApp, - tLambda, - tBlackhole, - tPrimOp, - tPrimOpApp, - tExternal, - tFloat + tInt = 1, + tBool, + tString, + tPath, + tNull, + tAttrs, + tList1, + tList2, + tListN, + tThunk, + tApp, + tLambda, + tBlackhole, + tPrimOp, + tPrimOpApp, + tExternal, + tFloat } ValueType; - class Bindings; struct Env; struct Expr; @@ -42,233 +40,201 @@ class EvalState; class XMLWriter; class JSONPlaceholder; - typedef int64_t NixInt; typedef double NixFloat; /* External values must descend from ExternalValueBase, so that * type-agnostic nix functions (e.g. showType) can be implemented */ -class ExternalValueBase -{ - friend std::ostream & operator << (std::ostream & str, const ExternalValueBase & v); - protected: - /* Print out the value */ - virtual std::ostream & print(std::ostream & str) const = 0; - - public: - /* Return a simple string describing the type */ - virtual string showType() const = 0; - - /* Return a string to be used in builtins.typeOf */ - virtual string typeOf() const = 0; - - /* How much space does this value take up */ - virtual size_t valueSize(std::set<const void *> & seen) const = 0; - - /* Coerce the value to a string. Defaults to uncoercable, i.e. throws an - * error - */ - virtual string coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore) const; - - /* Compare to another value of the same type. Defaults to uncomparable, - * i.e. always false. - */ - virtual bool operator==(const ExternalValueBase & b) const; - - /* Print the value as JSON. Defaults to unconvertable, i.e. throws an error */ - virtual void printValueAsJSON(EvalState & state, bool strict, - JSONPlaceholder & out, PathSet & context) const; - - /* Print the value as XML. Defaults to unevaluated */ - virtual void printValueAsXML(EvalState & state, bool strict, bool location, - XMLWriter & doc, PathSet & context, PathSet & drvsSeen) const; - - virtual ~ExternalValueBase() - { - }; -}; - -std::ostream & operator << (std::ostream & str, const ExternalValueBase & v); - - -struct Value -{ - ValueType type; - union - { - NixInt integer; - bool boolean; - - /* Strings in the evaluator carry a so-called `context' which - is a list of strings representing store paths. This is to - allow users to write things like - - "--with-freetype2-library=" + freetype + "/lib" - - where `freetype' is a derivation (or a source to be copied - to the store). If we just concatenated the strings without - keeping track of the referenced store paths, then if the - string is used as a derivation attribute, the derivation - will not have the correct dependencies in its inputDrvs and - inputSrcs. - - The semantics of the context is as follows: when a string - with context C is used as a derivation attribute, then the - derivations in C will be added to the inputDrvs of the - derivation, and the other store paths in C will be added to - the inputSrcs of the derivations. - - For canonicity, the store paths should be in sorted order. */ - struct { - const char * s; - const char * * context; // must be in sorted order - } string; - - const char * path; - Bindings * attrs; - struct { - size_t size; - Value * * elems; - } bigList; - Value * smallList[2]; - struct { - Env * env; - Expr * expr; - } thunk; - struct { - Value * left, * right; - } app; - struct { - Env * env; - ExprLambda * fun; - } lambda; - PrimOp * primOp; - struct { - Value * left, * right; - } primOpApp; - ExternalValueBase * external; - NixFloat fpoint; - }; - - bool isList() const - { - return type == tList1 || type == tList2 || type == tListN; - } - - Value * * listElems() - { - return type == tList1 || type == tList2 ? smallList : bigList.elems; - } - - const Value * const * listElems() const - { - return type == tList1 || type == tList2 ? smallList : bigList.elems; - } - - size_t listSize() const - { - return type == tList1 ? 1 : type == tList2 ? 2 : bigList.size; - } -}; +class ExternalValueBase { + friend std::ostream& operator<<(std::ostream& str, + const ExternalValueBase& v); + protected: + /* Print out the value */ + virtual std::ostream& print(std::ostream& str) const = 0; -/* After overwriting an app node, be sure to clear pointers in the - Value to ensure that the target isn't kept alive unnecessarily. */ -static inline void clearValue(Value & v) -{ - v.app.left = v.app.right = 0; -} + public: + /* Return a simple string describing the type */ + virtual string showType() const = 0; + /* Return a string to be used in builtins.typeOf */ + virtual string typeOf() const = 0; -static inline void mkInt(Value & v, NixInt n) -{ - clearValue(v); - v.type = tInt; - v.integer = n; -} + /* How much space does this value take up */ + virtual size_t valueSize(std::set<const void*>& seen) const = 0; + /* Coerce the value to a string. Defaults to uncoercable, i.e. throws an + * error + */ + virtual string coerceToString(const Pos& pos, PathSet& context, bool copyMore, + bool copyToStore) const; -static inline void mkFloat(Value & v, NixFloat n) -{ - clearValue(v); - v.type = tFloat; - v.fpoint = n; -} + /* Compare to another value of the same type. Defaults to uncomparable, + * i.e. always false. + */ + virtual bool operator==(const ExternalValueBase& b) const; + /* Print the value as JSON. Defaults to unconvertable, i.e. throws an error */ + virtual void printValueAsJSON(EvalState& state, bool strict, + JSONPlaceholder& out, PathSet& context) const; -static inline void mkBool(Value & v, bool b) -{ - clearValue(v); - v.type = tBool; - v.boolean = b; -} + /* Print the value as XML. Defaults to unevaluated */ + virtual void printValueAsXML(EvalState& state, bool strict, bool location, + XMLWriter& doc, PathSet& context, + PathSet& drvsSeen) const; + virtual ~ExternalValueBase(){}; +}; -static inline void mkNull(Value & v) -{ - clearValue(v); - v.type = tNull; -} +std::ostream& operator<<(std::ostream& str, const ExternalValueBase& v); + +struct Value { + ValueType type; + union { + NixInt integer; + bool boolean; + + /* Strings in the evaluator carry a so-called `context' which + is a list of strings representing store paths. This is to + allow users to write things like + + "--with-freetype2-library=" + freetype + "/lib" + + where `freetype' is a derivation (or a source to be copied + to the store). If we just concatenated the strings without + keeping track of the referenced store paths, then if the + string is used as a derivation attribute, the derivation + will not have the correct dependencies in its inputDrvs and + inputSrcs. + + The semantics of the context is as follows: when a string + with context C is used as a derivation attribute, then the + derivations in C will be added to the inputDrvs of the + derivation, and the other store paths in C will be added to + the inputSrcs of the derivations. + + For canonicity, the store paths should be in sorted order. */ + struct { + const char* s; + const char** context; // must be in sorted order + } string; + + const char* path; + Bindings* attrs; + struct { + size_t size; + Value** elems; + } bigList; + Value* smallList[2]; + struct { + Env* env; + Expr* expr; + } thunk; + struct { + Value *left, *right; + } app; + struct { + Env* env; + ExprLambda* fun; + } lambda; + PrimOp* primOp; + struct { + Value *left, *right; + } primOpApp; + ExternalValueBase* external; + NixFloat fpoint; + }; + + bool isList() const { + return type == tList1 || type == tList2 || type == tListN; + } + + Value** listElems() { + return type == tList1 || type == tList2 ? smallList : bigList.elems; + } + + const Value* const* listElems() const { + return type == tList1 || type == tList2 ? smallList : bigList.elems; + } + + size_t listSize() const { + return type == tList1 ? 1 : type == tList2 ? 2 : bigList.size; + } +}; +/* After overwriting an app node, be sure to clear pointers in the + Value to ensure that the target isn't kept alive unnecessarily. */ +static inline void clearValue(Value& v) { v.app.left = v.app.right = 0; } -static inline void mkApp(Value & v, Value & left, Value & right) -{ - v.type = tApp; - v.app.left = &left; - v.app.right = &right; +static inline void mkInt(Value& v, NixInt n) { + clearValue(v); + v.type = tInt; + v.integer = n; } - -static inline void mkPrimOpApp(Value & v, Value & left, Value & right) -{ - v.type = tPrimOpApp; - v.app.left = &left; - v.app.right = &right; +static inline void mkFloat(Value& v, NixFloat n) { + clearValue(v); + v.type = tFloat; + v.fpoint = n; } - -static inline void mkStringNoCopy(Value & v, const char * s) -{ - v.type = tString; - v.string.s = s; - v.string.context = 0; +static inline void mkBool(Value& v, bool b) { + clearValue(v); + v.type = tBool; + v.boolean = b; } - -static inline void mkString(Value & v, const Symbol & s) -{ - mkStringNoCopy(v, ((const string &) s).c_str()); +static inline void mkNull(Value& v) { + clearValue(v); + v.type = tNull; } +static inline void mkApp(Value& v, Value& left, Value& right) { + v.type = tApp; + v.app.left = &left; + v.app.right = &right; +} -void mkString(Value & v, const char * s); +static inline void mkPrimOpApp(Value& v, Value& left, Value& right) { + v.type = tPrimOpApp; + v.app.left = &left; + v.app.right = &right; +} +static inline void mkStringNoCopy(Value& v, const char* s) { + v.type = tString; + v.string.s = s; + v.string.context = 0; +} -static inline void mkPathNoCopy(Value & v, const char * s) -{ - clearValue(v); - v.type = tPath; - v.path = s; +static inline void mkString(Value& v, const Symbol& s) { + mkStringNoCopy(v, ((const string&)s).c_str()); } +void mkString(Value& v, const char* s); -void mkPath(Value & v, const char * s); +static inline void mkPathNoCopy(Value& v, const char* s) { + clearValue(v); + v.type = tPath; + v.path = s; +} +void mkPath(Value& v, const char* s); /* Compute the size in bytes of the given value, including all values and environments reachable from it. Static expressions (Exprs) are not included. */ -size_t valueSize(Value & v); - +size_t valueSize(Value& v); #if HAVE_BOEHMGC -typedef std::vector<Value *, gc_allocator<Value *> > ValueVector; -typedef std::map<Symbol, Value *, std::less<Symbol>, gc_allocator<std::pair<const Symbol, Value *> > > ValueMap; +typedef std::vector<Value*, gc_allocator<Value*> > ValueVector; +typedef std::map<Symbol, Value*, std::less<Symbol>, + gc_allocator<std::pair<const Symbol, Value*> > > + ValueMap; #else -typedef std::vector<Value *> ValueVector; -typedef std::map<Symbol, Value *> ValueMap; +typedef std::vector<Value*> ValueVector; +typedef std::map<Symbol, Value*> ValueMap; #endif - -} +} // namespace nix |