aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/derivations.cc30
-rw-r--r--src/libutil/util.hh9
2 files changed, 21 insertions, 18 deletions
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
index 616e78076..21ea84dbf 100644
--- a/src/libstore/derivations.cc
+++ b/src/libstore/derivations.cc
@@ -272,25 +272,19 @@ Derivation parseDerivation(const Store & store, std::string && s, std::string_vi
static void printString(string & res, std::string_view s)
{
- char * buf;
size_t bufSize = s.size() * 2 + 2;
- std::unique_ptr<char[]> dynBuf;
- if (bufSize < 0x10000) {
- buf = (char *)alloca(bufSize);
- } else {
- dynBuf = decltype(dynBuf)(new char[bufSize]);
- buf = dynBuf.get();
- }
- char * p = buf;
- *p++ = '"';
- for (auto c : s)
- if (c == '\"' || c == '\\') { *p++ = '\\'; *p++ = c; }
- else if (c == '\n') { *p++ = '\\'; *p++ = 'n'; }
- else if (c == '\r') { *p++ = '\\'; *p++ = 'r'; }
- else if (c == '\t') { *p++ = '\\'; *p++ = 't'; }
- else *p++ = c;
- *p++ = '"';
- res.append(buf, p - buf);
+ withBuffer<void, char>(bufSize, [&](char buf[]) {
+ char * p = buf;
+ *p++ = '"';
+ for (auto c : s)
+ if (c == '\"' || c == '\\') { *p++ = '\\'; *p++ = c; }
+ else if (c == '\n') { *p++ = '\\'; *p++ = 'n'; }
+ else if (c == '\r') { *p++ = '\\'; *p++ = 'r'; }
+ else if (c == '\t') { *p++ = '\\'; *p++ = 't'; }
+ else *p++ = c;
+ *p++ = '"';
+ res.append(buf, p - buf);
+ });
}
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 369c44f78..840acd67b 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -671,5 +671,14 @@ template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
std::string showBytes(uint64_t bytes);
+template<typename R = void, typename T = char> inline R withBuffer(size_t size, std::function<R (T[])> fun) {
+ if (size < 0x10000) {
+ T buf[size];
+ return fun(buf);
+ } else {
+ auto buf = std::unique_ptr<T[]>(new T[size]);
+ return fun(buf.get());
+ }
+}
}