about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-07-31T08·21+0200
committerEelco Dolstra <edolstra@gmail.com>2017-07-31T08·21+0200
commit561e977f51c1d9ec55e4a70791958d4e214df465 (patch)
tree65a667fbc746f4ff8efcaca3c0a58565985f26a5
parentc7654bc491d9ce7c1fbadecd7769418fa79a2060 (diff)
parent2fd8f8bb99a2832b3684878c020ba47322e79332 (diff)
Merge branch 'quotes' of https://github.com/Mic92/nix-1
-rw-r--r--perl/lib/Nix/Config.pm.in2
-rw-r--r--perl/lib/Nix/CopyClosure.pm4
-rw-r--r--perl/lib/Nix/Manifest.pm12
-rw-r--r--perl/lib/Nix/SSH.pm2
-rw-r--r--perl/lib/Nix/Utils.pm6
-rw-r--r--scripts/install-nix-from-closure.sh4
-rw-r--r--src/build-remote/build-remote.cc12
-rw-r--r--src/buildenv/buildenv.cc20
-rw-r--r--src/libexpr/attr-path.cc14
-rw-r--r--src/libexpr/common-opts.cc4
-rw-r--r--src/libexpr/eval.cc34
-rw-r--r--src/libexpr/get-drvs.cc4
-rw-r--r--src/libexpr/json-to-value.cc6
-rw-r--r--src/libexpr/lexer.l8
-rw-r--r--src/libexpr/nixexpr.cc4
-rw-r--r--src/libexpr/nixexpr.hh2
-rw-r--r--src/libexpr/parser.y16
-rw-r--r--src/libexpr/primops.cc108
-rw-r--r--src/libexpr/primops/fetchgit.cc18
-rw-r--r--src/libmain/shared.cc16
-rw-r--r--src/libmain/shared.hh6
-rw-r--r--src/libstore/binary-cache-store.cc18
-rw-r--r--src/libstore/build.cc204
-rw-r--r--src/libstore/builtins.cc4
-rw-r--r--src/libstore/derivations.cc12
-rw-r--r--src/libstore/download.cc30
-rw-r--r--src/libstore/export-import.cc8
-rw-r--r--src/libstore/gc.cc72
-rw-r--r--src/libstore/globals.cc2
-rw-r--r--src/libstore/http-binary-cache-store.cc2
-rw-r--r--src/libstore/legacy-ssh-store.cc12
-rw-r--r--src/libstore/local-binary-cache-store.cc2
-rw-r--r--src/libstore/local-fs-store.cc8
-rw-r--r--src/libstore/local-store.cc86
-rw-r--r--src/libstore/machines.cc2
-rw-r--r--src/libstore/misc.cc2
-rw-r--r--src/libstore/nar-accessor.cc10
-rw-r--r--src/libstore/nar-info.cc2
-rw-r--r--src/libstore/optimise-store.cc48
-rw-r--r--src/libstore/pathlocks.cc16
-rw-r--r--src/libstore/profiles.cc10
-rw-r--r--src/libstore/references.cc4
-rw-r--r--src/libstore/remote-fs-accessor.cc2
-rw-r--r--src/libstore/remote-store.cc10
-rw-r--r--src/libstore/s3-binary-cache-store.cc24
-rw-r--r--src/libstore/sqlite.cc18
-rw-r--r--src/libstore/ssh.cc4
-rw-r--r--src/libstore/store-api.cc26
-rw-r--r--src/libstore/store-api.hh2
-rw-r--r--src/libutil/archive.cc18
-rw-r--r--src/libutil/args.cc10
-rw-r--r--src/libutil/args.hh2
-rw-r--r--src/libutil/compression.cc4
-rw-r--r--src/libutil/config.cc2
-rw-r--r--src/libutil/hash.cc18
-rw-r--r--src/libutil/hash.hh2
-rw-r--r--src/libutil/serialise.hh2
-rw-r--r--src/libutil/util.cc56
-rwxr-xr-xsrc/nix-build/nix-build.cc8
-rwxr-xr-xsrc/nix-channel/nix-channel.cc14
-rwxr-xr-xsrc/nix-copy-closure/nix-copy-closure.cc4
-rw-r--r--src/nix-daemon/nix-daemon.cc12
-rw-r--r--src/nix-env/nix-env.cc62
-rw-r--r--src/nix-env/user-env.cc2
-rw-r--r--src/nix-instantiate/nix-instantiate.cc4
-rw-r--r--src/nix-prefetch-url/nix-prefetch-url.cc16
-rw-r--r--src/nix-store/dotgraph.cc2
-rw-r--r--src/nix-store/nix-store.cc48
-rw-r--r--src/nix/cat.cc4
-rw-r--r--src/nix/command.cc6
-rw-r--r--src/nix/command.hh4
-rw-r--r--src/nix/copy.cc2
-rw-r--r--src/nix/edit.cc6
-rw-r--r--src/nix/hash.cc2
-rw-r--r--src/nix/installables.cc2
-rw-r--r--src/nix/log.cc2
-rw-r--r--src/nix/ls.cc2
-rw-r--r--src/nix/main.cc6
-rw-r--r--src/nix/repl.cc4
-rw-r--r--src/nix/run.cc16
-rw-r--r--src/nix/search.cc8
-rw-r--r--src/nix/sigs.cc6
-rw-r--r--src/nix/verify.cc6
-rw-r--r--src/resolve-system-dependencies/resolve-system-dependencies.cc16
-rw-r--r--tests/timeout.nix2
-rw-r--r--tests/timeout.sh2
86 files changed, 662 insertions, 662 deletions
diff --git a/perl/lib/Nix/Config.pm.in b/perl/lib/Nix/Config.pm.in
index 4bdee7fd89f9..67a20c3f41d7 100644
--- a/perl/lib/Nix/Config.pm.in
+++ b/perl/lib/Nix/Config.pm.in
@@ -23,7 +23,7 @@ sub readConfig {
     my $config = "$confDir/nix.conf";
     return unless -f $config;
 
-    open CONFIG, "<$config" or die "cannot open ‘$config’";
+    open CONFIG, "<$config" or die "cannot open '$config'";
     while (<CONFIG>) {
         /^\s*([\w\-\.]+)\s*=\s*(.*)$/ or next;
         $config{$1} = $2;
diff --git a/perl/lib/Nix/CopyClosure.pm b/perl/lib/Nix/CopyClosure.pm
index affb3ea524ae..902ee1a1bc9f 100644
--- a/perl/lib/Nix/CopyClosure.pm
+++ b/perl/lib/Nix/CopyClosure.pm
@@ -35,14 +35,14 @@ sub copyToOpen {
     my $missingSize = 0;
     $missingSize += (queryPathInfo($_, 1))[3] foreach @missing;
 
-    printf STDERR "copying %d missing paths (%.2f MiB) to ‘$sshHost’...\n",
+    printf STDERR "copying %d missing paths (%.2f MiB) to '$sshHost'...\n",
         scalar(@missing), $missingSize / (1024**2);
     return if $dryRun;
 
     # Send the "import paths" command.
     syswrite($to, pack("L<x4", 4)) or die;
     exportPaths(fileno($to), @missing);
-    readInt($from) == 1 or die "remote machine ‘$sshHost’ failed to import closure\n";
+    readInt($from) == 1 or die "remote machine '$sshHost' failed to import closure\n";
 }
 
 
diff --git a/perl/lib/Nix/Manifest.pm b/perl/lib/Nix/Manifest.pm
index 0da376761201..6438398e1766 100644
--- a/perl/lib/Nix/Manifest.pm
+++ b/perl/lib/Nix/Manifest.pm
@@ -60,10 +60,10 @@ sub readManifest_ {
     # Decompress the manifest if necessary.
     if ($manifest =~ /\.bz2$/) {
         open MANIFEST, "$Nix::Config::bzip2 -d < $manifest |"
-            or die "cannot decompress ‘$manifest’: $!";
+            or die "cannot decompress '$manifest': $!";
     } else {
         open MANIFEST, "<$manifest"
-            or die "cannot open ‘$manifest’: $!";
+            or die "cannot open '$manifest': $!";
     }
 
     my $inside = 0;
@@ -287,7 +287,7 @@ sub parseNARInfo {
         # FIXME: might be useful to support multiple signatures per .narinfo.
 
         if (!defined $sig) {
-            warn "NAR info file ‘$location’ lacks a signature; ignoring\n";
+            warn "NAR info file '$location' lacks a signature; ignoring\n";
             return undef;
         }
         my ($keyName, $sig64) = split ":", $sig;
@@ -295,7 +295,7 @@ sub parseNARInfo {
 
         my $publicKey = $Nix::Config::binaryCachePublicKeys{$keyName};
         if (!defined $publicKey) {
-            warn "NAR info file ‘$location’ is signed by unknown key ‘$keyName’; ignoring\n";
+            warn "NAR info file '$location' is signed by unknown key '$keyName'; ignoring\n";
             return undef;
         }
 
@@ -306,12 +306,12 @@ sub parseNARInfo {
                 [ map { "$Nix::Config::storeDir/$_" } @refs ]);
         };
         if ($@) {
-            warn "cannot compute fingerprint of ‘$location’; ignoring\n";
+            warn "cannot compute fingerprint of '$location'; ignoring\n";
             return undef;
         }
 
         if (!checkSignature($publicKey, decode_base64($sig64), $fingerprint)) {
-            warn "NAR info file ‘$location’ has an incorrect signature; ignoring\n";
+            warn "NAR info file '$location' has an incorrect signature; ignoring\n";
             return undef;
         }
 
diff --git a/perl/lib/Nix/SSH.pm b/perl/lib/Nix/SSH.pm
index 95393d881450..490ba0ea991e 100644
--- a/perl/lib/Nix/SSH.pm
+++ b/perl/lib/Nix/SSH.pm
@@ -97,7 +97,7 @@ sub connectToRemoteNix {
         syswrite($to, pack("L<x4L<x4", $SERVE_MAGIC_1, $clientVersion)) or die;
         $magic = readInt($from);
     };
-    die "unable to connect to ‘$sshHost’\n" if $@;
+    die "unable to connect to '$sshHost'\n" if $@;
     die "did not get valid handshake from remote host\n" if $magic  != 0x5452eecb;
 
     my $serverVersion = readInt($from);
diff --git a/perl/lib/Nix/Utils.pm b/perl/lib/Nix/Utils.pm
index 392c45f2fffb..44955a70698c 100644
--- a/perl/lib/Nix/Utils.pm
+++ b/perl/lib/Nix/Utils.pm
@@ -10,7 +10,7 @@ $urlRE = "(?: [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!
 
 sub checkURL {
     my ($url) = @_;
-    die "invalid URL ‘$url’\n" unless $url =~ /^ $urlRE $ /x;
+    die "invalid URL '$url'\n" unless $url =~ /^ $urlRE $ /x;
 }
 
 sub uniq {
@@ -26,7 +26,7 @@ sub uniq {
 
 sub writeFile {
     my ($fn, $s) = @_;
-    open TMP, ">$fn" or die "cannot create file ‘$fn’: $!";
+    open TMP, ">$fn" or die "cannot create file '$fn': $!";
     print TMP "$s" or die;
     close TMP or die;
 }
@@ -34,7 +34,7 @@ sub writeFile {
 sub readFile {
     local $/ = undef;
     my ($fn) = @_;
-    open TMP, "<$fn" or die "cannot open file ‘$fn’: $!";
+    open TMP, "<$fn" or die "cannot open file '$fn': $!";
     my $s = <TMP>;
     close TMP or die;
     return $s;
diff --git a/scripts/install-nix-from-closure.sh b/scripts/install-nix-from-closure.sh
index 9d395020e606..3e5676f419ba 100644
--- a/scripts/install-nix-from-closure.sh
+++ b/scripts/install-nix-from-closure.sh
@@ -44,13 +44,13 @@ if ! [ -e $dest ]; then
     cmd="mkdir -m 0755 $dest && chown $USER $dest"
     echo "directory $dest does not exist; creating it by running '$cmd' using sudo" >&2
     if ! sudo sh -c "$cmd"; then
-        echo "$0: please manually run ‘$cmd’ as root to create $dest" >&2
+        echo "$0: please manually run '$cmd' as root to create $dest" >&2
         exit 1
     fi
 fi
 
 if ! [ -w $dest ]; then
-    echo "$0: directory $dest exists, but is not writable by you. This could indicate that another user has already performed a single-user installation of Nix on this system. If you wish to enable multi-user support see http://nixos.org/nix/manual/#ssec-multi-user. If you wish to continue with a single-user install for $USER please run ‘chown -R $USER $dest’ as root." >&2
+    echo "$0: directory $dest exists, but is not writable by you. This could indicate that another user has already performed a single-user installation of Nix on this system. If you wish to enable multi-user support see http://nixos.org/nix/manual/#ssec-multi-user. If you wish to continue with a single-user install for $USER please run 'chown -R $USER $dest' as root." >&2
     exit 1
 fi
 
diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc
index 8719959f0b69..d433e24913f7 100644
--- a/src/build-remote/build-remote.cc
+++ b/src/build-remote/build-remote.cc
@@ -77,7 +77,7 @@ int main (int argc, char * * argv)
             auto tokens = tokenizeString<std::vector<string>>(line);
             auto sz = tokens.size();
             if (sz != 3 && sz != 4)
-                throw Error("invalid build hook line ‘%1%’", line);
+                throw Error("invalid build hook line '%1%'", line);
             auto amWilling = tokens[0] == "1";
             auto neededSystem = tokens[1];
             drvPath = tokens[2];
@@ -99,7 +99,7 @@ int main (int argc, char * * argv)
                 Machine * bestMachine = nullptr;
                 unsigned long long bestLoad = 0;
                 for (auto & m : machines) {
-                    debug("considering building on ‘%s’", m.storeUri);
+                    debug("considering building on '%s'", m.storeUri);
 
                     if (m.enabled && std::find(m.systemTypes.begin(),
                             m.systemTypes.end(),
@@ -171,7 +171,7 @@ int main (int argc, char * * argv)
                     storeUri = bestMachine->storeUri;
 
                 } catch (std::exception & e) {
-                    printError("unable to open SSH connection to ‘%s’: %s; trying other available machines...",
+                    printError("unable to open SSH connection to '%s': %s; trying other available machines...",
                         bestMachine->storeUri, e.what());
                     bestMachine->enabled = false;
                     continue;
@@ -198,7 +198,7 @@ connected:
         auto old = signal(SIGALRM, handleAlarm);
         alarm(15 * 60);
         if (!lockFile(uploadLock.get(), ltWrite, true))
-            printError("somebody is hogging the upload lock for ‘%s’, continuing...");
+            printError("somebody is hogging the upload lock for '%s', continuing...");
         alarm(0);
         signal(SIGALRM, old);
         copyPaths(store, ref<Store>(sshStore), inputs, NoRepair, NoCheckSigs);
@@ -207,11 +207,11 @@ connected:
         BasicDerivation drv(readDerivation(drvPath));
         drv.inputSrcs = inputs;
 
-        printError("building ‘%s’ on ‘%s’", drvPath, storeUri);
+        printError("building '%s' on '%s'", drvPath, storeUri);
         auto result = sshStore->buildDerivation(drvPath, drv);
 
         if (!result.success())
-            throw Error("build of ‘%s’ on ‘%s’ failed: %s", drvPath, storeUri, result.errorMsg);
+            throw Error("build of '%s' on '%s' failed: %s", drvPath, storeUri, result.errorMsg);
 
         PathSet missing;
         for (auto & path : outputs)
diff --git a/src/buildenv/buildenv.cc b/src/buildenv/buildenv.cc
index f997096eddbb..885c5e169039 100644
--- a/src/buildenv/buildenv.cc
+++ b/src/buildenv/buildenv.cc
@@ -12,7 +12,7 @@ static bool isDirectory (const Path & path)
 {
     struct stat st;
     if (stat(path.c_str(), &st) == -1)
-        throw SysError(format("getting status of ‘%1%’") % path);
+        throw SysError(format("getting status of '%1%'") % path);
     return S_ISDIR(st.st_mode);
 }
 
@@ -53,18 +53,18 @@ static void createLinks(const Path & srcDir, const Path & dstDir, int priority)
                 } else if (S_ISLNK(dstSt.st_mode)) {
                     auto target = readLink(dstFile);
                     if (!isDirectory(target))
-                        throw Error(format("collision between ‘%1%’ and non-directory ‘%2%’")
+                        throw Error(format("collision between '%1%' and non-directory '%2%'")
                             % srcFile % target);
                     if (unlink(dstFile.c_str()) == -1)
-                        throw SysError(format("unlinking ‘%1%’") % dstFile);
+                        throw SysError(format("unlinking '%1%'") % dstFile);
                     if (mkdir(dstFile.c_str(), 0755) == -1)
-                        throw SysError(format("creating directory ‘%1%’"));
+                        throw SysError(format("creating directory '%1%'"));
                     createLinks(target, dstFile, priorities[dstFile]);
                     createLinks(srcFile, dstFile, priority);
                     continue;
                 }
             } else if (errno != ENOENT)
-                throw SysError(format("getting status of ‘%1%’") % dstFile);
+                throw SysError(format("getting status of '%1%'") % dstFile);
         } else {
             struct stat dstSt;
             auto res = lstat(dstFile.c_str(), &dstSt);
@@ -74,17 +74,17 @@ static void createLinks(const Path & srcDir, const Path & dstDir, int priority)
                     auto prevPriority = priorities[dstFile];
                     if (prevPriority == priority)
                         throw Error(format(
-                                "collision between ‘%1%’ and ‘%2%’; "
-                                "use ‘nix-env --set-flag priority NUMBER PKGNAME’ "
+                                "collision between '%1%' and '%2%'; "
+                                "use 'nix-env --set-flag priority NUMBER PKGNAME' "
                                 "to change the priority of one of the conflicting packages"
                                 ) % srcFile % target);
                     if (prevPriority < priority)
                         continue;
                     if (unlink(dstFile.c_str()) == -1)
-                        throw SysError(format("unlinking ‘%1%’") % dstFile);
+                        throw SysError(format("unlinking '%1%'") % dstFile);
                 }
             } else if (errno != ENOENT)
-                throw SysError(format("getting status of ‘%1%’") % dstFile);
+                throw SysError(format("getting status of '%1%'") % dstFile);
         }
         createSymlink(srcFile, dstFile);
         priorities[dstFile] = priority;
@@ -112,7 +112,7 @@ static void addPkg(const Path & pkgDir, int priority)
         if (!fd) {
             if (errno == ENOENT)
                 return;
-            throw SysError(format("opening ‘%1%’") % propagatedFN);
+            throw SysError(format("opening '%1%'") % propagatedFN);
         }
         propagated = readLine(fd.get());
     }
diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc
index 55379f94b189..b0f80db32a88 100644
--- a/src/libexpr/attr-path.cc
+++ b/src/libexpr/attr-path.cc
@@ -19,7 +19,7 @@ static Strings parseAttrPath(const string & s)
             ++i;
             while (1) {
                 if (i == s.end())
-                    throw Error(format("missing closing quote in selection path ‘%1%’") % s);
+                    throw Error(format("missing closing quote in selection path '%1%'") % s);
                 if (*i == '"') break;
                 cur.push_back(*i++);
             }
@@ -38,7 +38,7 @@ Value * findAlongAttrPath(EvalState & state, const string & attrPath,
     Strings tokens = parseAttrPath(attrPath);
 
     Error attrError =
-        Error(format("attribute selection path ‘%1%’ does not match expression") % attrPath);
+        Error(format("attribute selection path '%1%' does not match expression") % attrPath);
 
     Value * v = &vIn;
 
@@ -62,15 +62,15 @@ Value * findAlongAttrPath(EvalState & state, const string & attrPath,
 
             if (v->type != tAttrs)
                 throw TypeError(
-                    format("the expression selected by the selection path ‘%1%’ should be a set but is %2%")
+                    format("the expression selected by the selection path '%1%' should be a set but is %2%")
                     % attrPath % showType(*v));
 
             if (attr.empty())
-                throw Error(format("empty attribute name in selection path ‘%1%’") % attrPath);
+                throw Error(format("empty attribute name in selection path '%1%'") % attrPath);
 
             Bindings::iterator a = v->attrs->find(state.symbols.create(attr));
             if (a == v->attrs->end())
-                throw Error(format("attribute ‘%1%’ in selection path ‘%2%’ not found") % attr % attrPath);
+                throw Error(format("attribute '%1%' in selection path '%2%' not found") % attr % attrPath);
             v = &*a->value;
         }
 
@@ -78,11 +78,11 @@ Value * findAlongAttrPath(EvalState & state, const string & attrPath,
 
             if (!v->isList())
                 throw TypeError(
-                    format("the expression selected by the selection path ‘%1%’ should be a list but is %2%")
+                    format("the expression selected by the selection path '%1%' should be a list but is %2%")
                     % attrPath % showType(*v));
 
             if (attrIndex >= v->listSize())
-                throw Error(format("list index %1% in selection path ‘%2%’ is out of range") % attrIndex % attrPath);
+                throw Error(format("list index %1% in selection path '%2%' is out of range") % attrIndex % attrPath);
 
             v = v->listElems()[attrIndex];
         }
diff --git a/src/libexpr/common-opts.cc b/src/libexpr/common-opts.cc
index 06d6ed87df94..6b31961d345b 100644
--- a/src/libexpr/common-opts.cc
+++ b/src/libexpr/common-opts.cc
@@ -13,7 +13,7 @@ bool parseAutoArgs(Strings::iterator & i,
     string arg = *i;
     if (arg != "--arg" && arg != "--argstr") return false;
 
-    UsageError error(format("‘%1%’ requires two arguments") % arg);
+    UsageError error(format("'%1%' requires two arguments") % arg);
 
     if (++i == argsEnd) throw error;
     string name = *i;
@@ -46,7 +46,7 @@ bool parseSearchPathArg(Strings::iterator & i,
     const Strings::iterator & argsEnd, Strings & searchPath)
 {
     if (*i != "-I") return false;
-    if (++i == argsEnd) throw UsageError("‘-I’ requires an argument");
+    if (++i == argsEnd) throw UsageError("'-I' requires an argument");
     searchPath.push_back(*i);
     return true;
 }
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index ca4c9a373a3a..78f6b0010523 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -329,7 +329,7 @@ Path EvalState::checkSourcePath(const Path & path_)
     if (!restricted) return path_;
 
     /* Resolve symlinks. */
-    debug(format("checking access to ‘%s’") % path_);
+    debug(format("checking access to '%s'") % path_);
     Path path = canonPath(path_, true);
 
     for (auto & i : searchPath) {
@@ -351,7 +351,7 @@ Path EvalState::checkSourcePath(const Path & path_)
         return path;
 #endif
 
-    throw RestrictedPathError(format("access to path ‘%1%’ is forbidden in restricted mode") % path_);
+    throw RestrictedPathError(format("access to path '%1%' is forbidden in restricted mode") % path_);
 }
 
 
@@ -504,7 +504,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
             return j->value;
         }
         if (!env->prevWith)
-            throwUndefinedVarError("undefined variable ‘%1%’ at %2%", var.name, var.pos);
+            throwUndefinedVarError("undefined variable '%1%' at %2%", var.name, var.pos);
         for (unsigned int l = env->prevWith; l; --l, env = env->up) ;
     }
 }
@@ -643,12 +643,12 @@ void EvalState::evalFile(const Path & path, Value & v)
         return;
     }
 
-    printTalkative("evaluating file ‘%1%’", path2);
+    printTalkative("evaluating file '%1%'", path2);
     Expr * e = parseExprFromFile(checkSourcePath(path2));
     try {
         eval(e, v);
     } catch (Error & e) {
-        addErrorPrefix(e, "while evaluating the file ‘%1%’:\n", path2);
+        addErrorPrefix(e, "while evaluating the file '%1%':\n", path2);
         throw;
     }
 
@@ -798,7 +798,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
         Symbol nameSym = state.symbols.create(nameVal.string.s);
         Bindings::iterator j = v.attrs->find(nameSym);
         if (j != v.attrs->end())
-            throwEvalError("dynamic attribute ‘%1%’ at %2% already defined at %3%", nameSym, i.pos, *j->pos);
+            throwEvalError("dynamic attribute '%1%' at %2% already defined at %3%", nameSym, i.pos, *j->pos);
 
         i.valueExpr->setName(nameSym);
         /* Keep sorted order so find can catch duplicates */
@@ -886,7 +886,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
             } else {
                 state.forceAttrs(*vAttrs, pos);
                 if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
-                    throwEvalError("attribute ‘%1%’ missing, at %2%", name, pos);
+                    throwEvalError("attribute '%1%' missing, at %2%", name, pos);
             }
             vAttrs = j->value;
             pos2 = j->pos;
@@ -897,7 +897,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
 
     } catch (Error & e) {
         if (pos2 && pos2->file != state.sDerivationNix)
-            addErrorPrefix(e, "while evaluating the attribute ‘%1%’ at %2%:\n",
+            addErrorPrefix(e, "while evaluating the attribute '%1%' at %2%:\n",
                 showAttrPath(state, env, attrPath), *pos2);
         throw;
     }
@@ -1039,7 +1039,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
         for (auto & i : lambda.formals->formals) {
             Bindings::iterator j = arg.attrs->find(i.name);
             if (j == arg.attrs->end()) {
-                if (!i.def) throwTypeError("%1% called without required argument ‘%2%’, at %3%",
+                if (!i.def) throwTypeError("%1% called without required argument '%2%', at %3%",
                     lambda, i.name, pos);
                 env2.values[displ++] = i.def->maybeThunk(*this, env2);
             } else {
@@ -1055,7 +1055,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po
                user. */
             for (auto & i : *arg.attrs)
                 if (lambda.formals->argNames.find(i.name) == lambda.formals->argNames.end())
-                    throwTypeError("%1% called with unexpected argument ‘%2%’, at %3%", lambda, i.name, pos);
+                    throwTypeError("%1% called with unexpected argument '%2%', at %3%", lambda, i.name, pos);
             abort(); // can't happen
         }
     }
@@ -1113,7 +1113,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
         if (j != args.end())
             actualArgs->attrs->push_back(*j);
         else if (!i.def)
-            throwTypeError("cannot auto-call a function that has an argument without a default value (‘%1%’)", i.name);
+            throwTypeError("cannot auto-call a function that has an argument without a default value ('%1%')", i.name);
     }
 
     actualArgs->attrs->sort();
@@ -1342,7 +1342,7 @@ void EvalState::forceValueDeep(Value & v)
                 try {
                     recurse(*i.value);
                 } catch (Error & e) {
-                    addErrorPrefix(e, "while evaluating the attribute ‘%1%’ at %2%:\n", i.name, *i.pos);
+                    addErrorPrefix(e, "while evaluating the attribute '%1%' at %2%:\n", i.name, *i.pos);
                     throw;
                 }
         }
@@ -1434,10 +1434,10 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos)
     string s = forceString(v, pos);
     if (v.string.context) {
         if (pos)
-            throwEvalError("the string ‘%1%’ is not allowed to refer to a store path (such as ‘%2%’), at %3%",
+            throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%'), at %3%",
                 v.string.s, v.string.context[0], pos);
         else
-            throwEvalError("the string ‘%1%’ is not allowed to refer to a store path (such as ‘%2%’)",
+            throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')",
                 v.string.s, v.string.context[0]);
     }
     return s;
@@ -1519,7 +1519,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
 string EvalState::copyPathToStore(PathSet & context, const Path & path)
 {
     if (nix::isDerivation(path))
-        throwEvalError("file names are not allowed to end in ‘%1%’", drvExtension);
+        throwEvalError("file names are not allowed to end in '%1%'", drvExtension);
 
     Path dstPath;
     if (srcToStore[path] != "")
@@ -1529,7 +1529,7 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path)
             ? store->computeStorePathForPath(checkSourcePath(path)).first
             : store->addToStore(baseNameOf(path), checkSourcePath(path), true, htSHA256, defaultPathFilter, repair);
         srcToStore[path] = dstPath;
-        printMsg(lvlChatty, format("copied source ‘%1%’ -> ‘%2%’")
+        printMsg(lvlChatty, format("copied source '%1%' -> '%2%'")
             % path % dstPath);
     }
 
@@ -1542,7 +1542,7 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context)
 {
     string path = coerceToString(pos, v, context, false, false);
     if (path == "" || path[0] != '/')
-        throwEvalError("string ‘%1%’ doesn't represent an absolute path, at %2%", path, pos);
+        throwEvalError("string '%1%' doesn't represent an absolute path, at %2%", path, pos);
     return path;
 }
 
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index 66689e3e889f..d5bc42352a26 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -89,7 +89,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
     /* Check for `meta.outputsToInstall` and return `outputs` reduced to that. */
     const Value * outTI = queryMeta("outputsToInstall");
     if (!outTI) return outputs;
-    const auto errMsg = Error("this derivation has bad ‘meta.outputsToInstall’");
+    const auto errMsg = Error("this derivation has bad 'meta.outputsToInstall'");
         /* ^ this shows during `nix-env -i` right under the bad derivation */
     if (!outTI->isList()) throw errMsg;
     Outputs result;
@@ -310,7 +310,7 @@ static void getDerivations(EvalState & state, Value & vIn,
            bound to the attribute with the "lower" name should take
            precedence). */
         for (auto & i : v.attrs->lexicographicOrder()) {
-            debug("evaluating attribute ‘%1%’", i->name);
+            debug("evaluating attribute '%1%'", i->name);
             if (!std::regex_match(std::string(i->name), attrRegex))
                 continue;
             string pathPrefix2 = addToPath(pathPrefix, i->name);
diff --git a/src/libexpr/json-to-value.cc b/src/libexpr/json-to-value.cc
index c189cdef35e7..9380de3a66b3 100644
--- a/src/libexpr/json-to-value.cc
+++ b/src/libexpr/json-to-value.cc
@@ -57,7 +57,7 @@ static void parseJSON(EvalState & state, const char * & s, Value & v)
             values.push_back(v2);
             skipWhitespace(s);
             if (*s == ']') break;
-            if (*s != ',') throw JSONParseError("expected ‘,’ or ‘]’ after JSON array element");
+            if (*s != ',') throw JSONParseError("expected ',' or ']' after JSON array element");
             s++;
         }
         s++;
@@ -74,14 +74,14 @@ static void parseJSON(EvalState & state, const char * & s, Value & v)
             if (attrs.empty() && *s == '}') break;
             string name = parseJSONString(s);
             skipWhitespace(s);
-            if (*s != ':') throw JSONParseError("expected ‘:’ in JSON object");
+            if (*s != ':') throw JSONParseError("expected ':' in JSON object");
             s++;
             Value * v2 = state.allocValue();
             parseJSON(state, s, *v2);
             attrs[state.symbols.create(name)] = v2;
             skipWhitespace(s);
             if (*s == '}') break;
-            if (*s != ',') throw JSONParseError("expected ‘,’ or ‘}’ after JSON member");
+            if (*s != ',') throw JSONParseError("expected ',' or '}' after JSON member");
             s++;
         }
         state.mkAttrs(v, attrs.size());
diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l
index 40ca77258037..28a0a6a87896 100644
--- a/src/libexpr/lexer.l
+++ b/src/libexpr/lexer.l
@@ -124,13 +124,13 @@ or          { return OR_KW; }
 {INT}       { errno = 0;
               yylval->n = strtol(yytext, 0, 10);
               if (errno != 0)
-                  throw ParseError(format("invalid integer ‘%1%’") % yytext);
+                  throw ParseError(format("invalid integer '%1%'") % yytext);
               return INT;
             }
 {FLOAT}     { errno = 0;
               yylval->nf = strtod(yytext, 0);
               if (errno != 0)
-                  throw ParseError(format("invalid float ‘%1%’") % yytext);
+                  throw ParseError(format("invalid float '%1%'") % yytext);
               return FLOAT;
             }
 
@@ -191,12 +191,12 @@ or          { return OR_KW; }
 <INITIAL,INSIDE_DOLLAR_CURLY>{
 
 {PATH}      { if (yytext[yyleng-1] == '/')
-                  throw ParseError("path ‘%s’ has a trailing slash", yytext);
+                  throw ParseError("path '%s' has a trailing slash", yytext);
               yylval->path = strdup(yytext);
               return PATH;
             }
 {HPATH}     { if (yytext[yyleng-1] == '/')
-                  throw ParseError("path ‘%s’ has a trailing slash", yytext);
+                  throw ParseError("path '%s' has a trailing slash", yytext);
               yylval->path = strdup(yytext);
               return HPATH;
             }
diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc
index b2c9f0528ca9..7b0a127cd41c 100644
--- a/src/libexpr/nixexpr.cc
+++ b/src/libexpr/nixexpr.cc
@@ -267,7 +267,7 @@ void ExprVar::bindVars(const StaticEnv & env)
     /* Otherwise, the variable must be obtained from the nearest
        enclosing `with'.  If there is no `with', then we can issue an
        "undefined variable" error now. */
-    if (withLevel == -1) throw UndefinedVarError(format("undefined variable ‘%1%’ at %2%") % name % pos);
+    if (withLevel == -1) throw UndefinedVarError(format("undefined variable '%1%' at %2%") % name % pos);
 
     fromWith = true;
     this->level = withLevel;
@@ -419,7 +419,7 @@ void ExprLambda::setName(Symbol & name)
 
 string ExprLambda::showNamePos() const
 {
-    return (format("%1% at %2%") % (name.set() ? "‘" + (string) name + "’" : "anonymous function") % pos).str();
+    return (format("%1% at %2%") % (name.set() ? "'" + (string) name + "'" : "anonymous function") % pos).str();
 }
 
 
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index d2ca09b3a5bb..30be79bb57a6 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -235,7 +235,7 @@ struct ExprLambda : Expr
         : pos(pos), arg(arg), matchAttrs(matchAttrs), formals(formals), body(body)
     {
         if (!arg.empty() && formals && formals->argNames.find(arg) != formals->argNames.end())
-            throw ParseError(format("duplicate formal function argument ‘%1%’ at %2%")
+            throw ParseError(format("duplicate formal function argument '%1%' at %2%")
                 % arg % pos);
     };
     void setName(Symbol & name);
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index ca3d057451ab..669312bb7cff 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -65,14 +65,14 @@ namespace nix {
 
 static void dupAttr(const AttrPath & attrPath, const Pos & pos, const Pos & prevPos)
 {
-    throw ParseError(format("attribute ‘%1%’ at %2% already defined at %3%")
+    throw ParseError(format("attribute '%1%' at %2% already defined at %3%")
         % showAttrPath(attrPath) % pos % prevPos);
 }
 
 
 static void dupAttr(Symbol attr, const Pos & pos, const Pos & prevPos)
 {
-    throw ParseError(format("attribute ‘%1%’ at %2% already defined at %3%")
+    throw ParseError(format("attribute '%1%' at %2% already defined at %3%")
         % attr % pos % prevPos);
 }
 
@@ -121,7 +121,7 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath,
 static void addFormal(const Pos & pos, Formals * formals, const Formal & formal)
 {
     if (formals->argNames.find(formal.name) != formals->argNames.end())
-        throw ParseError(format("duplicate formal function argument ‘%1%’ at %2%")
+        throw ParseError(format("duplicate formal function argument '%1%' at %2%")
             % formal.name % pos);
     formals->formals.push_front(formal);
     formals->argNames.insert(formal.name);
@@ -564,7 +564,7 @@ Path resolveExprPath(Path path)
     struct stat st;
     while (true) {
         if (lstat(path.c_str(), &st))
-            throw SysError(format("getting status of ‘%1%’") % path);
+            throw SysError(format("getting status of '%1%'") % path);
         if (!S_ISLNK(st.st_mode)) break;
         path = absPath(readLink(path), dirOf(path));
     }
@@ -649,7 +649,7 @@ Path EvalState::findFile(SearchPath & searchPath, const string & path, const Pos
         if (pathExists(res)) return canonPath(res);
     }
     format f = format(
-        "file ‘%1%’ was not found in the Nix search path (add it using $NIX_PATH or -I)"
+        "file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)"
         + string(pos ? ", at %2%" : ""));
     f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
     throw ThrownError(f % path % pos);
@@ -671,7 +671,7 @@ std::pair<bool, std::string> EvalState::resolveSearchPathElem(const SearchPathEl
             else
                 res = { true, getDownloader()->downloadCached(store, elem.second, true) };
         } catch (DownloadError & e) {
-            printError(format("warning: Nix search path entry ‘%1%’ cannot be downloaded, ignoring") % elem.second);
+            printError(format("warning: Nix search path entry '%1%' cannot be downloaded, ignoring") % elem.second);
             res = { false, "" };
         }
     } else {
@@ -679,12 +679,12 @@ std::pair<bool, std::string> EvalState::resolveSearchPathElem(const SearchPathEl
         if (pathExists(path))
             res = { true, path };
         else {
-            printError(format("warning: Nix search path entry ‘%1%’ does not exist, ignoring") % elem.second);
+            printError(format("warning: Nix search path entry '%1%' does not exist, ignoring") % elem.second);
             res = { false, "" };
         }
     }
 
-    debug(format("resolved search path element ‘%s’ to ‘%s’") % elem.second % res.second);
+    debug(format("resolved search path element '%s' to '%s'") % elem.second % res.second);
 
     searchPathResolved[elem.second] = res;
     return res;
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 78d73e1f5572..4e51e8ff2562 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -44,7 +44,7 @@ std::pair<string, string> decodeContext(const string & s)
 
 
 InvalidPathError::InvalidPathError(const Path & path) :
-    EvalError(format("path ‘%1%’ is not valid") % path), path(path) {}
+    EvalError(format("path '%1%' is not valid") % path), path(path) {}
 
 void EvalState::realiseContext(const PathSet & context)
 {
@@ -60,7 +60,7 @@ void EvalState::realiseContext(const PathSet & context)
     }
     if (!drvs.empty()) {
         if (!settings.enableImportFromDerivation)
-            throw EvalError(format("attempted to realize ‘%1%’ during evaluation but 'allow-import-from-derivation' is false") % *(drvs.begin()));
+            throw EvalError(format("attempted to realize '%1%' during evaluation but 'allow-import-from-derivation' is false") % *(drvs.begin()));
         /* For performance, prefetch all substitute info. */
         PathSet willBuild, willSubstitute, unknown;
         unsigned long long downloadSize, narSize;
@@ -80,7 +80,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
     try {
         state.realiseContext(context);
     } catch (InvalidPathError & e) {
-        throw EvalError(format("cannot import ‘%1%’, since path ‘%2%’ is not valid, at %3%")
+        throw EvalError(format("cannot import '%1%', since path '%2%' is not valid, at %3%")
             % path % e.path % pos);
     }
 
@@ -127,7 +127,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
                 env->values[displ++] = attr.value;
             }
 
-            printTalkative("evaluating file ‘%1%’", path);
+            printTalkative("evaluating file '%1%'", path);
             Expr * e = state.parseExprFromFile(resolveExprPath(path), staticEnv);
 
             e->eval(state, *env, v);
@@ -149,7 +149,7 @@ static void prim_importNative(EvalState & state, const Pos & pos, Value * * args
     try {
         state.realiseContext(context);
     } catch (InvalidPathError & e) {
-        throw EvalError(format("cannot import ‘%1%’, since path ‘%2%’ is not valid, at %3%")
+        throw EvalError(format("cannot import '%1%', since path '%2%' is not valid, at %3%")
             % path % e.path % pos);
     }
 
@@ -159,16 +159,16 @@ static void prim_importNative(EvalState & state, const Pos & pos, Value * * args
 
     void *handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
     if (!handle)
-        throw EvalError(format("could not open ‘%1%’: %2%") % path % dlerror());
+        throw EvalError(format("could not open '%1%': %2%") % path % dlerror());
 
     dlerror();
     ValueInitializer func = (ValueInitializer) dlsym(handle, sym.c_str());
     if(!func) {
         char *message = dlerror();
         if (message)
-            throw EvalError(format("could not load symbol ‘%1%’ from ‘%2%’: %3%") % sym % path % message);
+            throw EvalError(format("could not load symbol '%1%' from '%2%': %3%") % sym % path % message);
         else
-            throw EvalError(format("symbol ‘%1%’ from ‘%2%’ resolved to NULL when a function pointer was expected")
+            throw EvalError(format("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected")
                     % sym % path);
     }
 
@@ -196,7 +196,7 @@ static void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value
     try {
         state.realiseContext(context);
     } catch (InvalidPathError & e) {
-        throw EvalError(format("cannot execute ‘%1%’, since path ‘%2%’ is not valid, at %3%")
+        throw EvalError(format("cannot execute '%1%', since path '%2%' is not valid, at %3%")
             % program % e.path % pos);
     }
 
@@ -205,13 +205,13 @@ static void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value
     try {
         parsed = state.parseExprFromString(output, pos.file);
     } catch (Error & e) {
-        e.addPrefix(format("While parsing the output from ‘%1%’, at %2%\n") % program % pos);
+        e.addPrefix(format("While parsing the output from '%1%', at %2%\n") % program % pos);
         throw;
     }
     try {
         state.eval(parsed, v);
     } catch (Error & e) {
-        e.addPrefix(format("While evaluating the output from ‘%1%’, at %2%\n") % program % pos);
+        e.addPrefix(format("While evaluating the output from '%1%', at %2%\n") % program % pos);
         throw;
     }
 }
@@ -332,7 +332,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
     Bindings::iterator startSet =
         args[0]->attrs->find(state.symbols.create("startSet"));
     if (startSet == args[0]->attrs->end())
-        throw EvalError(format("attribute ‘startSet’ required, at %1%") % pos);
+        throw EvalError(format("attribute 'startSet' required, at %1%") % pos);
     state.forceList(*startSet->value, pos);
 
     ValueList workSet;
@@ -343,7 +343,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
     Bindings::iterator op =
         args[0]->attrs->find(state.symbols.create("operator"));
     if (op == args[0]->attrs->end())
-        throw EvalError(format("attribute ‘operator’ required, at %1%") % pos);
+        throw EvalError(format("attribute 'operator' required, at %1%") % pos);
     state.forceValue(*op->value);
 
     /* Construct the closure by applying the operator to element of
@@ -362,7 +362,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
         Bindings::iterator key =
             e->attrs->find(state.symbols.create("key"));
         if (key == e->attrs->end())
-            throw EvalError(format("attribute ‘key’ required, at %1%") % pos);
+            throw EvalError(format("attribute 'key' required, at %1%") % pos);
         state.forceValue(*key->value);
 
         if (doneKeys.find(key->value) != doneKeys.end()) continue;
@@ -393,7 +393,7 @@ static void prim_abort(EvalState & state, const Pos & pos, Value * * args, Value
 {
     PathSet context;
     string s = state.coerceToString(pos, *args[0], context);
-    throw Abort(format("evaluation aborted with the following error message: ‘%1%’") % s);
+    throw Abort(format("evaluation aborted with the following error message: '%1%'") % s);
 }
 
 
@@ -502,13 +502,13 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
     /* Figure out the name first (for stack backtraces). */
     Bindings::iterator attr = args[0]->attrs->find(state.sName);
     if (attr == args[0]->attrs->end())
-        throw EvalError(format("required attribute ‘name’ missing, at %1%") % pos);
+        throw EvalError(format("required attribute 'name' missing, at %1%") % pos);
     string drvName;
     Pos & posDrvName(*attr->pos);
     try {
         drvName = state.forceStringNoCtx(*attr->value, pos);
     } catch (Error & e) {
-        e.addPrefix(format("while evaluating the derivation attribute ‘name’ at %1%:\n") % posDrvName);
+        e.addPrefix(format("while evaluating the derivation attribute 'name' at %1%:\n") % posDrvName);
         throw;
     }
 
@@ -540,26 +540,26 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
     for (auto & i : args[0]->attrs->lexicographicOrder()) {
         if (i->name == state.sIgnoreNulls) continue;
         string key = i->name;
-        vomit("processing attribute ‘%1%’", key);
+        vomit("processing attribute '%1%'", key);
 
         auto handleHashMode = [&](const std::string & s) {
             if (s == "recursive") outputHashRecursive = true;
             else if (s == "flat") outputHashRecursive = false;
-            else throw EvalError("invalid value ‘%s’ for ‘outputHashMode’ attribute, at %s", s, posDrvName);
+            else throw EvalError("invalid value '%s' for 'outputHashMode' attribute, at %s", s, posDrvName);
         };
 
         auto handleOutputs = [&](const Strings & ss) {
             outputs.clear();
             for (auto & j : ss) {
                 if (outputs.find(j) != outputs.end())
-                    throw EvalError(format("duplicate derivation output ‘%1%’, at %2%") % j % posDrvName);
+                    throw EvalError(format("duplicate derivation output '%1%', at %2%") % j % posDrvName);
                 /* !!! Check whether j is a valid attribute
                    name. */
                 /* Derivations cannot be named ‘drv’, because
                    then we'd have an attribute ‘drvPath’ in
                    the resulting set. */
                 if (j == "drv")
-                    throw EvalError(format("invalid derivation output name ‘drv’, at %1%") % posDrvName);
+                    throw EvalError(format("invalid derivation output name 'drv', at %1%") % posDrvName);
                 outputs.insert(j);
             }
             if (outputs.empty())
@@ -622,7 +622,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
                     else if (i->name == state.sSystem) drv.platform = s;
                     else if (i->name == state.sName) {
                         drvName = s;
-                        printMsg(lvlVomit, format("derivation name is ‘%1%’") % drvName);
+                        printMsg(lvlVomit, format("derivation name is '%1%'") % drvName);
                     }
                     else if (key == "outputHash") outputHash = s;
                     else if (key == "outputHashAlgo") outputHashAlgo = s;
@@ -634,7 +634,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
             }
 
         } catch (Error & e) {
-            e.addPrefix(format("while evaluating the attribute ‘%1%’ of the derivation ‘%2%’ at %3%:\n")
+            e.addPrefix(format("while evaluating the attribute '%1%' of the derivation '%2%' at %3%:\n")
                 % key % drvName % posDrvName);
             throw;
         }
@@ -690,14 +690,14 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
 
     /* Do we have all required attributes? */
     if (drv.builder == "")
-        throw EvalError(format("required attribute ‘builder’ missing, at %1%") % posDrvName);
+        throw EvalError(format("required attribute 'builder' missing, at %1%") % posDrvName);
     if (drv.platform == "")
-        throw EvalError(format("required attribute ‘system’ missing, at %1%") % posDrvName);
+        throw EvalError(format("required attribute 'system' missing, at %1%") % posDrvName);
 
     /* Check whether the derivation name is valid. */
     checkStoreName(drvName);
     if (isDerivation(drvName))
-        throw EvalError(format("derivation names are not allowed to end in ‘%1%’, at %2%")
+        throw EvalError(format("derivation names are not allowed to end in '%1%', at %2%")
             % drvExtension % posDrvName);
 
     if (outputHash) {
@@ -707,7 +707,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
 
         HashType ht = parseHashType(outputHashAlgo);
         if (ht == htUnknown)
-            throw EvalError(format("unknown hash algorithm ‘%1%’, at %2%") % outputHashAlgo % posDrvName);
+            throw EvalError(format("unknown hash algorithm '%1%', at %2%") % outputHashAlgo % posDrvName);
         Hash h(*outputHash, ht);
         outputHash = h.to_string(Base16, false);
         if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo;
@@ -743,7 +743,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
     /* Write the resulting term into the Nix store directory. */
     Path drvPath = writeDerivation(state.store, drv, drvName, state.repair);
 
-    printMsg(lvlChatty, format("instantiated ‘%1%’ -> ‘%2%’")
+    printMsg(lvlChatty, format("instantiated '%1%' -> '%2%'")
         % drvName % drvPath);
 
     /* Optimisation, but required in read-only mode! because in that
@@ -763,7 +763,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
 
 /* Return a placeholder string for the specified output that will be
    substituted by the corresponding output path at build time. For
-   example, ‘placeholder "out"’ returns the string
+   example, 'placeholder "out"' returns the string
    /1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9. At build
    time, any occurence of this string in an derivation attribute will
    be replaced with the concrete path in the Nix store of the output
@@ -805,7 +805,7 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V
        e.g. nix-push does the right thing. */
     if (!state.store->isStorePath(path)) path = canonPath(path, true);
     if (!state.store->isInStore(path))
-        throw EvalError(format("path ‘%1%’ is not in the Nix store, at %2%") % path % pos);
+        throw EvalError(format("path '%1%' is not in the Nix store, at %2%") % path % pos);
     Path path2 = state.store->toStorePath(path);
     if (!settings.readOnlyMode)
         state.store->ensurePath(path2);
@@ -819,7 +819,7 @@ static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args,
     PathSet context;
     Path path = state.coerceToPath(pos, *args[0], context);
     if (!context.empty())
-        throw EvalError(format("string ‘%1%’ cannot refer to other paths, at %2%") % path % pos);
+        throw EvalError(format("string '%1%' cannot refer to other paths, at %2%") % path % pos);
     try {
         mkBool(v, pathExists(state.checkSourcePath(path)));
     } catch (SysError & e) {
@@ -860,18 +860,18 @@ static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Va
     try {
         state.realiseContext(context);
     } catch (InvalidPathError & e) {
-        throw EvalError(format("cannot read ‘%1%’, since path ‘%2%’ is not valid, at %3%")
+        throw EvalError(format("cannot read '%1%', since path '%2%' is not valid, at %3%")
             % path % e.path % pos);
     }
     string s = readFile(state.checkSourcePath(path));
     if (s.find((char) 0) != string::npos)
-        throw Error(format("the contents of the file ‘%1%’ cannot be represented as a Nix string") % path);
+        throw Error(format("the contents of the file '%1%' cannot be represented as a Nix string") % path);
     mkString(v, s.c_str());
 }
 
 
 /* Find a file in the Nix search path. Used to implement <x> paths,
-   which are desugared to ‘findFile __nixPath "x"’. */
+   which are desugared to 'findFile __nixPath "x"'. */
 static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
     state.forceList(*args[0], pos);
@@ -889,7 +889,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
 
         i = v2.attrs->find(state.symbols.create("path"));
         if (i == v2.attrs->end())
-            throw EvalError(format("attribute ‘path’ missing, at %1%") % pos);
+            throw EvalError(format("attribute 'path' missing, at %1%") % pos);
 
         PathSet context;
         string path = state.coerceToString(pos, *i->value, context, false, false);
@@ -897,7 +897,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
         try {
             state.realiseContext(context);
         } catch (InvalidPathError & e) {
-            throw EvalError(format("cannot find ‘%1%’, since path ‘%2%’ is not valid, at %3%")
+            throw EvalError(format("cannot find '%1%', since path '%2%' is not valid, at %3%")
                 % path % e.path % pos);
         }
 
@@ -917,7 +917,7 @@ static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Val
     try {
         state.realiseContext(ctx);
     } catch (InvalidPathError & e) {
-        throw EvalError(format("cannot read ‘%1%’, since path ‘%2%’ is not valid, at %3%")
+        throw EvalError(format("cannot read '%1%', since path '%2%' is not valid, at %3%")
             % path % e.path % pos);
     }
 
@@ -991,7 +991,7 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu
         if (isDerivation(path)) {
             /* See prim_unsafeDiscardOutputDependency. */
             if (path.at(0) != '~')
-                throw EvalError(format("in ‘toFile’: the file ‘%1%’ cannot refer to derivation outputs, at %2%") % name % pos);
+                throw EvalError(format("in 'toFile': the file '%1%' cannot refer to derivation outputs, at %2%") % name % pos);
             path = string(path, 1);
         }
         refs.insert(path);
@@ -1024,7 +1024,7 @@ struct FilterFromExpr : PathFilter
     {
         struct stat st;
         if (lstat(path.c_str(), &st))
-            throw SysError(format("getting attributes of path ‘%1%’") % path);
+            throw SysError(format("getting attributes of path '%1%'") % path);
 
         /* Call the filter function.  The first argument is the path,
            the second is a string indicating the type of the file. */
@@ -1054,11 +1054,11 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args
     PathSet context;
     Path path = state.coerceToPath(pos, *args[1], context);
     if (!context.empty())
-        throw EvalError(format("string ‘%1%’ cannot refer to other paths, at %2%") % path % pos);
+        throw EvalError(format("string '%1%' cannot refer to other paths, at %2%") % path % pos);
 
     state.forceValue(*args[0]);
     if (args[0]->type != tLambda)
-        throw TypeError(format("first argument in call to ‘filterSource’ is not a function but %1%, at %2%") % showType(*args[0]) % pos);
+        throw TypeError(format("first argument in call to 'filterSource' is not a function but %1%, at %2%") % showType(*args[0]) % pos);
 
     FilterFromExpr filter(state, *args[0], pos);
 
@@ -1119,7 +1119,7 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v)
     // !!! Should we create a symbol here or just do a lookup?
     Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
     if (i == args[1]->attrs->end())
-        throw EvalError(format("attribute ‘%1%’ missing, at %2%") % attr % pos);
+        throw EvalError(format("attribute '%1%' missing, at %2%") % attr % pos);
     // !!! add to stack trace?
     if (state.countCalls && i->pos) state.attrSelects[*i->pos]++;
     state.forceValue(*i->value);
@@ -1199,14 +1199,14 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args,
 
         Bindings::iterator j = v2.attrs->find(state.sName);
         if (j == v2.attrs->end())
-            throw TypeError(format("‘name’ attribute missing in a call to ‘listToAttrs’, at %1%") % pos);
+            throw TypeError(format("'name' attribute missing in a call to 'listToAttrs', at %1%") % pos);
         string name = state.forceStringNoCtx(*j->value, pos);
 
         Symbol sym = state.symbols.create(name);
         if (seen.find(sym) == seen.end()) {
             Bindings::iterator j2 = v2.attrs->find(state.symbols.create(state.sValue));
             if (j2 == v2.attrs->end())
-                throw TypeError(format("‘value’ attribute missing in a call to ‘listToAttrs’, at %1%") % pos);
+                throw TypeError(format("'value' attribute missing in a call to 'listToAttrs', at %1%") % pos);
 
             v.attrs->push_back(Attr(sym, j2->value, j2->pos));
             seen.insert(sym);
@@ -1281,7 +1281,7 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args
 {
     state.forceValue(*args[0]);
     if (args[0]->type != tLambda)
-        throw TypeError(format("‘functionArgs’ requires a function, at %1%") % pos);
+        throw TypeError(format("'functionArgs' requires a function, at %1%") % pos);
 
     if (!args[0]->lambda.fun->matchAttrs) {
         state.mkAttrs(v, 0);
@@ -1340,7 +1340,7 @@ static void prim_tail(EvalState & state, const Pos & pos, Value * * args, Value
 {
     state.forceList(*args[0], pos);
     if (args[0]->listSize() == 0)
-        throw Error(format("‘tail’ called on an empty list, at %1%") % pos);
+        throw Error(format("'tail' called on an empty list, at %1%") % pos);
     state.mkList(v, args[0]->listSize() - 1);
     for (unsigned int n = 0; n < v.listSize(); ++n)
         v.listElems()[n] = args[0]->listElems()[n + 1];
@@ -1649,7 +1649,7 @@ static void prim_substring(EvalState & state, const Pos & pos, Value * * args, V
     PathSet context;
     string s = state.coerceToString(pos, *args[2], context);
 
-    if (start < 0) throw EvalError(format("negative start position in ‘substring’, at %1%") % pos);
+    if (start < 0) throw EvalError(format("negative start position in 'substring', at %1%") % pos);
 
     mkString(v, (unsigned int) start >= s.size() ? "" : string(s, start, len), context);
 }
@@ -1696,7 +1696,7 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args,
     string type = state.forceStringNoCtx(*args[0], pos);
     HashType ht = parseHashType(type);
     if (ht == htUnknown)
-      throw Error(format("unknown hash type ‘%1%’, at %2%") % type % pos);
+      throw Error(format("unknown hash type '%1%', at %2%") % type % pos);
 
     PathSet context; // discarded
     string s = state.forceString(*args[1], context, pos);
@@ -1737,9 +1737,9 @@ static void prim_match(EvalState & state, const Pos & pos, Value * * args, Value
     } catch (std::regex_error &e) {
         if (e.code() == std::regex_constants::error_space) {
           // limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++
-          throw EvalError("memory limit exceeded by regular expression ‘%s’, at %s", re, pos);
+          throw EvalError("memory limit exceeded by regular expression '%s', at %s", re, pos);
         } else {
-          throw EvalError("invalid regular expression ‘%s’, at %s", re, pos);
+          throw EvalError("invalid regular expression '%s', at %s", re, pos);
         }
     }
 }
@@ -1770,7 +1770,7 @@ static void prim_replaceStrings(EvalState & state, const Pos & pos, Value * * ar
     state.forceList(*args[0], pos);
     state.forceList(*args[1], pos);
     if (args[0]->listSize() != args[1]->listSize())
-        throw EvalError(format("‘from’ and ‘to’ arguments to ‘replaceStrings’ have different lengths, at %1%") % pos);
+        throw EvalError(format("'from' and 'to' arguments to 'replaceStrings' have different lengths, at %1%") % pos);
 
     vector<string> from;
     from.reserve(args[0]->listSize());
@@ -1861,17 +1861,17 @@ void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
             else if (n == "name")
                 name = state.forceStringNoCtx(*attr.value, *attr.pos);
             else
-                throw EvalError(format("unsupported argument ‘%1%’ to ‘%2%’, at %3%") % attr.name % who % attr.pos);
+                throw EvalError(format("unsupported argument '%1%' to '%2%', at %3%") % attr.name % who % attr.pos);
         }
 
         if (url.empty())
-            throw EvalError(format("‘url’ argument required, at %1%") % pos);
+            throw EvalError(format("'url' argument required, at %1%") % pos);
 
     } else
         url = state.forceStringNoCtx(*args[0], pos);
 
     if (state.restricted && !expectedHash)
-        throw Error(format("‘%1%’ is not allowed in restricted mode") % who);
+        throw Error(format("'%1%' is not allowed in restricted mode") % who);
 
     Path res = getDownloader()->downloadCached(state.store, url, unpack, name, expectedHash);
     mkString(v, res, PathSet({res}));
diff --git a/src/libexpr/primops/fetchgit.cc b/src/libexpr/primops/fetchgit.cc
index 1e01a452b7e7..e16c8235378d 100644
--- a/src/libexpr/primops/fetchgit.cc
+++ b/src/libexpr/primops/fetchgit.cc
@@ -14,18 +14,18 @@ Path exportGit(ref<Store> store, const std::string & uri,
     const std::string & ref, const std::string & rev)
 {
     if (!isUri(uri))
-        throw EvalError(format("‘%s’ is not a valid URI") % uri);
+        throw EvalError(format("'%s' is not a valid URI") % uri);
 
     if (rev != "") {
         std::regex revRegex("^[0-9a-fA-F]{40}$");
         if (!std::regex_match(rev, revRegex))
-            throw Error("invalid Git revision ‘%s’", rev);
+            throw Error("invalid Git revision '%s'", rev);
     }
 
     // FIXME: too restrictive, but better safe than sorry.
     std::regex refRegex("^[0-9a-zA-Z][0-9a-zA-Z.-]+$");
     if (!std::regex_match(ref, refRegex))
-        throw Error("invalid Git ref ‘%s’", ref);
+        throw Error("invalid Git ref '%s'", ref);
 
     Path cacheDir = getCacheDir() + "/nix/git";
 
@@ -34,7 +34,7 @@ Path exportGit(ref<Store> store, const std::string & uri,
         runProgram("git", true, { "init", "--bare", cacheDir });
     }
 
-    //Activity act(*logger, lvlInfo, format("fetching Git repository ‘%s’") % uri);
+    //Activity act(*logger, lvlInfo, format("fetching Git repository '%s'") % uri);
 
     std::string localRef = hashString(htSHA256, fmt("%s-%s", uri, ref)).to_string(Base32, false);
 
@@ -62,10 +62,10 @@ Path exportGit(ref<Store> store, const std::string & uri,
     std::string commitHash =
         rev != "" ? rev : chomp(readFile(localRefFile));
 
-    printTalkative("using revision %s of repo ‘%s’", uri, commitHash);
+    printTalkative("using revision %s of repo '%s'", uri, commitHash);
 
     Path storeLink = cacheDir + "/" + commitHash + ".link";
-    PathLocks storeLinkLock({storeLink}, fmt("waiting for lock on ‘%1%’...", storeLink));
+    PathLocks storeLinkLock({storeLink}, fmt("waiting for lock on '%1%'...", storeLink));
 
     if (pathExists(storeLink)) {
         auto storePath = readLink(storeLink);
@@ -94,7 +94,7 @@ Path exportGit(ref<Store> store, const std::string & uri,
 static void prim_fetchgit(EvalState & state, const Pos & pos, Value * * args, Value & v)
 {
     // FIXME: cut&paste from fetch().
-    if (state.restricted) throw Error("‘fetchgit’ is not allowed in restricted mode");
+    if (state.restricted) throw Error("'fetchgit' is not allowed in restricted mode");
 
     std::string url;
     std::string ref = "master";
@@ -118,11 +118,11 @@ static void prim_fetchgit(EvalState & state, const Pos & pos, Value * * args, Va
             else if (name == "rev")
                 rev = state.forceStringNoCtx(*attr.value, *attr.pos);
             else
-                throw EvalError("unsupported argument ‘%s’ to ‘fetchgit’, at %s", attr.name, *attr.pos);
+                throw EvalError("unsupported argument '%s' to 'fetchgit', at %s", attr.name, *attr.pos);
         }
 
         if (url.empty())
-            throw EvalError(format("‘url’ argument required, at %1%") % pos);
+            throw EvalError(format("'url' argument required, at %1%") % pos);
 
     } else
         url = state.forceStringNoCtx(*args[0], pos);
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index 48b00e1a399a..67178b4a8915 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -29,7 +29,7 @@ void printGCWarning()
     if (!gcWarning) return;
     static bool haveWarned = false;
     warnOnce(haveWarned,
-        "you did not specify ‘--add-root’; "
+        "you did not specify '--add-root'; "
         "the result might be removed by the garbage collector");
 }
 
@@ -76,7 +76,7 @@ string getArg(const string & opt,
     Strings::iterator & i, const Strings::iterator & end)
 {
     ++i;
-    if (i == end) throw UsageError(format("‘%1%’ requires an argument") % opt);
+    if (i == end) throw UsageError(format("'%1%' requires an argument") % opt);
     return *i;
 }
 
@@ -194,7 +194,7 @@ struct LegacyArgs : public MixCommonArgs
         mkFlag(0, "show-trace", "show Nix expression stack trace in evaluation errors",
             &settings.showTrace);
 
-        mkFlag(0, "no-gc-warning", "disable warning about not using ‘--add-root’",
+        mkFlag(0, "no-gc-warning", "disable warning about not using '--add-root'",
             &gcWarning, false);
     }
 
@@ -213,7 +213,7 @@ struct LegacyArgs : public MixCommonArgs
         Strings ss(args);
         auto pos = ss.begin();
         if (!parseArg(pos, ss.end()))
-            throw UsageError(format("unexpected argument ‘%1%’") % args.front());
+            throw UsageError(format("unexpected argument '%1%'") % args.front());
         return true;
     }
 };
@@ -257,7 +257,7 @@ void showManPage(const string & name)
 {
     restoreSignals();
     execlp("man", "man", name.c_str(), NULL);
-    throw SysError(format("command ‘man %1%’ failed") % name.c_str());
+    throw SysError(format("command 'man %1%' failed") % name.c_str());
 }
 
 
@@ -281,13 +281,13 @@ int handleExceptions(const string & programName, std::function<void()> fun)
         return e.status;
     } catch (UsageError & e) {
         printError(
-            format(error + "%1%\nTry ‘%2% --help’ for more information.")
+            format(error + "%1%\nTry '%2% --help' for more information.")
             % e.what() % programName);
         return 1;
     } catch (BaseError & e) {
         printError(format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg());
         if (e.prefix() != "" && !settings.showTrace)
-            printError("(use ‘--show-trace’ to show detailed location information)");
+            printError("(use '--show-trace' to show detailed location information)");
         return e.status;
     } catch (std::bad_alloc & e) {
         printError(error + "out of memory");
@@ -322,7 +322,7 @@ RunPager::RunPager()
         execlp("pager", "pager", NULL);
         execlp("less", "less", NULL);
         execlp("more", "more", NULL);
-        throw SysError(format("executing ‘%1%’") % pager);
+        throw SysError(format("executing '%1%'") % pager);
     });
 
     pid.setKillSignal(SIGINT);
diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh
index 14e436cc8bb2..becf258734e8 100644
--- a/src/libmain/shared.hh
+++ b/src/libmain/shared.hh
@@ -48,7 +48,7 @@ template<class N> N getIntArg(const string & opt,
     Strings::iterator & i, const Strings::iterator & end, bool allowUnit)
 {
     ++i;
-    if (i == end) throw UsageError(format("‘%1%’ requires an argument") % opt);
+    if (i == end) throw UsageError(format("'%1%' requires an argument") % opt);
     string s = *i;
     N multiplier = 1;
     if (allowUnit && !s.empty()) {
@@ -58,13 +58,13 @@ template<class N> N getIntArg(const string & opt,
             else if (u == 'M') multiplier = 1ULL << 20;
             else if (u == 'G') multiplier = 1ULL << 30;
             else if (u == 'T') multiplier = 1ULL << 40;
-            else throw UsageError(format("invalid unit specifier ‘%1%’") % u);
+            else throw UsageError(format("invalid unit specifier '%1%'") % u);
             s.resize(s.size() - 1);
         }
     }
     N n;
     if (!string2Int(s, n))
-        throw UsageError(format("‘%1%’ requires an integer argument") % opt);
+        throw UsageError(format("'%1%' requires an integer argument") % opt);
     return n * multiplier;
 }
 
diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc
index 8147345c2e1c..403b4687287e 100644
--- a/src/libstore/binary-cache-store.cc
+++ b/src/libstore/binary-cache-store.cc
@@ -39,7 +39,7 @@ struct BinaryCacheStoreAccessor : public FSAccessor
         std::string restPath = std::string(path, storePath.size());
 
         if (!store->isValidPath(storePath))
-            throw InvalidPath(format("path ‘%1%’ is not a valid store path") % storePath);
+            throw InvalidPath(format("path '%1%' is not a valid store path") % storePath);
 
         auto i = nars.find(storePath);
         if (i != nars.end()) return {i->second, restPath};
@@ -103,7 +103,7 @@ void BinaryCacheStore::init()
             auto value = trim(line.substr(colon + 1, std::string::npos));
             if (name == "StoreDir") {
                 if (value != storeDir)
-                    throw Error(format("binary cache ‘%s’ is for Nix stores with prefix ‘%s’, not ‘%s’")
+                    throw Error(format("binary cache '%s' is for Nix stores with prefix '%s', not '%s'")
                         % getUri() % value % storeDir);
             } else if (name == "WantMassQuery") {
                 wantMassQuery_ = value == "1";
@@ -145,7 +145,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
             if (ref != info.path)
                 queryPathInfo(ref);
         } catch (InvalidPath &) {
-            throw Error(format("cannot add ‘%s’ to the binary cache because the reference ‘%s’ is not valid")
+            throw Error(format("cannot add '%s' to the binary cache because the reference '%s' is not valid")
                 % info.path % ref);
         }
 
@@ -159,7 +159,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
     narInfo->narHash = hashString(htSHA256, *nar);
 
     if (info.narHash && info.narHash != narInfo->narHash)
-        throw Error(format("refusing to copy corrupted path ‘%1%’ to binary cache") % info.path);
+        throw Error(format("refusing to copy corrupted path '%1%' to binary cache") % info.path);
 
     auto accessor_ = std::dynamic_pointer_cast<BinaryCacheStoreAccessor>(accessor);
 
@@ -233,7 +233,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::str
     narInfo->fileSize = narCompressed->size();
 
     auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now2 - now1).count();
-    printMsg(lvlTalkative, format("copying path ‘%1%’ (%2% bytes, compressed %3$.1f%% in %4% ms) to binary cache")
+    printMsg(lvlTalkative, format("copying path '%1%' (%2% bytes, compressed %3$.1f%% in %4% ms) to binary cache")
         % narInfo->path % narInfo->narSize
         % ((1.0 - (double) narCompressed->size() / nar->size()) * 100.0)
         % duration);
@@ -286,7 +286,7 @@ void BinaryCacheStore::narFromPath(const Path & storePath, Sink & sink)
 
     auto nar = getFile(info->url);
 
-    if (!nar) throw Error(format("file ‘%s’ missing from binary cache") % info->url);
+    if (!nar) throw Error(format("file '%s' missing from binary cache") % info->url);
 
     stats.narRead++;
     stats.narReadCompressedBytes += nar->size();
@@ -296,13 +296,13 @@ void BinaryCacheStore::narFromPath(const Path & storePath, Sink & sink)
     try {
         nar = decompress(info->compression, *nar);
     } catch (UnknownCompressionMethod &) {
-        throw Error(format("binary cache path ‘%s’ uses unknown compression method ‘%s’")
+        throw Error(format("binary cache path '%s' uses unknown compression method '%s'")
             % storePath % info->compression);
     }
 
     stats.narReadBytes += nar->size();
 
-    printMsg(lvlTalkative, format("exporting path ‘%1%’ (%2% bytes)") % storePath % nar->size());
+    printMsg(lvlTalkative, format("exporting path '%1%' (%2% bytes)") % storePath % nar->size());
 
     assert(nar->size() % 8 == 0);
 
@@ -394,7 +394,7 @@ std::shared_ptr<std::string> BinaryCacheStore::getBuildLog(const Path & path)
 
     auto logPath = "log/" + baseNameOf(drvPath);
 
-    debug("fetching build log from binary cache ‘%s/%s’", getUri(), logPath);
+    debug("fetching build log from binary cache '%s/%s'", getUri(), logPath);
 
     return getFile(logPath);
 }
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 8f483a90daad..db5f606fa883 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -341,7 +341,7 @@ void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
     assert(waitees.find(waitee) != waitees.end());
     waitees.erase(waitee);
 
-    trace(format("waitee ‘%1%’ done; %2% left") %
+    trace(format("waitee '%1%' done; %2% left") %
         waitee->name % waitees.size());
 
     if (result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure) ++nrFailed;
@@ -415,7 +415,7 @@ static void commonChildInit(Pipe & logPipe)
     /* Reroute stdin to /dev/null. */
     int fdDevNull = open(pathNullDevice.c_str(), O_RDWR);
     if (fdDevNull == -1)
-        throw SysError(format("cannot open ‘%1%’") % pathNullDevice);
+        throw SysError(format("cannot open '%1%'") % pathNullDevice);
     if (dup2(fdDevNull, STDIN_FILENO) == -1)
         throw SysError("cannot dup null device into stdin");
     close(fdDevNull);
@@ -468,29 +468,29 @@ UserLock::UserLock()
     /* Get the members of the build-users-group. */
     struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
     if (!gr)
-        throw Error(format("the group ‘%1%’ specified in ‘build-users-group’ does not exist")
+        throw Error(format("the group '%1%' specified in 'build-users-group' does not exist")
             % settings.buildUsersGroup);
     gid = gr->gr_gid;
 
     /* Copy the result of getgrnam. */
     Strings users;
     for (char * * p = gr->gr_mem; *p; ++p) {
-        debug(format("found build user ‘%1%’") % *p);
+        debug(format("found build user '%1%'") % *p);
         users.push_back(*p);
     }
 
     if (users.empty())
-        throw Error(format("the build users group ‘%1%’ has no members")
+        throw Error(format("the build users group '%1%' has no members")
             % settings.buildUsersGroup);
 
     /* Find a user account that isn't currently in use for another
        build. */
     for (auto & i : users) {
-        debug(format("trying user ‘%1%’") % i);
+        debug(format("trying user '%1%'") % i);
 
         struct passwd * pw = getpwnam(i.c_str());
         if (!pw)
-            throw Error(format("the user ‘%1%’ in the group ‘%2%’ does not exist")
+            throw Error(format("the user '%1%' in the group '%2%' does not exist")
                 % i % settings.buildUsersGroup);
 
         createDirs(settings.nixStateDir + "/userpool");
@@ -509,7 +509,7 @@ UserLock::UserLock()
 
             AutoCloseFD fd = open(fnUserLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
             if (!fd)
-                throw SysError(format("opening user lock ‘%1%’") % fnUserLock);
+                throw SysError(format("opening user lock '%1%'") % fnUserLock);
 
             if (lockFile(fd.get(), ltWrite, false)) {
                 fdUserLock = std::move(fd);
@@ -518,7 +518,7 @@ UserLock::UserLock()
 
                 /* Sanity check... */
                 if (uid == getuid() || uid == geteuid())
-                    throw Error(format("the Nix user should not be a member of ‘%1%’")
+                    throw Error(format("the Nix user should not be a member of '%1%'")
                         % settings.buildUsersGroup);
 
 #if __linux__
@@ -529,7 +529,7 @@ UserLock::UserLock()
                 int err = getgrouplist(pw->pw_name, pw->pw_gid,
                     supplementaryGIDs.data(), &ngroups);
                 if (err == -1)
-                    throw Error(format("failed to get list of supplementary groups for ‘%1%’") % pw->pw_name);
+                    throw Error(format("failed to get list of supplementary groups for '%1%'") % pw->pw_name);
 
                 supplementaryGIDs.resize(ngroups);
 #endif
@@ -543,7 +543,7 @@ UserLock::UserLock()
     }
 
     throw Error(format("all build users are currently in use; "
-        "consider creating additional users and adding them to the ‘%1%’ group")
+        "consider creating additional users and adding them to the '%1%' group")
         % settings.buildUsersGroup);
 }
 
@@ -587,7 +587,7 @@ struct HookInstance
 
 HookInstance::HookInstance()
 {
-    debug("starting build hook ‘%s’", settings.buildHook);
+    debug("starting build hook '%s'", settings.buildHook);
 
     /* Create a pipe to get the output of the child. */
     fromHook.create();
@@ -624,7 +624,7 @@ HookInstance::HookInstance()
 
         execv(settings.buildHook.get().c_str(), stringsToCharPtrs(args).data());
 
-        throw SysError("executing ‘%s’", settings.buildHook);
+        throw SysError("executing '%s'", settings.buildHook);
     });
 
     pid.setSeparatePG(true);
@@ -927,7 +927,7 @@ DerivationGoal::DerivationGoal(const Path & drvPath, const StringSet & wantedOut
     , buildMode(buildMode)
 {
     state = &DerivationGoal::getDerivation;
-    name = (format("building of ‘%1%’") % drvPath).str();
+    name = (format("building of '%1%'") % drvPath).str();
     trace("created");
 
     logger->event(evBuildCreated, act, drvPath);
@@ -1042,7 +1042,7 @@ void DerivationGoal::loadDerivation()
     trace("loading derivation");
 
     if (nrFailed != 0) {
-        printError(format("cannot build missing derivation ‘%1%’") % drvPath);
+        printError(format("cannot build missing derivation '%1%'") % drvPath);
         done(BuildResult::MiscFailure);
         return;
     }
@@ -1080,7 +1080,7 @@ void DerivationGoal::haveDerivation()
     /* Reject doing a hash build of anything other than a fixed-output
        derivation. */
     if (buildMode == bmHash && !drv->isFixedOutput())
-        throw Error("cannot do a hash build of non-fixed-output derivation ‘%1%’", drvPath);
+        throw Error("cannot do a hash build of non-fixed-output derivation '%1%'", drvPath);
 
     /* We are first going to try to create the invalid output paths
        through substitutes.  If that doesn't work, we'll build
@@ -1101,7 +1101,7 @@ void DerivationGoal::outputsSubstituted()
     trace("all outputs substituted (maybe)");
 
     if (nrFailed > 0 && nrFailed > nrNoSubstituters + nrIncompleteClosure && !settings.tryFallback) {
-        done(BuildResult::TransientFailure, (format("some substitutes for the outputs of derivation ‘%1%’ failed (usually happens due to networking issues); try ‘--fallback’ to build derivation from source ") % drvPath).str());
+        done(BuildResult::TransientFailure, (format("some substitutes for the outputs of derivation '%1%' failed (usually happens due to networking issues); try '--fallback' to build derivation from source ") % drvPath).str());
         return;
     }
 
@@ -1128,7 +1128,7 @@ void DerivationGoal::outputsSubstituted()
         return;
     }
     if (buildMode == bmCheck && nrInvalid > 0)
-        throw Error(format("some outputs of ‘%1%’ are not valid, so checking is not possible") % drvPath);
+        throw Error(format("some outputs of '%1%' are not valid, so checking is not possible") % drvPath);
 
     /* Otherwise, at least one of the output paths could not be
        produced using a substitute.  So we have to build instead. */
@@ -1145,7 +1145,7 @@ void DerivationGoal::outputsSubstituted()
     for (auto & i : drv->inputSrcs) {
         if (worker.store.isValidPath(i)) continue;
         if (!settings.useSubstitutes)
-            throw Error(format("dependency of ‘%1%’ of ‘%2%’ does not exist, and substitution is disabled")
+            throw Error(format("dependency of '%1%' of '%2%' does not exist, and substitution is disabled")
                 % i % drvPath);
         addWaitee(worker.makeSubstitutionGoal(i));
     }
@@ -1192,7 +1192,7 @@ void DerivationGoal::repairClosure()
     PathSet broken;
     for (auto & i : outputClosure) {
         if (worker.pathContentsGood(i)) continue;
-        printError(format("found corrupted or missing path ‘%1%’ in the output closure of ‘%2%’") % i % drvPath);
+        printError(format("found corrupted or missing path '%1%' in the output closure of '%2%'") % i % drvPath);
         Path drvPath2 = outputsToDrv[i];
         if (drvPath2 == "")
             addWaitee(worker.makeSubstitutionGoal(i, Repair));
@@ -1213,7 +1213,7 @@ void DerivationGoal::closureRepaired()
 {
     trace("closure repaired");
     if (nrFailed > 0)
-        throw Error(format("some paths in the output closure of derivation ‘%1%’ could not be repaired") % drvPath);
+        throw Error(format("some paths in the output closure of derivation '%1%' could not be repaired") % drvPath);
     done(BuildResult::AlreadyValid);
 }
 
@@ -1224,9 +1224,9 @@ void DerivationGoal::inputsRealised()
 
     if (nrFailed != 0) {
         if (!useDerivation)
-            throw Error(format("some dependencies of ‘%1%’ are missing") % drvPath);
+            throw Error(format("some dependencies of '%1%' are missing") % drvPath);
         printError(
-            format("cannot build derivation ‘%1%’: %2% dependencies couldn't be built")
+            format("cannot build derivation '%1%': %2% dependencies couldn't be built")
             % drvPath % nrFailed);
         done(BuildResult::DependencyFailed);
         return;
@@ -1242,7 +1242,7 @@ void DerivationGoal::inputsRealised()
 
     /* The outputs are referenceable paths. */
     for (auto & i : drv->outputs) {
-        debug(format("building path ‘%1%’") % i.second.path);
+        debug(format("building path '%1%'") % i.second.path);
         allPaths.insert(i.second.path);
     }
 
@@ -1261,7 +1261,7 @@ void DerivationGoal::inputsRealised()
                     worker.store.computeFSClosure(inDrv.outputs[j].path, inputPaths);
                 else
                     throw Error(
-                        format("derivation ‘%1%’ requires non-existent output ‘%2%’ from input derivation ‘%3%’")
+                        format("derivation '%1%' requires non-existent output '%2%' from input derivation '%3%'")
                         % drvPath % j % i.first);
         }
 
@@ -1302,7 +1302,7 @@ void DerivationGoal::tryToBuild()
        goal to sleep until another goal finishes, then try again. */
     for (auto & i : drv->outputs)
         if (pathIsLockedByMe(worker.store.toRealPath(i.second.path))) {
-            debug(format("putting derivation ‘%1%’ to sleep because ‘%2%’ is locked by another goal")
+            debug(format("putting derivation '%1%' to sleep because '%2%' is locked by another goal")
                 % drvPath % i.second.path);
             worker.waitForAnyGoal(shared_from_this());
             return;
@@ -1331,7 +1331,7 @@ void DerivationGoal::tryToBuild()
        build this derivation, so no further checks are necessary. */
     validPaths = checkPathValidity(true, buildMode == bmRepair);
     if (buildMode != bmCheck && validPaths.size() == drv->outputs.size()) {
-        debug(format("skipping build of derivation ‘%1%’, someone beat us to it") % drvPath);
+        debug(format("skipping build of derivation '%1%', someone beat us to it") % drvPath);
         outputLocks.setDeletion(true);
         done(BuildResult::AlreadyValid);
         return;
@@ -1346,7 +1346,7 @@ void DerivationGoal::tryToBuild()
     for (auto & i : drv->outputs) {
         Path path = i.second.path;
         if (worker.store.isValidPath(path)) continue;
-        debug(format("removing invalid path ‘%1%’") % path);
+        debug(format("removing invalid path '%1%'") % path);
         deletePath(worker.store.toRealPath(path));
     }
 
@@ -1416,7 +1416,7 @@ void replaceValidPath(const Path & storePath, const Path tmpPath)
     if (pathExists(storePath))
         rename(storePath.c_str(), oldPath.c_str());
     if (rename(tmpPath.c_str(), storePath.c_str()) == -1)
-        throw SysError(format("moving ‘%1%’ to ‘%2%’") % tmpPath % storePath);
+        throw SysError(format("moving '%1%' to '%2%'") % tmpPath % storePath);
     deletePath(oldPath);
 }
 
@@ -1439,7 +1439,7 @@ void DerivationGoal::buildDone()
        kill it. */
     int status = hook ? hook->pid.kill() : pid.kill();
 
-    debug(format("builder process for ‘%1%’ finished") % drvPath);
+    debug(format("builder process for '%1%' finished") % drvPath);
 
     result.timesBuilt++;
     result.stopTime = time(0);
@@ -1496,7 +1496,7 @@ void DerivationGoal::buildDone()
                     if (pathExists(chrootRootDir + i))
                         rename((chrootRootDir + i).c_str(), i.c_str());
 
-            std::string msg = (format("builder for ‘%1%’ %2%")
+            std::string msg = (format("builder for '%1%' %2%")
                 % drvPath % statusToString(status)).str();
 
             if (!settings.verboseBuild && !logTail.empty()) {
@@ -1606,7 +1606,7 @@ HookReply DerivationGoal::tryBuildHook()
             writeToStderr(s);
         }
 
-        debug(format("hook reply is ‘%1%’") % reply);
+        debug(format("hook reply is '%1%'") % reply);
 
         if (reply == "decline")
             return rpDecline;
@@ -1618,7 +1618,7 @@ HookReply DerivationGoal::tryBuildHook()
         else if (reply == "postpone")
             return rpPostpone;
         else if (reply != "accept")
-            throw Error(format("bad hook reply ‘%1%’") % reply);
+            throw Error(format("bad hook reply '%1%'") % reply);
 
     } catch (SysError & e) {
         if (e.errNo == EPIPE) {
@@ -1659,7 +1659,7 @@ HookReply DerivationGoal::tryBuildHook()
 void chmod_(const Path & path, mode_t mode)
 {
     if (chmod(path.c_str(), mode) == -1)
-        throw SysError(format("setting permissions on ‘%1%’") % path);
+        throw SysError(format("setting permissions on '%1%'") % path);
 }
 
 
@@ -1683,7 +1683,7 @@ void DerivationGoal::startBuilder()
     /* Right platform? */
     if (!drv->canBuildLocally()) {
         throw Error(
-            format("a ‘%1%’ is required to build ‘%3%’, but I am a ‘%2%’")
+            format("a '%1%' is required to build '%3%', but I am a '%2%'")
             % drv->platform % settings.thisSystem % drvPath);
     }
 
@@ -1695,12 +1695,12 @@ void DerivationGoal::startBuilder()
     {
         if (settings.sandboxMode == smEnabled) {
             if (get(drv->env, "__noChroot") == "1")
-                throw Error(format("derivation ‘%1%’ has ‘__noChroot’ set, "
-                    "but that's not allowed when ‘build-use-sandbox’ is ‘true’") % drvPath);
+                throw Error(format("derivation '%1%' has '__noChroot' set, "
+                    "but that's not allowed when 'build-use-sandbox' is 'true'") % drvPath);
 #if __APPLE__
             if (additionalSandboxProfile != "")
-                throw Error(format("derivation ‘%1%’ specifies a sandbox profile, "
-                    "but this is only allowed when ‘build-use-sandbox’ is ‘relaxed’") % drvPath);
+                throw Error(format("derivation '%1%' specifies a sandbox profile, "
+                    "but this is only allowed when 'build-use-sandbox' is 'relaxed'") % drvPath);
 #endif
             useChroot = true;
         }
@@ -1788,7 +1788,7 @@ void DerivationGoal::startBuilder()
                     worker.store.computeFSClosure(worker.store.toStorePath(i.second.source), closure);
             } catch (InvalidPath & e) {
             } catch (Error & e) {
-                throw Error(format("while processing ‘build-sandbox-paths’: %s") % e.what());
+                throw Error(format("while processing 'build-sandbox-paths': %s") % e.what());
             }
         for (auto & i : closure)
             dirsInChroot[i] = i;
@@ -1813,7 +1813,7 @@ void DerivationGoal::startBuilder()
                 }
             }
             if (!found)
-                throw Error(format("derivation ‘%1%’ requested impure path ‘%2%’, but it was not in allowed-impure-host-deps") % drvPath % i);
+                throw Error(format("derivation '%1%' requested impure path '%2%', but it was not in allowed-impure-host-deps") % drvPath % i);
 
             dirsInChroot[i] = i;
         }
@@ -1829,13 +1829,13 @@ void DerivationGoal::startBuilder()
         /* Clean up the chroot directory automatically. */
         autoDelChroot = std::make_shared<AutoDelete>(chrootRootDir);
 
-        printMsg(lvlChatty, format("setting up chroot environment in ‘%1%’") % chrootRootDir);
+        printMsg(lvlChatty, format("setting up chroot environment in '%1%'") % chrootRootDir);
 
         if (mkdir(chrootRootDir.c_str(), 0750) == -1)
-            throw SysError(format("cannot create ‘%1%’") % chrootRootDir);
+            throw SysError(format("cannot create '%1%'") % chrootRootDir);
 
         if (buildUser && chown(chrootRootDir.c_str(), 0, buildUser->getGID()) == -1)
-            throw SysError(format("cannot change ownership of ‘%1%’") % chrootRootDir);
+            throw SysError(format("cannot change ownership of '%1%'") % chrootRootDir);
 
         /* Create a writable /tmp in the chroot.  Many builders need
            this.  (Of course they should really respect $TMPDIR
@@ -1879,25 +1879,25 @@ void DerivationGoal::startBuilder()
         chmod_(chrootStoreDir, 01775);
 
         if (buildUser && chown(chrootStoreDir.c_str(), 0, buildUser->getGID()) == -1)
-            throw SysError(format("cannot change ownership of ‘%1%’") % chrootStoreDir);
+            throw SysError(format("cannot change ownership of '%1%'") % chrootStoreDir);
 
         for (auto & i : inputPaths) {
             Path r = worker.store.toRealPath(i);
             struct stat st;
             if (lstat(r.c_str(), &st))
-                throw SysError(format("getting attributes of path ‘%1%’") % i);
+                throw SysError(format("getting attributes of path '%1%'") % i);
             if (S_ISDIR(st.st_mode))
                 dirsInChroot[i] = r;
             else {
                 Path p = chrootRootDir + i;
-                debug("linking ‘%1%’ to ‘%2%’", p, r);
+                debug("linking '%1%' to '%2%'", p, r);
                 if (link(r.c_str(), p.c_str()) == -1) {
                     /* Hard-linking fails if we exceed the maximum
                        link count on a file (e.g. 32000 of ext3),
                        which is quite possible after a `nix-store
                        --optimise'. */
                     if (errno != EMLINK)
-                        throw SysError(format("linking ‘%1%’ to ‘%2%’") % p % i);
+                        throw SysError(format("linking '%1%' to '%2%'") % p % i);
                     StringSink sink;
                     dumpPath(r, sink);
                     StringSource source(*sink.s);
@@ -1925,7 +1925,7 @@ void DerivationGoal::startBuilder()
     else {
 
         if (pathExists(homeDir))
-            throw Error(format("directory ‘%1%’ exists; please remove it") % homeDir);
+            throw Error(format("directory '%1%' exists; please remove it") % homeDir);
 
         /* We're not doing a chroot build, but we have some valid
            output paths.  Since we can't just overwrite or delete
@@ -1951,7 +1951,7 @@ void DerivationGoal::startBuilder()
     }
 
     if (useChroot && settings.preBuildHook != "" && dynamic_cast<Derivation *>(drv.get())) {
-        printMsg(lvlChatty, format("executing pre-build hook ‘%1%’")
+        printMsg(lvlChatty, format("executing pre-build hook '%1%'")
             % settings.preBuildHook);
         auto args = useChroot ? Strings({drvPath, chrootRootDir}) :
             Strings({ drvPath });
@@ -1970,7 +1970,7 @@ void DerivationGoal::startBuilder()
                 if (line == "extra-sandbox-paths" || line == "extra-chroot-dirs") {
                     state = stExtraChrootDirs;
                 } else {
-                    throw Error(format("unknown pre-build hook command ‘%1%’")
+                    throw Error(format("unknown pre-build hook command '%1%'")
                         % line);
                 }
             } else if (state == stExtraChrootDirs) {
@@ -1988,7 +1988,7 @@ void DerivationGoal::startBuilder()
     }
 
     /* Run the builder. */
-    printMsg(lvlChatty, format("executing builder ‘%1%’") % drv->builder);
+    printMsg(lvlChatty, format("executing builder '%1%'") % drv->builder);
 
     /* Create the log file. */
     Path logFile = openLogFile();
@@ -2232,7 +2232,7 @@ void DerivationGoal::chownToBuilder(const Path & path)
 {
     if (!buildUser) return;
     if (chown(path.c_str(), buildUser->getUID(), buildUser->getGID()) == -1)
-        throw SysError(format("cannot change ownership of ‘%1%’") % path);
+        throw SysError(format("cannot change ownership of '%1%'") % path);
 }
 
 
@@ -2248,7 +2248,7 @@ void DerivationGoal::doExportReferencesGraph()
     string s = get(drv->env, "exportReferencesGraph");
     Strings ss = tokenizeString<Strings>(s);
     if (ss.size() % 2 != 0)
-        throw BuildError(format("odd number of tokens in ‘exportReferencesGraph’: ‘%1%’") % s);
+        throw BuildError(format("odd number of tokens in 'exportReferencesGraph': '%1%'") % s);
     for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
         string fileName = *i++;
         checkStoreName(fileName); /* !!! abuse of this function */
@@ -2256,11 +2256,11 @@ void DerivationGoal::doExportReferencesGraph()
         /* Check that the store path is valid. */
         Path storePath = *i++;
         if (!worker.store.isInStore(storePath))
-            throw BuildError(format("‘exportReferencesGraph’ contains a non-store path ‘%1%’")
+            throw BuildError(format("'exportReferencesGraph' contains a non-store path '%1%'")
                 % storePath);
         storePath = worker.store.toStorePath(storePath);
         if (!worker.store.isValidPath(storePath))
-            throw BuildError(format("‘exportReferencesGraph’ contains an invalid path ‘%1%’")
+            throw BuildError(format("'exportReferencesGraph' contains an invalid path '%1%'")
                 % storePath);
 
         /* If there are derivations in the graph, then include their
@@ -2418,13 +2418,13 @@ void DerivationGoal::runChild()
                local to the namespace, though, so setting MS_PRIVATE
                does not affect the outside world. */
             if (mount(0, "/", 0, MS_REC|MS_PRIVATE, 0) == -1) {
-                throw SysError("unable to make ‘/’ private mount");
+                throw SysError("unable to make '/' private mount");
             }
 
             /* Bind-mount chroot directory to itself, to treat it as a
                different filesystem from /, as needed for pivot_root. */
             if (mount(chrootRootDir.c_str(), chrootRootDir.c_str(), 0, MS_BIND, 0) == -1)
-                throw SysError(format("unable to bind mount ‘%1%’") % chrootRootDir);
+                throw SysError(format("unable to bind mount '%1%'") % chrootRootDir);
 
             /* Set up a nearly empty /dev, unless the user asked to
                bind-mount the host /dev. */
@@ -2464,13 +2464,13 @@ void DerivationGoal::runChild()
                filesystem that we want in the chroot
                environment. */
             auto doBind = [&](const Path & source, const Path & target, bool optional = false) {
-                debug(format("bind mounting ‘%1%’ to ‘%2%’") % source % target);
+                debug(format("bind mounting '%1%' to '%2%'") % source % target);
                 struct stat st;
                 if (stat(source.c_str(), &st) == -1) {
                     if (optional && errno == ENOENT)
                         return;
                     else
-                        throw SysError("getting attributes of path ‘%1%’", source);
+                        throw SysError("getting attributes of path '%1%'", source);
                 }
                 if (S_ISDIR(st.st_mode))
                     createDirs(target);
@@ -2479,7 +2479,7 @@ void DerivationGoal::runChild()
                     writeFile(target, "");
                 }
                 if (mount(source.c_str(), target.c_str(), "", MS_BIND | MS_REC, 0) == -1)
-                    throw SysError("bind mount from ‘%1%’ to ‘%2%’ failed", source, target);
+                    throw SysError("bind mount from '%1%' to '%2%' failed", source, target);
             };
 
             for (auto & i : dirsInChroot) {
@@ -2523,16 +2523,16 @@ void DerivationGoal::runChild()
 
             /* Do the chroot(). */
             if (chdir(chrootRootDir.c_str()) == -1)
-                throw SysError(format("cannot change directory to ‘%1%’") % chrootRootDir);
+                throw SysError(format("cannot change directory to '%1%'") % chrootRootDir);
 
             if (mkdir("real-root", 0) == -1)
                 throw SysError("cannot create real-root directory");
 
             if (pivot_root(".", "real-root") == -1)
-                throw SysError(format("cannot pivot old root directory onto ‘%1%’") % (chrootRootDir + "/real-root"));
+                throw SysError(format("cannot pivot old root directory onto '%1%'") % (chrootRootDir + "/real-root"));
 
             if (chroot(".") == -1)
-                throw SysError(format("cannot change root directory to ‘%1%’") % chrootRootDir);
+                throw SysError(format("cannot change root directory to '%1%'") % chrootRootDir);
 
             if (umount2("real-root", MNT_DETACH) == -1)
                 throw SysError("cannot unmount real root filesystem");
@@ -2553,7 +2553,7 @@ void DerivationGoal::runChild()
 #endif
 
         if (chdir(tmpDirInSandbox.c_str()) == -1)
-            throw SysError(format("changing into ‘%1%’") % tmpDir);
+            throw SysError(format("changing into '%1%'") % tmpDir);
 
         /* Close all other file descriptors. */
         closeMostFDs(set<int>());
@@ -2699,7 +2699,7 @@ void DerivationGoal::runChild()
                     if (lstat(path.c_str(), &st)) {
                         if (i.second.optional && errno == ENOENT)
                             continue;
-                        throw SysError(format("getting attributes of path ‘%1%’") % path);
+                        throw SysError(format("getting attributes of path '%1%'") % path);
                     }
                     if (S_ISDIR(st.st_mode))
                         sandboxProfile += (format("\t(subpath \"%1%\")\n") % path).str();
@@ -2762,7 +2762,7 @@ void DerivationGoal::runChild()
                 if (drv->builder == "builtin:fetchurl")
                     builtinFetchurl(*drv, netrcData);
                 else
-                    throw Error(format("unsupported builtin function ‘%1%’") % string(drv->builder, 8));
+                    throw Error(format("unsupported builtin function '%1%'") % string(drv->builder, 8));
                 _exit(0);
             } catch (std::exception & e) {
                 writeFull(STDERR_FILENO, "error: " + string(e.what()) + "\n");
@@ -2772,7 +2772,7 @@ void DerivationGoal::runChild()
 
         execve(builder, stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
 
-        throw SysError(format("executing ‘%1%’") % drv->builder);
+        throw SysError(format("executing '%1%'") % drv->builder);
 
     } catch (std::exception & e) {
         writeFull(STDERR_FILENO, "\1while setting up the build environment: " + string(e.what()) + "\n");
@@ -2794,7 +2794,7 @@ PathSet parseReferenceSpecifiers(Store & store, const BasicDerivation & drv, str
         else if (drv.outputs.find(i) != drv.outputs.end())
             result.insert(drv.outputs.find(i)->second.path);
         else throw BuildError(
-            format("derivation contains an illegal reference specifier ‘%1%’") % i);
+            format("derivation contains an illegal reference specifier '%1%'") % i);
     }
     return result;
 }
@@ -2841,7 +2841,7 @@ void DerivationGoal::registerOutputs()
                     replaceValidPath(path, actualPath);
                 else
                     if (buildMode != bmCheck && rename(actualPath.c_str(), worker.store.toRealPath(path).c_str()) == -1)
-                        throw SysError(format("moving build output ‘%1%’ from the sandbox to the Nix store") % path);
+                        throw SysError(format("moving build output '%1%' from the sandbox to the Nix store") % path);
             }
             if (buildMode != bmCheck) actualPath = worker.store.toRealPath(path);
         } else {
@@ -2858,9 +2858,9 @@ void DerivationGoal::registerOutputs()
         if (lstat(actualPath.c_str(), &st) == -1) {
             if (errno == ENOENT)
                 throw BuildError(
-                    format("builder for ‘%1%’ failed to produce output path ‘%2%’")
+                    format("builder for '%1%' failed to produce output path '%2%'")
                     % drvPath % path);
-            throw SysError(format("getting attributes of path ‘%1%’") % actualPath);
+            throw SysError(format("getting attributes of path '%1%'") % actualPath);
         }
 
 #ifndef __CYGWIN__
@@ -2870,13 +2870,13 @@ void DerivationGoal::registerOutputs()
            user. */
         if ((!S_ISLNK(st.st_mode) && (st.st_mode & (S_IWGRP | S_IWOTH))) ||
             (buildUser && st.st_uid != buildUser->getUID()))
-            throw BuildError(format("suspicious ownership or permission on ‘%1%’; rejecting this build output") % path);
+            throw BuildError(format("suspicious ownership or permission on '%1%'; rejecting this build output") % path);
 #endif
 
         /* Apply hash rewriting if necessary. */
         bool rewritten = false;
         if (!outputRewrites.empty()) {
-            printError(format("warning: rewriting hashes in ‘%1%’; cross fingers") % path);
+            printError(format("warning: rewriting hashes in '%1%'; cross fingers") % path);
 
             /* Canonicalise first.  This ensures that the path we're
                rewriting doesn't contain a hard link to /etc/shadow or
@@ -2907,7 +2907,7 @@ void DerivationGoal::registerOutputs()
                    execute permission. */
                 if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
                     throw BuildError(
-                        format("output path ‘%1%’ should be a non-executable regular file") % path);
+                        format("output path '%1%' should be a non-executable regular file") % path);
             }
 
             /* Check the hash. In hash mode, move the path produced by
@@ -2915,7 +2915,7 @@ void DerivationGoal::registerOutputs()
             Hash h2 = recursive ? hashPath(h.type, actualPath).first : hashFile(h.type, actualPath);
             if (buildMode == bmHash) {
                 Path dest = worker.store.makeFixedOutputPath(recursive, h2, drv->env["name"]);
-                printError(format("build produced path ‘%1%’ with %2% hash ‘%3%’")
+                printError(format("build produced path '%1%' with %2% hash '%3%'")
                     % dest % printHashType(h.type) % printHash16or32(h2));
                 if (worker.store.isValidPath(dest))
                     return;
@@ -2924,14 +2924,14 @@ void DerivationGoal::registerOutputs()
                     PathLocks outputLocks({actualDest});
                     deletePath(actualDest);
                     if (rename(actualPath.c_str(), actualDest.c_str()) == -1)
-                        throw SysError(format("moving ‘%1%’ to ‘%2%’") % actualPath % dest);
+                        throw SysError(format("moving '%1%' to '%2%'") % actualPath % dest);
                 }
                 path = dest;
                 actualPath = actualDest;
             } else {
                 if (h != h2)
                     throw BuildError(
-                        format("output path ‘%1%’ has %2% hash ‘%3%’ when ‘%4%’ was expected")
+                        format("output path '%1%' has %2% hash '%3%' when '%4%' was expected")
                         % path % i.second.hashAlgo % printHash16or32(h2) % printHash16or32(h));
             }
 
@@ -2947,7 +2947,7 @@ void DerivationGoal::registerOutputs()
            contained in it.  Compute the SHA-256 NAR hash at the same
            time.  The hash is stored in the database so that we can
            verify later on whether nobody has messed with the store. */
-        debug("scanning for references inside ‘%1%’", path);
+        debug("scanning for references inside '%1%'", path);
         HashResult hash;
         PathSet references = scanForReferences(actualPath, allPaths, hash);
 
@@ -2959,11 +2959,11 @@ void DerivationGoal::registerOutputs()
                     Path dst = worker.store.toRealPath(path + checkSuffix);
                     deletePath(dst);
                     if (rename(actualPath.c_str(), dst.c_str()))
-                        throw SysError(format("renaming ‘%1%’ to ‘%2%’") % actualPath % dst);
-                    throw Error(format("derivation ‘%1%’ may not be deterministic: output ‘%2%’ differs from ‘%3%’")
+                        throw SysError(format("renaming '%1%' to '%2%'") % actualPath % dst);
+                    throw Error(format("derivation '%1%' may not be deterministic: output '%2%' differs from '%3%'")
                         % drvPath % path % dst);
                 } else
-                    throw Error(format("derivation ‘%1%’ may not be deterministic: output ‘%2%’ differs")
+                    throw Error(format("derivation '%1%' may not be deterministic: output '%2%' differs")
                         % drvPath % path);
             }
 
@@ -2983,9 +2983,9 @@ void DerivationGoal::registerOutputs()
         for (auto & i : inputPaths) {
             PathSet::iterator j = references.find(i);
             if (j == references.end())
-                debug(format("unreferenced input: ‘%1%’") % i);
+                debug(format("unreferenced input: '%1%'") % i);
             else
-                debug(format("referenced input: ‘%1%’") % i);
+                debug(format("referenced input: '%1%'") % i);
         }
 
         /* Enforce `allowedReferences' and friends. */
@@ -3021,7 +3021,7 @@ void DerivationGoal::registerOutputs()
                     badPathsStr += "\n\t";
                     badPathsStr += i;
                 }
-                throw BuildError(format("output ‘%1%’ is not allowed to refer to the following paths:%2%") % actualPath % badPathsStr);
+                throw BuildError(format("output '%1%' is not allowed to refer to the following paths:%2%") % actualPath % badPathsStr);
             }
         };
 
@@ -3058,8 +3058,8 @@ void DerivationGoal::registerOutputs()
                 Path prev = i->path + checkSuffix;
                 bool prevExists = keepPreviousRound && pathExists(prev);
                 auto msg = prevExists
-                    ? fmt("output ‘%1%’ of ‘%2%’ differs from ‘%3%’ from previous round", i->path, drvPath, prev)
-                    : fmt("output ‘%1%’ of ‘%2%’ differs from previous round", i->path, drvPath);
+                    ? fmt("output '%1%' of '%2%' differs from '%3%' from previous round", i->path, drvPath, prev)
+                    : fmt("output '%1%' of '%2%' differs from previous round", i->path, drvPath);
 
                 auto diffHook = settings.diffHook;
                 if (prevExists && diffHook != "" && runDiffHook) {
@@ -3088,7 +3088,7 @@ void DerivationGoal::registerOutputs()
             deletePath(prev);
             Path dst = i.second.path + checkSuffix;
             if (rename(i.second.path.c_str(), dst.c_str()))
-                throw SysError(format("renaming ‘%1%’ to ‘%2%’") % i.second.path % dst);
+                throw SysError(format("renaming '%1%' to '%2%'") % i.second.path % dst);
         }
     }
 
@@ -3129,7 +3129,7 @@ Path DerivationGoal::openLogFile()
         settings.compressLog ? ".bz2" : "");
 
     fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0666);
-    if (!fdLogFile) throw SysError(format("creating log file ‘%1%’") % logFileName);
+    if (!fdLogFile) throw SysError(format("creating log file '%1%'") % logFileName);
 
     logFileSink = std::make_shared<FdSink>(fdLogFile.get());
 
@@ -3159,7 +3159,7 @@ void DerivationGoal::deleteTmpDir(bool force)
            might have privileged stuff (like a copy of netrc). */
         if (settings.keepFailed && !force && !drv->isBuiltin()) {
             printError(
-                format("note: keeping build directory ‘%2%’")
+                format("note: keeping build directory '%2%'")
                 % drvPath % tmpDir);
             chmod(tmpDir.c_str(), 0755);
         }
@@ -3351,7 +3351,7 @@ SubstitutionGoal::SubstitutionGoal(const Path & storePath, Worker & worker, Repa
 {
     this->storePath = storePath;
     state = &SubstitutionGoal::init;
-    name = (format("substitution of ‘%1%’") % storePath).str();
+    name = (format("substitution of '%1%'") % storePath).str();
     trace("created");
     logger->event(evSubstitutionCreated, act, storePath);
 }
@@ -3390,7 +3390,7 @@ void SubstitutionGoal::init()
     }
 
     if (settings.readOnlyMode)
-        throw Error(format("cannot substitute path ‘%1%’ - no write access to the Nix store") % storePath);
+        throw Error(format("cannot substitute path '%1%' - no write access to the Nix store") % storePath);
 
     subs = settings.useSubstitutes ? getDefaultSubstituters() : std::list<ref<Store>>();
 
@@ -3405,7 +3405,7 @@ void SubstitutionGoal::tryNext()
     if (subs.size() == 0) {
         /* None left.  Terminate this goal and let someone else deal
            with it. */
-        debug(format("path ‘%1%’ is required, but there is no substituter that can build it") % storePath);
+        debug(format("path '%1%' is required, but there is no substituter that can build it") % storePath);
 
         /* Hack: don't indicate failure if there were no substituters.
            In that case the calling derivation should just do a
@@ -3436,7 +3436,7 @@ void SubstitutionGoal::tryNext()
        signature. LocalStore::addToStore() also checks for this, but
        only after we've downloaded the path. */
     if (worker.store.requireSigs && !info->checkSignatures(worker.store, worker.store.publicKeys)) {
-        printInfo(format("warning: substituter ‘%s’ does not have a valid signature for path ‘%s’")
+        printInfo(format("warning: substituter '%s' does not have a valid signature for path '%s'")
             % sub->getUri() % storePath);
         tryNext();
         return;
@@ -3460,7 +3460,7 @@ void SubstitutionGoal::referencesValid()
     trace("all references realised");
 
     if (nrFailed > 0) {
-        debug(format("some references of path ‘%1%’ could not be realised") % storePath);
+        debug(format("some references of path '%1%' could not be realised") % storePath);
         amDone(nrNoSubstituters > 0 || nrIncompleteClosure > 0 ? ecIncompleteClosure : ecFailed);
         return;
     }
@@ -3487,7 +3487,7 @@ void SubstitutionGoal::tryToRun()
         return;
     }
 
-    printInfo(format("fetching path ‘%1%’...") % storePath);
+    printInfo(format("fetching path '%1%'...") % storePath);
 
     logger->event(evSubstitutionStarted, act);
 
@@ -3536,7 +3536,7 @@ void SubstitutionGoal::finished()
     worker.markContentsGood(storePath);
 
     printMsg(lvlChatty,
-        format("substitution of path ‘%1%’ succeeded") % storePath);
+        format("substitution of path '%1%' succeeded") % storePath);
 
     amDone(ecSuccess);
 }
@@ -3766,7 +3766,7 @@ void Worker::run(const Goals & _topGoals)
             waitForInput();
         else {
             if (awake.empty() && 0 == settings.maxBuildJobs) throw Error(
-                "unable to start any build; either increase ‘--max-jobs’ "
+                "unable to start any build; either increase '--max-jobs' "
                 "or enable distributed builds");
             assert(!awake.empty());
         }
@@ -3927,7 +3927,7 @@ bool Worker::pathContentsGood(const Path & path)
 {
     std::map<Path, bool>::iterator i = pathContentsGoodCache.find(path);
     if (i != pathContentsGoodCache.end()) return i->second;
-    printInfo(format("checking path ‘%1%’...") % path);
+    printInfo(format("checking path '%1%'...") % path);
     auto info = store.queryPathInfo(path);
     bool res;
     if (!pathExists(path))
@@ -3938,7 +3938,7 @@ bool Worker::pathContentsGood(const Path & path)
         res = info->narHash == nullHash || info->narHash == current.first;
     }
     pathContentsGoodCache[path] = res;
-    if (!res) printError(format("path ‘%1%’ is corrupted or missing!") % path);
+    if (!res) printError(format("path '%1%' is corrupted or missing!") % path);
     return res;
 }
 
@@ -4013,7 +4013,7 @@ void LocalStore::ensurePath(const Path & path)
     worker.run(goals);
 
     if (goal->getExitCode() != Goal::ecSuccess)
-        throw Error(worker.exitStatus(), "path ‘%s’ does not exist and cannot be created", path);
+        throw Error(worker.exitStatus(), "path '%s' does not exist and cannot be created", path);
 }
 
 
@@ -4034,7 +4034,7 @@ void LocalStore::repairPath(const Path & path)
             goals.insert(worker.makeDerivationGoal(deriver, StringSet(), bmRepair));
             worker.run(goals);
         } else
-            throw Error(worker.exitStatus(), "cannot repair path ‘%s’", path);
+            throw Error(worker.exitStatus(), "cannot repair path '%s'", path);
     }
 }
 
diff --git a/src/libstore/builtins.cc b/src/libstore/builtins.cc
index a01dbba4ede4..1075b45c00b5 100644
--- a/src/libstore/builtins.cc
+++ b/src/libstore/builtins.cc
@@ -18,7 +18,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
 
     auto getAttr = [&](const string & name) {
         auto i = drv.env.find(name);
-        if (i == drv.env.end()) throw Error(format("attribute ‘%s’ missing") % name);
+        if (i == drv.env.end()) throw Error(format("attribute '%s' missing") % name);
         return i->second;
     };
 
@@ -65,7 +65,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
     auto executable = drv.env.find("executable");
     if (executable != drv.env.end() && executable->second == "1") {
         if (chmod(storePath.c_str(), 0755) == -1)
-            throw SysError(format("making ‘%1%’ executable") % storePath);
+            throw SysError(format("making '%1%' executable") % storePath);
     }
 }
 
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
index 48c0837ffaaa..a0a0d78b7d30 100644
--- a/src/libstore/derivations.cc
+++ b/src/libstore/derivations.cc
@@ -21,7 +21,7 @@ void DerivationOutput::parseHashInfo(bool & recursive, Hash & hash) const
 
     HashType hashType = parseHashType(algo);
     if (hashType == htUnknown)
-        throw Error(format("unknown hash algorithm ‘%1%’") % algo);
+        throw Error(format("unknown hash algorithm '%1%'") % algo);
 
     hash = Hash(this->hash, hashType);
 }
@@ -31,7 +31,7 @@ Path BasicDerivation::findOutput(const string & id) const
 {
     auto i = outputs.find(id);
     if (i == outputs.end())
-        throw Error(format("derivation has no output ‘%1%’") % id);
+        throw Error(format("derivation has no output '%1%'") % id);
     return i->second.path;
 }
 
@@ -94,7 +94,7 @@ static void expect(std::istream & str, const string & s)
     char s2[s.size()];
     str.read(s2, s.size());
     if (string(s2, s.size()) != s)
-        throw FormatError(format("expected string ‘%1%’") % s);
+        throw FormatError(format("expected string '%1%'") % s);
 }
 
 
@@ -121,7 +121,7 @@ static Path parsePath(std::istream & str)
 {
     string s = parseString(str);
     if (s.size() == 0 || s[0] != '/')
-        throw FormatError(format("bad path ‘%1%’ in derivation") % s);
+        throw FormatError(format("bad path '%1%' in derivation") % s);
     return s;
 }
 
@@ -204,7 +204,7 @@ Derivation readDerivation(const Path & drvPath)
     try {
         return parseDerivation(readFile(drvPath));
     } catch (FormatError & e) {
-        throw Error(format("error parsing derivation ‘%1%’: %2%") % drvPath % e.msg());
+        throw Error(format("error parsing derivation '%1%': %2%") % drvPath % e.msg());
     }
 }
 
@@ -217,7 +217,7 @@ Derivation Store::derivationFromPath(const Path & drvPath)
     try {
         return parseDerivation(accessor->readFile(drvPath));
     } catch (FormatError & e) {
-        throw Error(format("error parsing derivation ‘%1%’: %2%") % drvPath % e.msg());
+        throw Error(format("error parsing derivation '%1%': %2%") % drvPath % e.msg());
     }
 }
 
diff --git a/src/libstore/download.cc b/src/libstore/download.cc
index ac9a2b8fede3..b731297a2086 100644
--- a/src/libstore/download.cc
+++ b/src/libstore/download.cc
@@ -47,7 +47,7 @@ ref<std::string> decodeContent(const std::string & encoding, ref<std::string> da
     else if (encoding == "br")
         return decompress(encoding, *data);
     else
-        throw Error("unsupported Content-Encoding ‘%s’", encoding);
+        throw Error("unsupported Content-Encoding '%s'", encoding);
 }
 
 struct CurlDownloader : public Downloader
@@ -101,7 +101,7 @@ struct CurlDownloader : public Downloader
             if (requestHeaders) curl_slist_free_all(requestHeaders);
             try {
                 if (!done)
-                    fail(DownloadError(Interrupted, format("download of ‘%s’ was interrupted") % request.uri));
+                    fail(DownloadError(Interrupted, format("download of '%s' was interrupted") % request.uri));
             } catch (...) {
                 ignoreException();
             }
@@ -132,7 +132,7 @@ struct CurlDownloader : public Downloader
         {
             size_t realSize = size * nmemb;
             std::string line((char *) contents, realSize);
-            printMsg(lvlVomit, format("got header for ‘%s’: %s") % request.uri % trim(line));
+            printMsg(lvlVomit, format("got header for '%s': %s") % request.uri % trim(line));
             if (line.compare(0, 5, "HTTP/") == 0) { // new response starts
                 result.etag = "";
                 auto ss = tokenizeString<vector<string>>(line, " ");
@@ -250,7 +250,7 @@ struct CurlDownloader : public Downloader
             if (effectiveUrlCStr)
                 result.effectiveUrl = effectiveUrlCStr;
 
-            debug(format("finished download of ‘%s’; curl status = %d, HTTP status = %d, body = %d bytes")
+            debug(format("finished download of '%s'; curl status = %d, HTTP status = %d, body = %d bytes")
                 % request.uri % code % httpStatus % (result.data ? result.data->size() : 0));
 
             if (code == CURLE_WRITE_ERROR && result.etag == request.expectedETag) {
@@ -298,10 +298,10 @@ struct CurlDownloader : public Downloader
 
                 auto exc =
                     code == CURLE_ABORTED_BY_CALLBACK && _isInterrupted
-                    ? DownloadError(Interrupted, format("download of ‘%s’ was interrupted") % request.uri)
+                    ? DownloadError(Interrupted, format("download of '%s' was interrupted") % request.uri)
                     : httpStatus != 0
-                      ? DownloadError(err, format("unable to download ‘%s’: HTTP error %d (curl error: %s)") % request.uri % httpStatus % curl_easy_strerror(code))
-                      : DownloadError(err, format("unable to download ‘%s’: %s (%d)") % request.uri % curl_easy_strerror(code) % code);
+                      ? DownloadError(err, format("unable to download '%s': HTTP error %d (curl error: %s)") % request.uri % httpStatus % curl_easy_strerror(code))
+                      : DownloadError(err, format("unable to download '%s': %s (%d)") % request.uri % curl_easy_strerror(code) % code);
 
                 /* If this is a transient error, then maybe retry the
                    download after a while. */
@@ -512,18 +512,18 @@ struct CurlDownloader : public Downloader
                 S3Helper s3Helper(Aws::Region::US_EAST_1); // FIXME: make configurable
                 auto slash = request.uri.find('/', 5);
                 if (slash == std::string::npos)
-                    throw nix::Error("bad S3 URI ‘%s’", request.uri);
+                    throw nix::Error("bad S3 URI '%s'", request.uri);
                 std::string bucketName(request.uri, 5, slash - 5);
                 std::string key(request.uri, slash + 1);
                 // FIXME: implement ETag
                 auto s3Res = s3Helper.getObject(bucketName, key);
                 DownloadResult res;
                 if (!s3Res.data)
-                    throw DownloadError(NotFound, fmt("S3 object ‘%s’ does not exist", request.uri));
+                    throw DownloadError(NotFound, fmt("S3 object '%s' does not exist", request.uri));
                 res.data = s3Res.data;
                 return res;
 #else
-                throw nix::Error("cannot download ‘%s’ because Nix is not built with S3 support", request.uri);
+                throw nix::Error("cannot download '%s' because Nix is not built with S3 support", request.uri);
 #endif
             });
             return;
@@ -587,7 +587,7 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
     Path dataFile = cacheDir + "/" + urlHash + ".info";
     Path fileLink = cacheDir + "/" + urlHash + "-file";
 
-    PathLocks lock({fileLink}, fmt("waiting for lock on ‘%1%’...", fileLink));
+    PathLocks lock({fileLink}, fmt("waiting for lock on '%1%'...", fileLink));
 
     Path storePath;
 
@@ -608,7 +608,7 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
                     if (effectiveUrl)
                         *effectiveUrl = url_;
                 } else if (!ss[1].empty()) {
-                    debug(format("verifying previous ETag ‘%1%’") % ss[1]);
+                    debug(format("verifying previous ETag '%1%'") % ss[1]);
                     expectedETag = ss[1];
                 }
             }
@@ -650,7 +650,7 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
 
     if (unpack) {
         Path unpackedLink = cacheDir + "/" + baseNameOf(storePath) + "-unpacked";
-        PathLocks lock2({unpackedLink}, fmt("waiting for lock on ‘%1%’...", unpackedLink));
+        PathLocks lock2({unpackedLink}, fmt("waiting for lock on '%1%'...", unpackedLink));
         Path unpackedStorePath;
         if (pathExists(unpackedLink)) {
             unpackedStorePath = readLink(unpackedLink);
@@ -659,7 +659,7 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
                 unpackedStorePath = "";
         }
         if (unpackedStorePath.empty()) {
-            printInfo(format("unpacking ‘%1%’...") % url);
+            printInfo(format("unpacking '%1%'...") % url);
             Path tmpDir = createTempDir();
             AutoDelete autoDelete(tmpDir, true);
             // FIXME: this requires GNU tar for decompression.
@@ -671,7 +671,7 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
     }
 
     if (expectedStorePath != "" && storePath != expectedStorePath)
-        throw nix::Error("store path mismatch in file downloaded from ‘%s’", url);
+        throw nix::Error("store path mismatch in file downloaded from '%s'", url);
 
     return storePath;
 }
diff --git a/src/libstore/export-import.cc b/src/libstore/export-import.cc
index 2cbcedc6fb00..ef3fea7c838b 100644
--- a/src/libstore/export-import.cc
+++ b/src/libstore/export-import.cc
@@ -33,7 +33,7 @@ void Store::exportPaths(const Paths & paths, Sink & sink)
     //logger->incExpected(doneLabel, sorted.size());
 
     for (auto & path : sorted) {
-        //Activity act(*logger, lvlInfo, format("exporting path ‘%s’") % path);
+        //Activity act(*logger, lvlInfo, format("exporting path '%s'") % path);
         sink << 1;
         exportPath(path, sink);
         //logger->incProgress(doneLabel);
@@ -55,7 +55,7 @@ void Store::exportPath(const Path & path, Sink & sink)
        Don't complain if the stored hash is zero (unknown). */
     Hash hash = hashAndWriteSink.currentHash();
     if (hash != info->narHash && info->narHash != Hash(info->narHash.type))
-        throw Error(format("hash of path ‘%1%’ has changed from ‘%2%’ to ‘%3%’!") % path
+        throw Error(format("hash of path '%1%' has changed from '%2%' to '%3%'!") % path
             % info->narHash.to_string() % hash.to_string());
 
     hashAndWriteSink << exportMagic << path << info->references << info->deriver << 0;
@@ -67,7 +67,7 @@ Paths Store::importPaths(Source & source, std::shared_ptr<FSAccessor> accessor,
     while (true) {
         auto n = readNum<uint64_t>(source);
         if (n == 0) break;
-        if (n != 1) throw Error("input doesn't look like something created by ‘nix-store --export’");
+        if (n != 1) throw Error("input doesn't look like something created by 'nix-store --export'");
 
         /* Extract the NAR from the source. */
         TeeSink tee(source);
@@ -81,7 +81,7 @@ Paths Store::importPaths(Source & source, std::shared_ptr<FSAccessor> accessor,
 
         info.path = readStorePath(*this, source);
 
-        //Activity act(*logger, lvlInfo, format("importing path ‘%s’") % info.path);
+        //Activity act(*logger, lvlInfo, format("importing path '%s'") % info.path);
 
         info.references = readStorePaths<PathSet>(*this, source);
 
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 0cf9f87cac32..bd335fbb49e3 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -32,11 +32,11 @@ int LocalStore::openGCLock(LockType lockType)
     Path fnGCLock = (format("%1%/%2%")
         % stateDir % gcLockName).str();
 
-    debug(format("acquiring global GC lock ‘%1%’") % fnGCLock);
+    debug(format("acquiring global GC lock '%1%'") % fnGCLock);
 
     AutoCloseFD fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
     if (!fdGCLock)
-        throw SysError(format("opening global GC lock ‘%1%’") % fnGCLock);
+        throw SysError(format("opening global GC lock '%1%'") % fnGCLock);
 
     if (!lockFile(fdGCLock.get(), lockType, false)) {
         printError(format("waiting for the big garbage collector lock..."));
@@ -63,7 +63,7 @@ static void makeSymlink(const Path & link, const Path & target)
 
     /* Atomically replace the old one. */
     if (rename(tempLink.c_str(), link.c_str()) == -1)
-        throw SysError(format("cannot rename ‘%1%’ to ‘%2%’")
+        throw SysError(format("cannot rename '%1%' to '%2%'")
             % tempLink % link);
 }
 
@@ -99,7 +99,7 @@ Path LocalFSStore::addPermRoot(const Path & _storePath,
         /* Don't clobber the link if it already exists and doesn't
            point to the Nix store. */
         if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot))))
-            throw Error(format("cannot create symlink ‘%1%’; already exists") % gcRoot);
+            throw Error(format("cannot create symlink '%1%'; already exists") % gcRoot);
         makeSymlink(gcRoot, storePath);
         addIndirectRoot(gcRoot);
     }
@@ -110,8 +110,8 @@ Path LocalFSStore::addPermRoot(const Path & _storePath,
 
             if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
                 throw Error(format(
-                    "path ‘%1%’ is not a valid garbage collector root; "
-                    "it's not in the directory ‘%2%’")
+                    "path '%1%' is not a valid garbage collector root; "
+                    "it's not in the directory '%2%'")
                     % gcRoot % rootsDir);
         }
 
@@ -131,8 +131,8 @@ Path LocalFSStore::addPermRoot(const Path & _storePath,
         if (roots.find(gcRoot) == roots.end())
             printError(
                 format(
-                    "warning: ‘%1%’ is not in a directory where the garbage collector looks for roots; "
-                    "therefore, ‘%2%’ might be removed by the garbage collector")
+                    "warning: '%1%' is not in a directory where the garbage collector looks for roots; "
+                    "therefore, '%2%' might be removed by the garbage collector")
                 % gcRoot % storePath);
     }
 
@@ -169,14 +169,14 @@ void LocalStore::addTempRoot(const Path & path)
 
             fdGCLock = -1;
 
-            debug(format("acquiring read lock on ‘%1%’") % state->fnTempRoots);
+            debug(format("acquiring read lock on '%1%'") % state->fnTempRoots);
             lockFile(state->fdTempRoots.get(), ltRead, true);
 
             /* Check whether the garbage collector didn't get in our
                way. */
             struct stat st;
             if (fstat(state->fdTempRoots.get(), &st) == -1)
-                throw SysError(format("statting ‘%1%’") % state->fnTempRoots);
+                throw SysError(format("statting '%1%'") % state->fnTempRoots);
             if (st.st_size == 0) break;
 
             /* The garbage collector deleted this file before we could
@@ -188,14 +188,14 @@ void LocalStore::addTempRoot(const Path & path)
 
     /* Upgrade the lock to a write lock.  This will cause us to block
        if the garbage collector is holding our lock. */
-    debug(format("acquiring write lock on ‘%1%’") % state->fnTempRoots);
+    debug(format("acquiring write lock on '%1%'") % state->fnTempRoots);
     lockFile(state->fdTempRoots.get(), ltWrite, true);
 
     string s = path + '\0';
     writeFull(state->fdTempRoots.get(), s);
 
     /* Downgrade to a read lock. */
-    debug(format("downgrading to read lock on ‘%1%’") % state->fnTempRoots);
+    debug(format("downgrading to read lock on '%1%'") % state->fnTempRoots);
     lockFile(state->fdTempRoots.get(), ltRead, true);
 }
 
@@ -210,12 +210,12 @@ void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
     for (auto & i : tempRootFiles) {
         Path path = (format("%1%/%2%/%3%") % stateDir % tempRootsDir % i.name).str();
 
-        debug(format("reading temporary root file ‘%1%’") % path);
+        debug(format("reading temporary root file '%1%'") % path);
         FDPtr fd(new AutoCloseFD(open(path.c_str(), O_CLOEXEC | O_RDWR, 0666)));
         if (!*fd) {
             /* It's okay if the file has disappeared. */
             if (errno == ENOENT) continue;
-            throw SysError(format("opening temporary roots file ‘%1%’") % path);
+            throw SysError(format("opening temporary roots file '%1%'") % path);
         }
 
         /* This should work, but doesn't, for some reason. */
@@ -226,7 +226,7 @@ void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
            only succeed if the owning process has died.  In that case
            we don't care about its temporary roots. */
         if (lockFile(fd->get(), ltWrite, false)) {
-            printError(format("removing stale temporary roots file ‘%1%’") % path);
+            printError(format("removing stale temporary roots file '%1%'") % path);
             unlink(path.c_str());
             writeFull(fd->get(), "d");
             continue;
@@ -235,7 +235,7 @@ void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
         /* Acquire a read lock.  This will prevent the owning process
            from upgrading to a write lock, therefore it will block in
            addTempRoot(). */
-        debug(format("waiting for read lock on ‘%1%’") % path);
+        debug(format("waiting for read lock on '%1%'") % path);
         lockFile(fd->get(), ltRead, true);
 
         /* Read the entire file. */
@@ -246,7 +246,7 @@ void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
 
         while ((end = contents.find((char) 0, pos)) != string::npos) {
             Path root(contents, pos, end - pos);
-            debug(format("got temporary root ‘%1%’") % root);
+            debug(format("got temporary root '%1%'") % root);
             assertStorePath(root);
             tempRoots.insert(root);
             pos = end + 1;
@@ -264,7 +264,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
         if (isStorePath(storePath) && isValidPath(storePath))
             roots[path] = storePath;
         else
-            printInfo(format("skipping invalid root from ‘%1%’ to ‘%2%’") % path % storePath);
+            printInfo(format("skipping invalid root from '%1%' to '%2%'") % path % storePath);
     };
 
     try {
@@ -287,7 +287,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
                 target = absPath(target, dirOf(path));
                 if (!pathExists(target)) {
                     if (isInDir(path, stateDir + "/" + gcRootsDir + "/auto")) {
-                        printInfo(format("removing stale link from ‘%1%’ to ‘%2%’") % path % target);
+                        printInfo(format("removing stale link from '%1%' to '%2%'") % path % target);
                         unlink(path.c_str());
                     }
                 } else {
@@ -310,7 +310,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
     catch (SysError & e) {
         /* We only ignore permanent failures. */
         if (e.errNo == EACCES || e.errNo == ENOENT || e.errNo == ENOTDIR)
-            printInfo(format("cannot read potential root ‘%1%’") % path);
+            printInfo(format("cannot read potential root '%1%'") % path);
         else
             throw;
     }
@@ -451,7 +451,7 @@ void LocalStore::findRuntimeRoots(PathSet & roots)
         if (isInStore(i)) {
             Path path = toStorePath(i);
             if (roots.find(path) == roots.end() && isStorePath(path) && isValidPath(path)) {
-                debug(format("got additional root ‘%1%’") % path);
+                debug(format("got additional root '%1%'") % path);
                 roots.insert(path);
             }
         }
@@ -517,7 +517,7 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
         throw SysError(format("getting status of %1%") % realPath);
     }
 
-    printInfo(format("deleting ‘%1%’") % path);
+    printInfo(format("deleting '%1%'") % path);
 
     state.results.paths.insert(path);
 
@@ -532,14 +532,14 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
         // size.
         try {
             if (chmod(realPath.c_str(), st.st_mode | S_IWUSR) == -1)
-                throw SysError(format("making ‘%1%’ writable") % realPath);
+                throw SysError(format("making '%1%' writable") % realPath);
             Path tmp = trashDir + "/" + baseNameOf(path);
             if (rename(realPath.c_str(), tmp.c_str()))
-                throw SysError(format("unable to rename ‘%1%’ to ‘%2%’") % realPath % tmp);
+                throw SysError(format("unable to rename '%1%' to '%2%'") % realPath % tmp);
             state.bytesInvalidated += size;
         } catch (SysError & e) {
             if (e.errNo == ENOSPC) {
-                printInfo(format("note: can't create move ‘%1%’: %2%") % realPath % e.msg());
+                printInfo(format("note: can't create move '%1%': %2%") % realPath % e.msg());
                 deleteGarbage(state, realPath);
             }
         }
@@ -566,7 +566,7 @@ bool LocalStore::canReachRoot(GCState & state, PathSet & visited, const Path & p
     }
 
     if (state.roots.find(path) != state.roots.end()) {
-        debug(format("cannot delete ‘%1%’ because it's a root") % path);
+        debug(format("cannot delete '%1%' because it's a root") % path);
         state.alive.insert(path);
         return true;
     }
@@ -615,7 +615,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
     auto realPath = realStoreDir + "/" + baseNameOf(path);
     if (realPath == linksDir || realPath == trashDir) return;
 
-    //Activity act(*logger, lvlDebug, format("considering whether to delete ‘%1%’") % path);
+    //Activity act(*logger, lvlDebug, format("considering whether to delete '%1%'") % path);
 
     if (!isStorePath(path) || !isValidPath(path)) {
         /* A lock file belonging to a path that we're building right
@@ -635,7 +635,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
     PathSet visited;
 
     if (canReachRoot(state, visited, path)) {
-        debug(format("cannot delete ‘%1%’ because it's still reachable") % path);
+        debug(format("cannot delete '%1%' because it's still reachable") % path);
     } else {
         /* No path we visited was a root, so everything is garbage.
            But we only delete ‘path’ and its referrers here so that
@@ -656,7 +656,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
 void LocalStore::removeUnusedLinks(const GCState & state)
 {
     AutoCloseDir dir(opendir(linksDir.c_str()));
-    if (!dir) throw SysError(format("opening directory ‘%1%’") % linksDir);
+    if (!dir) throw SysError(format("opening directory '%1%'") % linksDir);
 
     long long actualSize = 0, unsharedSize = 0;
 
@@ -669,7 +669,7 @@ void LocalStore::removeUnusedLinks(const GCState & state)
 
         struct stat st;
         if (lstat(path.c_str(), &st) == -1)
-            throw SysError(format("statting ‘%1%’") % path);
+            throw SysError(format("statting '%1%'") % path);
 
         if (st.st_nlink != 1) {
             unsigned long long size = st.st_blocks * 512ULL;
@@ -678,17 +678,17 @@ void LocalStore::removeUnusedLinks(const GCState & state)
             continue;
         }
 
-        printMsg(lvlTalkative, format("deleting unused link ‘%1%’") % path);
+        printMsg(lvlTalkative, format("deleting unused link '%1%'") % path);
 
         if (unlink(path.c_str()) == -1)
-            throw SysError(format("deleting ‘%1%’") % path);
+            throw SysError(format("deleting '%1%'") % path);
 
         state.results.bytesFreed += st.st_blocks * 512ULL;
     }
 
     struct stat st;
     if (stat(linksDir.c_str(), &st) == -1)
-        throw SysError(format("statting ‘%1%’") % linksDir);
+        throw SysError(format("statting '%1%'") % linksDir);
     long long overhead = st.st_blocks * 512ULL;
 
     printInfo(format("note: currently hard linking saves %.2f MiB")
@@ -768,7 +768,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
             assertStorePath(i);
             tryToDelete(state, i);
             if (state.dead.find(i) == state.dead.end())
-                throw Error(format("cannot delete path ‘%1%’ since it is still alive") % i);
+                throw Error(format("cannot delete path '%1%' since it is still alive") % i);
         }
 
     } else if (options.maxFreed > 0) {
@@ -781,7 +781,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
         try {
 
             AutoCloseDir dir(opendir(realStoreDir.c_str()));
-            if (!dir) throw SysError(format("opening directory ‘%1%’") % realStoreDir);
+            if (!dir) throw SysError(format("opening directory '%1%'") % realStoreDir);
 
             /* Read the store and immediately delete all paths that
                aren't valid.  When using --max-freed etc., deleting
@@ -834,7 +834,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
     fds.clear();
 
     /* Delete the trash directory. */
-    printInfo(format("deleting ‘%1%’") % trashDir);
+    printInfo(format("deleting '%1%'") % trashDir);
     deleteGarbage(state, trashDir);
 
     /* Clean up the links directory. */
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 935018132d31..7da4bce87753 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -129,7 +129,7 @@ void MaxBuildJobsSetting::set(const std::string & str)
 {
     if (str == "auto") value = std::max(1U, std::thread::hardware_concurrency());
     else if (!string2Int(str, value))
-        throw UsageError("configuration setting ‘%s’ should be ‘auto’ or an integer", name);
+        throw UsageError("configuration setting '%s' should be 'auto' or an integer", name);
 }
 
 }
diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc
index cead81514ab4..057337685791 100644
--- a/src/libstore/http-binary-cache-store.cc
+++ b/src/libstore/http-binary-cache-store.cc
@@ -38,7 +38,7 @@ public:
             try {
                 BinaryCacheStore::init();
             } catch (UploadToHTTP &) {
-                throw Error(format("‘%s’ does not appear to be a binary cache") % cacheUri);
+                throw Error(format("'%s' does not appear to be a binary cache") % cacheUri);
             }
             diskCache->createCache(cacheUri, storeDir, wantMassQuery_, priority);
         }
diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc
index a84f85c1b95a..65fe575d2536 100644
--- a/src/libstore/legacy-ssh-store.cc
+++ b/src/libstore/legacy-ssh-store.cc
@@ -65,13 +65,13 @@ struct LegacySSHStore : public Store
 
             unsigned int magic = readInt(conn->from);
             if (magic != SERVE_MAGIC_2)
-                throw Error("protocol mismatch with ‘nix-store --serve’ on ‘%s’", host);
+                throw Error("protocol mismatch with 'nix-store --serve' on '%s'", host);
             conn->remoteVersion = readInt(conn->from);
             if (GET_PROTOCOL_MAJOR(conn->remoteVersion) != 0x200)
-                throw Error("unsupported ‘nix-store --serve’ protocol version on ‘%s’", host);
+                throw Error("unsupported 'nix-store --serve' protocol version on '%s'", host);
 
         } catch (EndOfFile & e) {
-            throw Error("cannot connect to ‘%1%’", host);
+            throw Error("cannot connect to '%1%'", host);
         }
 
         return conn;
@@ -89,7 +89,7 @@ struct LegacySSHStore : public Store
         sync2async<std::shared_ptr<ValidPathInfo>>(success, failure, [&]() -> std::shared_ptr<ValidPathInfo> {
             auto conn(connections->get());
 
-            debug("querying remote host ‘%s’ for info on ‘%s’", host, path);
+            debug("querying remote host '%s' for info on '%s'", host, path);
 
             conn->to << cmdQueryPathInfos << PathSet{path};
             conn->to.flush();
@@ -116,7 +116,7 @@ struct LegacySSHStore : public Store
         RepairFlag repair, CheckSigsFlag checkSigs,
         std::shared_ptr<FSAccessor> accessor) override
     {
-        debug("adding path ‘%s’ to remote host ‘%s’", info.path, host);
+        debug("adding path '%s' to remote host '%s'", info.path, host);
 
         auto conn(connections->get());
 
@@ -134,7 +134,7 @@ struct LegacySSHStore : public Store
         conn->to.flush();
 
         if (readInt(conn->from) != 1)
-            throw Error("failed to add path ‘%s’ to remote host ‘%s’, info.path, host");
+            throw Error("failed to add path '%s' to remote host '%s', info.path, host");
 
     }
 
diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc
index aff22f9fcc22..2577e90aef23 100644
--- a/src/libstore/local-binary-cache-store.cc
+++ b/src/libstore/local-binary-cache-store.cc
@@ -76,7 +76,7 @@ static void atomicWrite(const Path & path, const std::string & s)
     AutoDelete del(tmp, false);
     writeFile(tmp, s);
     if (rename(tmp.c_str(), path.c_str()))
-        throw SysError(format("renaming ‘%1%’ to ‘%2%’") % tmp % path);
+        throw SysError(format("renaming '%1%' to '%2%'") % tmp % path);
     del.cancel();
 }
 
diff --git a/src/libstore/local-fs-store.cc b/src/libstore/local-fs-store.cc
index bf28a1c70c62..642e4070d459 100644
--- a/src/libstore/local-fs-store.cc
+++ b/src/libstore/local-fs-store.cc
@@ -22,7 +22,7 @@ struct LocalStoreAccessor : public FSAccessor
     {
         Path storePath = store->toStorePath(path);
         if (!store->isValidPath(storePath))
-            throw InvalidPath(format("path ‘%1%’ is not a valid store path") % storePath);
+            throw InvalidPath(format("path '%1%' is not a valid store path") % storePath);
         return store->getRealStoreDir() + std::string(path, store->storeDir.size());
     }
 
@@ -33,11 +33,11 @@ struct LocalStoreAccessor : public FSAccessor
         struct stat st;
         if (lstat(realPath.c_str(), &st)) {
             if (errno == ENOENT || errno == ENOTDIR) return {Type::tMissing, 0, false};
-            throw SysError(format("getting status of ‘%1%’") % path);
+            throw SysError(format("getting status of '%1%'") % path);
         }
 
         if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode))
-            throw Error(format("file ‘%1%’ has unsupported type") % path);
+            throw Error(format("file '%1%' has unsupported type") % path);
 
         return {
             S_ISREG(st.st_mode) ? Type::tRegular :
@@ -80,7 +80,7 @@ ref<FSAccessor> LocalFSStore::getFSAccessor()
 void LocalFSStore::narFromPath(const Path & path, Sink & sink)
 {
     if (!isValidPath(path))
-        throw Error(format("path ‘%s’ is not valid") % path);
+        throw Error(format("path '%s' is not valid") % path);
     dumpPath(getRealStoreDir() + std::string(path, storeDir.size()), sink);
 }
 
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 7c41dfca7f31..95b05f8afd31 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -76,24 +76,24 @@ LocalStore::LocalStore(const Params & params)
         Path perUserDir = profilesDir + "/per-user";
         createDirs(perUserDir);
         if (chmod(perUserDir.c_str(), 01777) == -1)
-            throw SysError(format("could not set permissions on ‘%1%’ to 1777") % perUserDir);
+            throw SysError(format("could not set permissions on '%1%' to 1777") % perUserDir);
 
         mode_t perm = 01775;
 
         struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
         if (!gr)
-            printError(format("warning: the group ‘%1%’ specified in ‘build-users-group’ does not exist")
+            printError(format("warning: the group '%1%' specified in 'build-users-group' does not exist")
                 % settings.buildUsersGroup);
         else {
             struct stat st;
             if (stat(realStoreDir.c_str(), &st))
-                throw SysError(format("getting attributes of path ‘%1%’") % realStoreDir);
+                throw SysError(format("getting attributes of path '%1%'") % realStoreDir);
 
             if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
                 if (chown(realStoreDir.c_str(), 0, gr->gr_gid) == -1)
-                    throw SysError(format("changing ownership of path ‘%1%’") % realStoreDir);
+                    throw SysError(format("changing ownership of path '%1%'") % realStoreDir);
                 if (chmod(realStoreDir.c_str(), perm) == -1)
-                    throw SysError(format("changing permissions on path ‘%1%’") % realStoreDir);
+                    throw SysError(format("changing permissions on path '%1%'") % realStoreDir);
             }
         }
     }
@@ -104,10 +104,10 @@ LocalStore::LocalStore(const Params & params)
         struct stat st;
         while (path != "/") {
             if (lstat(path.c_str(), &st))
-                throw SysError(format("getting status of ‘%1%’") % path);
+                throw SysError(format("getting status of '%1%'") % path);
             if (S_ISLNK(st.st_mode))
                 throw Error(format(
-                        "the path ‘%1%’ is a symlink; "
+                        "the path '%1%' is a symlink; "
                         "this is not allowed for the Nix store and its parent directories")
                     % path);
             path = dirOf(path);
@@ -267,7 +267,7 @@ int LocalStore::getSchema()
     if (pathExists(schemaPath)) {
         string s = readFile(schemaPath);
         if (!string2Int(s, curSchema))
-            throw Error(format("‘%1%’ is corrupt") % schemaPath);
+            throw Error(format("'%1%' is corrupt") % schemaPath);
     }
     return curSchema;
 }
@@ -276,14 +276,14 @@ int LocalStore::getSchema()
 void LocalStore::openDB(State & state, bool create)
 {
     if (access(dbDir.c_str(), R_OK | W_OK))
-        throw SysError(format("Nix database directory ‘%1%’ is not writable") % dbDir);
+        throw SysError(format("Nix database directory '%1%' is not writable") % dbDir);
 
     /* Open the Nix database. */
     string dbPath = dbDir + "/db.sqlite";
     auto & db(state.db);
     if (sqlite3_open_v2(dbPath.c_str(), &db.db,
             SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
-        throw Error(format("cannot open Nix database ‘%1%’") % dbPath);
+        throw Error(format("cannot open Nix database '%1%'") % dbPath);
 
 #ifdef __CYGWIN__
     /* The cygwin version of sqlite3 has a patch which calls
@@ -378,7 +378,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
                  | 0444
                  | (st.st_mode & S_IXUSR ? 0111 : 0);
             if (chmod(path.c_str(), mode) == -1)
-                throw SysError(format("changing mode of ‘%1%’ to %2$o") % path % mode);
+                throw SysError(format("changing mode of '%1%' to %2$o") % path % mode);
         }
 
     }
@@ -396,7 +396,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
 #else
         if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1)
 #endif
-            throw SysError(format("changing modification time of ‘%1%’") % path);
+            throw SysError(format("changing modification time of '%1%'") % path);
     }
 }
 
@@ -405,7 +405,7 @@ void canonicaliseTimestampAndPermissions(const Path & path)
 {
     struct stat st;
     if (lstat(path.c_str(), &st))
-        throw SysError(format("getting attributes of path ‘%1%’") % path);
+        throw SysError(format("getting attributes of path '%1%'") % path);
     canonicaliseTimestampAndPermissions(path, st);
 }
 
@@ -420,17 +420,17 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
        setattrlist() to remove other attributes as well. */
     if (lchflags(path.c_str(), 0)) {
         if (errno != ENOTSUP)
-            throw SysError(format("clearing flags of path ‘%1%’") % path);
+            throw SysError(format("clearing flags of path '%1%'") % path);
     }
 #endif
 
     struct stat st;
     if (lstat(path.c_str(), &st))
-        throw SysError(format("getting attributes of path ‘%1%’") % path);
+        throw SysError(format("getting attributes of path '%1%'") % path);
 
     /* Really make sure that the path is of a supported type. */
     if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)))
-        throw Error(format("file ‘%1%’ has an unsupported type") % path);
+        throw Error(format("file '%1%' has an unsupported type") % path);
 
 #if __linux__
     /* Remove extended attributes / ACLs. */
@@ -438,19 +438,19 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
 
     if (eaSize < 0) {
         if (errno != ENOTSUP)
-            throw SysError("querying extended attributes of ‘%s’", path);
+            throw SysError("querying extended attributes of '%s'", path);
     } else if (eaSize > 0) {
         std::vector<char> eaBuf(eaSize);
 
         if ((eaSize = llistxattr(path.c_str(), eaBuf.data(), eaBuf.size())) < 0)
-            throw SysError("querying extended attributes of ‘%s’", path);
+            throw SysError("querying extended attributes of '%s'", path);
 
         for (auto & eaName: tokenizeString<Strings>(std::string(eaBuf.data(), eaSize), std::string("\000", 1))) {
             /* Ignore SELinux security labels since these cannot be
                removed even by root. */
             if (eaName == "security.selinux") continue;
             if (lremovexattr(path.c_str(), eaName.c_str()) == -1)
-                throw SysError("removing extended attribute ‘%s’ from ‘%s’", eaName, path);
+                throw SysError("removing extended attribute '%s' from '%s'", eaName, path);
         }
      }
 #endif
@@ -464,7 +464,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
     if (fromUid != (uid_t) -1 && st.st_uid != fromUid) {
         assert(!S_ISDIR(st.st_mode));
         if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end())
-            throw BuildError(format("invalid ownership on file ‘%1%’") % path);
+            throw BuildError(format("invalid ownership on file '%1%'") % path);
         mode_t mode = st.st_mode & ~S_IFMT;
         assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore));
         return;
@@ -488,7 +488,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
         if (!S_ISLNK(st.st_mode) &&
             chown(path.c_str(), geteuid(), getegid()) == -1)
 #endif
-            throw SysError(format("changing owner of ‘%1%’ to %2%")
+            throw SysError(format("changing owner of '%1%' to %2%")
                 % path % geteuid());
     }
 
@@ -508,11 +508,11 @@ void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & ino
        be a symlink, since we can't change its ownership. */
     struct stat st;
     if (lstat(path.c_str(), &st))
-        throw SysError(format("getting attributes of path ‘%1%’") % path);
+        throw SysError(format("getting attributes of path '%1%'") % path);
 
     if (st.st_uid != geteuid()) {
         assert(S_ISLNK(st.st_mode));
-        throw Error(format("wrong ownership of top-level store path ‘%1%’") % path);
+        throw Error(format("wrong ownership of top-level store path '%1%'") % path);
     }
 }
 
@@ -533,7 +533,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
     if (drv.isFixedOutput()) {
         DerivationOutputs::const_iterator out = drv.outputs.find("out");
         if (out == drv.outputs.end())
-            throw Error(format("derivation ‘%1%’ does not have an output named ‘out’") % drvPath);
+            throw Error(format("derivation '%1%' does not have an output named 'out'") % drvPath);
 
         bool recursive; Hash h;
         out->second.parseHashInfo(recursive, h);
@@ -541,7 +541,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
 
         StringPairs::const_iterator j = drv.env.find("out");
         if (out->second.path != outPath || j == drv.env.end() || j->second != outPath)
-            throw Error(format("derivation ‘%1%’ has incorrect output ‘%2%’, should be ‘%3%’")
+            throw Error(format("derivation '%1%' has incorrect output '%2%', should be '%3%'")
                 % drvPath % out->second.path % outPath);
     }
 
@@ -558,7 +558,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
             Path outPath = makeOutputPath(i.first, h, drvName);
             StringPairs::const_iterator j = drv.env.find(i.first);
             if (i.second.path != outPath || j == drv.env.end() || j->second != outPath)
-                throw Error(format("derivation ‘%1%’ has incorrect output ‘%2%’, should be ‘%3%’")
+                throw Error(format("derivation '%1%' has incorrect output '%2%', should be '%3%'")
                     % drvPath % i.second.path % outPath);
         }
     }
@@ -639,7 +639,7 @@ void LocalStore::queryPathInfoUncached(const Path & path,
             try {
                 info->narHash = Hash(useQueryPathInfo.getStr(1));
             } catch (BadHash & e) {
-                throw Error("in valid-path entry for ‘%s’: %s", path, e.what());
+                throw Error("in valid-path entry for '%s': %s", path, e.what());
             }
 
             info->registrationTime = useQueryPathInfo.getInt(2);
@@ -688,7 +688,7 @@ uint64_t LocalStore::queryValidPathId(State & state, const Path & path)
 {
     auto use(state.stmtQueryPathInfo.use()(path));
     if (!use.next())
-        throw Error(format("path ‘%1%’ is not valid") % path);
+        throw Error(format("path '%1%' is not valid") % path);
     return use.getInt(0);
 }
 
@@ -855,7 +855,7 @@ void LocalStore::querySubstitutablePathInfos(const PathSet & paths,
         if (sub->storeDir != storeDir) continue;
         for (auto & path : paths) {
             if (infos.count(path)) continue;
-            debug(format("checking substituter ‘%s’ for path ‘%s’")
+            debug(format("checking substituter '%s' for path '%s'")
                 % sub->getUri() % path);
             try {
                 auto info = sub->queryPathInfo(path);
@@ -936,7 +936,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
    there are no referrers. */
 void LocalStore::invalidatePath(State & state, const Path & path)
 {
-    debug(format("invalidating path ‘%1%’") % path);
+    debug(format("invalidating path '%1%'") % path);
 
     state.stmtInvalidatePath.use()(path).exec();
 
@@ -957,15 +957,15 @@ void LocalStore::addToStore(const ValidPathInfo & info, const ref<std::string> &
 
     Hash h = hashString(htSHA256, *nar);
     if (h != info.narHash)
-        throw Error("hash mismatch importing path ‘%s’; expected hash ‘%s’, got ‘%s’",
+        throw Error("hash mismatch importing path '%s'; expected hash '%s', got '%s'",
             info.path, info.narHash.to_string(), h.to_string());
 
     if (nar->size() != info.narSize)
-        throw Error("size mismatch importing path ‘%s’; expected %s, got %s",
+        throw Error("size mismatch importing path '%s'; expected %s, got %s",
             info.path, info.narSize, nar->size());
 
     if (requireSigs && checkSigs && !info.checkSignatures(*this, publicKeys))
-        throw Error("cannot add path ‘%s’ because it lacks a valid signature", info.path);
+        throw Error("cannot add path '%s' because it lacks a valid signature", info.path);
 
     addTempRoot(info.path);
 
@@ -1150,7 +1150,7 @@ void LocalStore::invalidatePathChecked(const Path & path)
             PathSet referrers; queryReferrers(*state, path, referrers);
             referrers.erase(path); /* ignore self-references */
             if (!referrers.empty())
-                throw PathInUse(format("cannot delete path ‘%1%’ because it is in use by %2%")
+                throw PathInUse(format("cannot delete path '%1%' because it is in use by %2%")
                     % path % showPaths(referrers));
             invalidatePath(*state, path);
         }
@@ -1195,12 +1195,12 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
                 auto info = std::const_pointer_cast<ValidPathInfo>(std::shared_ptr<const ValidPathInfo>(queryPathInfo(i)));
 
                 /* Check the content hash (optionally - slow). */
-                printMsg(lvlTalkative, format("checking contents of ‘%1%’") % i);
+                printMsg(lvlTalkative, format("checking contents of '%1%'") % i);
                 HashResult current = hashPath(info->narHash.type, i);
 
                 if (info->narHash != nullHash && info->narHash != current.first) {
-                    printError(format("path ‘%1%’ was modified! "
-                            "expected hash ‘%2%’, got ‘%3%’")
+                    printError(format("path '%1%' was modified! "
+                            "expected hash '%2%', got '%3%'")
                         % i % info->narHash.to_string() % current.first.to_string());
                     if (repair) repairPath(i); else errors = true;
                 } else {
@@ -1209,14 +1209,14 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
 
                     /* Fill in missing hashes. */
                     if (info->narHash == nullHash) {
-                        printError(format("fixing missing hash on ‘%1%’") % i);
+                        printError(format("fixing missing hash on '%1%'") % i);
                         info->narHash = current.first;
                         update = true;
                     }
 
                     /* Fill in missing narSize fields (from old stores). */
                     if (info->narSize == 0) {
-                        printError(format("updating size field on ‘%1%’ to %2%") % i % current.second);
+                        printError(format("updating size field on '%1%' to %2%") % i % current.second);
                         info->narSize = current.second;
                         update = true;
                     }
@@ -1253,7 +1253,7 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
     done.insert(path);
 
     if (!isStorePath(path)) {
-        printError(format("path ‘%1%’ is not in the Nix store") % path);
+        printError(format("path '%1%' is not in the Nix store") % path);
         auto state(_state.lock());
         invalidatePath(*state, path);
         return;
@@ -1272,11 +1272,11 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
             }
 
         if (canInvalidate) {
-            printError(format("path ‘%1%’ disappeared, removing from database...") % path);
+            printError(format("path '%1%' disappeared, removing from database...") % path);
             auto state(_state.lock());
             invalidatePath(*state, path);
         } else {
-            printError(format("path ‘%1%’ disappeared, but it still has valid referrers!") % path);
+            printError(format("path '%1%' disappeared, but it still has valid referrers!") % path);
             if (repair)
                 try {
                     repairPath(path);
@@ -1315,7 +1315,7 @@ static void makeMutable(const Path & path)
     AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
     if (fd == -1) {
         if (errno == ELOOP) return; // it's a symlink
-        throw SysError(format("opening file ‘%1%’") % path);
+        throw SysError(format("opening file '%1%'") % path);
     }
 
     unsigned int flags = 0, old;
diff --git a/src/libstore/machines.cc b/src/libstore/machines.cc
index 7491037b2d79..076c3cab3e90 100644
--- a/src/libstore/machines.cc
+++ b/src/libstore/machines.cc
@@ -53,7 +53,7 @@ void parseMachines(const std::string & s, Machines & machines)
         auto tokens = tokenizeString<std::vector<string>>(line);
         auto sz = tokens.size();
         if (sz < 1)
-            throw FormatError("bad machine specification ‘%s’", line);
+            throw FormatError("bad machine specification '%s'", line);
 
         auto isSet = [&](size_t n) {
             return tokens.size() > n && tokens[n] != "" && tokens[n] != "-";
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index 9a88cdc317b6..8fa84d3a2787 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -245,7 +245,7 @@ Paths Store::topoSortPaths(const PathSet & paths)
 
     dfsVisit = [&](const Path & path, const Path * parent) {
         if (parents.find(path) != parents.end())
-            throw BuildError(format("cycle detected in the references of ‘%1%’ from ‘%2%’") % path % *parent);
+            throw BuildError(format("cycle detected in the references of '%1%' from '%2%'") % path % *parent);
 
         if (visited.find(path) != visited.end()) return;
         visited.insert(path);
diff --git a/src/libstore/nar-accessor.cc b/src/libstore/nar-accessor.cc
index 82595e76a9b5..2afdeb021a93 100644
--- a/src/libstore/nar-accessor.cc
+++ b/src/libstore/nar-accessor.cc
@@ -46,7 +46,7 @@ struct NarIndexer : ParseSink, StringSource
             parents.push(&root);
         } else {
             if(parents.top()->type != FSAccessor::Type::tDirectory) {
-                throw Error(format("NAR file missing parent directory of path ‘%1%’") % path);
+                throw Error(format("NAR file missing parent directory of path '%1%'") % path);
             }
             auto result = parents.top()->children.emplace(baseNameOf(path), std::move(member));
             parents.push(&result.first->second);
@@ -120,7 +120,7 @@ struct NarIndexer : ParseSink, StringSource
     NarMember& at(const Path & path) {
         auto result = find(path);
         if(result == nullptr) {
-            throw Error(format("NAR file does not contain path ‘%1%’") % path);
+            throw Error(format("NAR file does not contain path '%1%'") % path);
         }
         return *result;
     }
@@ -149,7 +149,7 @@ struct NarAccessor : public FSAccessor
         auto i = indexer.at(path);
 
         if (i.type != FSAccessor::Type::tDirectory)
-            throw Error(format("path ‘%1%’ inside NAR file is not a directory") % path);
+            throw Error(format("path '%1%' inside NAR file is not a directory") % path);
 
         StringSet res;
         for(auto&& child : i.children) {
@@ -163,7 +163,7 @@ struct NarAccessor : public FSAccessor
     {
         auto i = indexer.at(path);
         if (i.type != FSAccessor::Type::tRegular)
-            throw Error(format("path ‘%1%’ inside NAR file is not a regular file") % path);
+            throw Error(format("path '%1%' inside NAR file is not a regular file") % path);
         return std::string(*nar, i.start, i.size);
     }
 
@@ -171,7 +171,7 @@ struct NarAccessor : public FSAccessor
     {
         auto i = indexer.at(path);
         if (i.type != FSAccessor::Type::tSymlink)
-            throw Error(format("path ‘%1%’ inside NAR file is not a symlink") % path);
+            throw Error(format("path '%1%' inside NAR file is not a symlink") % path);
         return i.target;
     }
 };
diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc
index 660f6a42a19d..cb568ccdc828 100644
--- a/src/libstore/nar-info.cc
+++ b/src/libstore/nar-info.cc
@@ -6,7 +6,7 @@ namespace nix {
 NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence)
 {
     auto corrupt = [&]() {
-        throw Error(format("NAR info file ‘%1%’ is corrupt") % whence);
+        throw Error(format("NAR info file '%1%' is corrupt") % whence);
     };
 
     auto parseHashField = [&](const string & s) {
diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc
index 8e8002a30db5..4461fc6dd70d 100644
--- a/src/libstore/optimise-store.cc
+++ b/src/libstore/optimise-store.cc
@@ -19,9 +19,9 @@ static void makeWritable(const Path & path)
 {
     struct stat st;
     if (lstat(path.c_str(), &st))
-        throw SysError(format("getting attributes of path ‘%1%’") % path);
+        throw SysError(format("getting attributes of path '%1%'") % path);
     if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
-        throw SysError(format("changing writability of ‘%1%’") % path);
+        throw SysError(format("changing writability of '%1%'") % path);
 }
 
 
@@ -47,7 +47,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
     InodeHash inodeHash;
 
     AutoCloseDir dir(opendir(linksDir.c_str()));
-    if (!dir) throw SysError(format("opening directory ‘%1%’") % linksDir);
+    if (!dir) throw SysError(format("opening directory '%1%'") % linksDir);
 
     struct dirent * dirent;
     while (errno = 0, dirent = readdir(dir.get())) { /* sic */
@@ -55,7 +55,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
         // We don't care if we hit non-hash files, anything goes
         inodeHash.insert(dirent->d_ino);
     }
-    if (errno) throw SysError(format("reading directory ‘%1%’") % linksDir);
+    if (errno) throw SysError(format("reading directory '%1%'") % linksDir);
 
     printMsg(lvlTalkative, format("loaded %1% hash inodes") % inodeHash.size());
 
@@ -68,14 +68,14 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
     Strings names;
 
     AutoCloseDir dir(opendir(path.c_str()));
-    if (!dir) throw SysError(format("opening directory ‘%1%’") % path);
+    if (!dir) throw SysError(format("opening directory '%1%'") % path);
 
     struct dirent * dirent;
     while (errno = 0, dirent = readdir(dir.get())) { /* sic */
         checkInterrupt();
 
         if (inodeHash.count(dirent->d_ino)) {
-            debug(format("‘%1%’ is already linked") % dirent->d_name);
+            debug(format("'%1%' is already linked") % dirent->d_name);
             continue;
         }
 
@@ -83,7 +83,7 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
         if (name == "." || name == "..") continue;
         names.push_back(name);
     }
-    if (errno) throw SysError(format("reading directory ‘%1%’") % path);
+    if (errno) throw SysError(format("reading directory '%1%'") % path);
 
     return names;
 }
@@ -95,7 +95,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
 
     struct stat st;
     if (lstat(path.c_str(), &st))
-        throw SysError(format("getting attributes of path ‘%1%’") % path);
+        throw SysError(format("getting attributes of path '%1%'") % path);
 
 #if __APPLE__
     /* HFS/OS X has some undocumented security feature disabling hardlinking for
@@ -105,7 +105,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
 
     if (std::regex_search(path, std::regex("\\.app/Contents/PkgInfo$")) ||
         std::regex_search(path, std::regex("\\.app/Contents/Resources/.+\\.lproj$"))) {
-        debug(format("‘%1%’ is not allowed to be linked in OS X") % path);
+        debug(format("'%1%' is not allowed to be linked in OS X") % path);
         return;
     }
 #endif
@@ -129,13 +129,13 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
        NixOS (example: $fontconfig/var/cache being modified).  Skip
        those files.  FIXME: check the modification time. */
     if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) {
-        printError(format("skipping suspicious writable file ‘%1%’") % path);
+        printError(format("skipping suspicious writable file '%1%'") % path);
         return;
     }
 
     /* This can still happen on top-level files. */
     if (st.st_nlink > 1 && inodeHash.count(st.st_ino)) {
-        debug(format("‘%1%’ is already linked, with %2% other file(s)") % path % (st.st_nlink - 2));
+        debug(format("'%1%' is already linked, with %2% other file(s)") % path % (st.st_nlink - 2));
         return;
     }
 
@@ -149,7 +149,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
        contents of the symlink (i.e. the result of readlink()), not
        the contents of the target (which may not even exist). */
     Hash hash = hashPath(htSHA256, path).first;
-    debug(format("‘%1%’ has hash ‘%2%’") % path % hash.to_string());
+    debug(format("'%1%' has hash '%2%'") % path % hash.to_string());
 
     /* Check if this is a known hash. */
     Path linkPath = linksDir + "/" + hash.to_string(Base32, false);
@@ -173,11 +173,11 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
                full.  When that happens, it's fine to ignore it: we
                just effectively disable deduplication of this
                file.  */
-            printInfo("cannot link ‘%s’ to ‘%s’: %s", linkPath, path, strerror(errno));
+            printInfo("cannot link '%s' to '%s': %s", linkPath, path, strerror(errno));
             return;
 
         default:
-            throw SysError("cannot link ‘%1%’ to ‘%2%’", linkPath, path);
+            throw SysError("cannot link '%1%' to '%2%'", linkPath, path);
         }
     }
 
@@ -185,20 +185,20 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
        current file with a hard link to that file. */
     struct stat stLink;
     if (lstat(linkPath.c_str(), &stLink))
-        throw SysError(format("getting attributes of path ‘%1%’") % linkPath);
+        throw SysError(format("getting attributes of path '%1%'") % linkPath);
 
     if (st.st_ino == stLink.st_ino) {
-        debug(format("‘%1%’ is already linked to ‘%2%’") % path % linkPath);
+        debug(format("'%1%' is already linked to '%2%'") % path % linkPath);
         return;
     }
 
     if (st.st_size != stLink.st_size) {
-        printError(format("removing corrupted link ‘%1%’") % linkPath);
+        printError(format("removing corrupted link '%1%'") % linkPath);
         unlink(linkPath.c_str());
         goto retry;
     }
 
-    printMsg(lvlTalkative, format("linking ‘%1%’ to ‘%2%’") % path % linkPath);
+    printMsg(lvlTalkative, format("linking '%1%' to '%2%'") % path % linkPath);
 
     /* Make the containing directory writable, but only if it's not
        the store itself (we don't want or need to mess with its
@@ -219,25 +219,25 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
                systems).  This is likely to happen with empty files.
                Just shrug and ignore. */
             if (st.st_size)
-                printInfo(format("‘%1%’ has maximum number of links") % linkPath);
+                printInfo(format("'%1%' has maximum number of links") % linkPath);
             return;
         }
-        throw SysError("cannot link ‘%1%’ to ‘%2%’", tempLink, linkPath);
+        throw SysError("cannot link '%1%' to '%2%'", tempLink, linkPath);
     }
 
     /* Atomically replace the old file with the new hard link. */
     if (rename(tempLink.c_str(), path.c_str()) == -1) {
         if (unlink(tempLink.c_str()) == -1)
-            printError(format("unable to unlink ‘%1%’") % tempLink);
+            printError(format("unable to unlink '%1%'") % tempLink);
         if (errno == EMLINK) {
             /* Some filesystems generate too many links on the rename,
                rather than on the original link.  (Probably it
                temporarily increases the st_nlink field before
                decreasing it again.) */
-            debug("‘%s’ has reached maximum number of links", linkPath);
+            debug("'%s' has reached maximum number of links", linkPath);
             return;
         }
-        throw SysError(format("cannot rename ‘%1%’ to ‘%2%’") % tempLink % path);
+        throw SysError(format("cannot rename '%1%' to '%2%'") % tempLink % path);
     }
 
     stats.filesLinked++;
@@ -254,7 +254,7 @@ void LocalStore::optimiseStore(OptimiseStats & stats)
     for (auto & i : paths) {
         addTempRoot(i);
         if (!isValidPath(i)) continue; /* path was GC'ed, probably */
-        //Activity act(*logger, lvlChatty, format("hashing files in ‘%1%’") % i);
+        //Activity act(*logger, lvlChatty, format("hashing files in '%1%'") % i);
         optimisePath_(stats, realStoreDir + "/" + baseNameOf(i), inodeHash);
     }
 }
diff --git a/src/libstore/pathlocks.cc b/src/libstore/pathlocks.cc
index bf7ad3d21851..587f29598851 100644
--- a/src/libstore/pathlocks.cc
+++ b/src/libstore/pathlocks.cc
@@ -19,7 +19,7 @@ AutoCloseFD openLockFile(const Path & path, bool create)
 
     fd = open(path.c_str(), O_CLOEXEC | O_RDWR | (create ? O_CREAT : 0), 0600);
     if (!fd && (create || errno != ENOENT))
-        throw SysError(format("opening lock file ‘%1%’") % path);
+        throw SysError(format("opening lock file '%1%'") % path);
 
     return fd;
 }
@@ -109,12 +109,12 @@ bool PathLocks::lockPaths(const PathSet & _paths,
         checkInterrupt();
         Path lockPath = path + ".lock";
 
-        debug(format("locking path ‘%1%’") % path);
+        debug(format("locking path '%1%'") % path);
 
         {
             auto lockedPaths(lockedPaths_.lock());
             if (lockedPaths->count(lockPath))
-                throw Error("deadlock: trying to re-acquire self-held lock ‘%s’", lockPath);
+                throw Error("deadlock: trying to re-acquire self-held lock '%s'", lockPath);
             lockedPaths->insert(lockPath);
         }
 
@@ -141,19 +141,19 @@ bool PathLocks::lockPaths(const PathSet & _paths,
                     }
                 }
 
-                debug(format("lock acquired on ‘%1%’") % lockPath);
+                debug(format("lock acquired on '%1%'") % lockPath);
 
                 /* Check that the lock file hasn't become stale (i.e.,
                    hasn't been unlinked). */
                 struct stat st;
                 if (fstat(fd.get(), &st) == -1)
-                    throw SysError(format("statting lock file ‘%1%’") % lockPath);
+                    throw SysError(format("statting lock file '%1%'") % lockPath);
                 if (st.st_size != 0)
                     /* This lock file has been unlinked, so we're holding
                        a lock on a deleted file.  This means that other
                        processes may create and acquire a lock on
                        `lockPath', and proceed.  So we must retry. */
-                    debug(format("open lock file ‘%1%’ has become stale") % lockPath);
+                    debug(format("open lock file '%1%' has become stale") % lockPath);
                 else
                     break;
             }
@@ -191,9 +191,9 @@ void PathLocks::unlock()
 
         if (close(i.first) == -1)
             printError(
-                format("error (ignored): cannot close lock file on ‘%1%’") % i.second);
+                format("error (ignored): cannot close lock file on '%1%'") % i.second);
 
-        debug(format("lock released on ‘%1%’") % i.second);
+        debug(format("lock released on '%1%'") % i.second);
     }
 
     fds.clear();
diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc
index f24daa8862a1..4a607b584506 100644
--- a/src/libstore/profiles.cc
+++ b/src/libstore/profiles.cc
@@ -50,7 +50,7 @@ Generations findGenerations(Path profile, int & curGen)
             gen.number = n;
             struct stat st;
             if (lstat(gen.path.c_str(), &st) != 0)
-                throw SysError(format("statting ‘%1%’") % gen.path);
+                throw SysError(format("statting '%1%'") % gen.path);
             gen.creationTime = st.st_mtime;
             gens.push_back(gen);
         }
@@ -117,7 +117,7 @@ Path createGeneration(ref<LocalFSStore> store, Path profile, Path outPath)
 static void removeFile(const Path & path)
 {
     if (remove(path.c_str()) == -1)
-        throw SysError(format("cannot unlink ‘%1%’") % path);
+        throw SysError(format("cannot unlink '%1%'") % path);
 }
 
 
@@ -149,7 +149,7 @@ void deleteGenerations(const Path & profile, const std::set<unsigned int> & gens
     Generations gens = findGenerations(profile, curGen);
 
     if (gensToDelete.find(curGen) != gensToDelete.end())
-        throw Error(format("cannot delete current generation of profile %1%’") % profile);
+        throw Error(format("cannot delete current generation of profile %1%'") % profile);
 
     for (auto & i : gens) {
         if (gensToDelete.find(i.number) == gensToDelete.end()) continue;
@@ -203,7 +203,7 @@ void deleteGenerationsOlderThan(const Path & profile, const string & timeSpec, b
     int days;
 
     if (!string2Int(strDays, days) || days < 1)
-        throw Error(format("invalid number of days specifier ‘%1%’") % timeSpec);
+        throw Error(format("invalid number of days specifier '%1%'") % timeSpec);
 
     time_t oldTime = curTime - days * 24 * 3600;
 
@@ -222,7 +222,7 @@ void switchLink(Path link, Path target)
 
 void lockProfile(PathLocks & lock, const Path & profile)
 {
-    lock.lockPaths({profile}, (format("waiting for lock on profile ‘%1%’") % profile).str());
+    lock.lockPaths({profile}, (format("waiting for lock on profile '%1%'") % profile).str());
     lock.setDeletion(true);
 }
 
diff --git a/src/libstore/references.cc b/src/libstore/references.cc
index 33eab5a240b5..ba9f18b9ca5e 100644
--- a/src/libstore/references.cc
+++ b/src/libstore/references.cc
@@ -37,7 +37,7 @@ static void search(const unsigned char * s, unsigned int len,
         if (!match) continue;
         string ref((const char *) s + i, refLength);
         if (hashes.find(ref) != hashes.end()) {
-            debug(format("found reference to ‘%1%’ at offset ‘%2%’")
+            debug(format("found reference to '%1%' at offset '%2%'")
                   % ref % i);
             seen.insert(ref);
             hashes.erase(ref);
@@ -93,7 +93,7 @@ PathSet scanForReferences(const string & path,
         string baseName = baseNameOf(i);
         string::size_type pos = baseName.find('-');
         if (pos == string::npos)
-            throw Error(format("bad reference ‘%1%’") % i);
+            throw Error(format("bad reference '%1%'") % i);
         string s = string(baseName, 0, pos);
         assert(s.size() == refLength);
         assert(backMap.find(s) == backMap.end());
diff --git a/src/libstore/remote-fs-accessor.cc b/src/libstore/remote-fs-accessor.cc
index ca14057c2e28..098151f8c0f6 100644
--- a/src/libstore/remote-fs-accessor.cc
+++ b/src/libstore/remote-fs-accessor.cc
@@ -17,7 +17,7 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path & path_)
     std::string restPath = std::string(path, storePath.size());
 
     if (!store->isValidPath(storePath))
-        throw InvalidPath(format("path ‘%1%’ is not a valid store path") % storePath);
+        throw InvalidPath(format("path '%1%' is not a valid store path") % storePath);
 
     auto i = nars.find(storePath);
     if (i != nars.end()) return {i->second, restPath};
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index ab726e79534a..e9f2cee80db0 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -54,7 +54,7 @@ RemoteStore::RemoteStore(const Params & params)
 ref<RemoteStore::Connection> RemoteStore::openConnectionWrapper()
 {
     if (failed)
-        throw Error("opening a connection to remote store ‘%s’ previously failed", getUri());
+        throw Error("opening a connection to remote store '%s' previously failed", getUri());
     try {
         return openConnection();
     } catch (...) {
@@ -97,11 +97,11 @@ ref<RemoteStore::Connection> UDSRemoteStore::openConnection()
     struct sockaddr_un addr;
     addr.sun_family = AF_UNIX;
     if (socketPath.size() + 1 >= sizeof(addr.sun_path))
-        throw Error(format("socket path ‘%1%’ is too long") % socketPath);
+        throw Error(format("socket path '%1%' is too long") % socketPath);
     strcpy(addr.sun_path, socketPath.c_str());
 
     if (::connect(conn->fd.get(), (struct sockaddr *) &addr, sizeof(addr)) == -1)
-        throw SysError(format("cannot connect to daemon at ‘%1%’") % socketPath);
+        throw SysError(format("cannot connect to daemon at '%1%'") % socketPath);
 
     conn->from.fd = conn->fd.get();
     conn->to.fd = conn->fd.get();
@@ -142,7 +142,7 @@ void RemoteStore::initConnection(Connection & conn)
         conn.processStderr();
     }
     catch (Error & e) {
-        throw Error("cannot open connection to remote store ‘%s’: %s", getUri(), e.what());
+        throw Error("cannot open connection to remote store '%s': %s", getUri(), e.what());
     }
 
     setOptions(conn);
@@ -288,7 +288,7 @@ void RemoteStore::queryPathInfoUncached(const Path & path,
         }
         if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 17) {
             bool valid; conn->from >> valid;
-            if (!valid) throw InvalidPath(format("path ‘%s’ is not valid") % path);
+            if (!valid) throw InvalidPath(format("path '%s' is not valid") % path);
         }
         auto info = std::make_shared<ValidPathInfo>();
         info->path = path;
diff --git a/src/libstore/s3-binary-cache-store.cc b/src/libstore/s3-binary-cache-store.cc
index 145a8191c55c..5fc7371a5198 100644
--- a/src/libstore/s3-binary-cache-store.cc
+++ b/src/libstore/s3-binary-cache-store.cc
@@ -110,7 +110,7 @@ ref<Aws::Client::ClientConfiguration> S3Helper::makeConfig(const string & region
 S3Helper::DownloadResult S3Helper::getObject(
     const std::string & bucketName, const std::string & key)
 {
-    debug("fetching ‘s3://%s/%s’...", bucketName, key);
+    debug("fetching 's3://%s/%s'...", bucketName, key);
 
     auto request =
         Aws::S3::Model::GetObjectRequest()
@@ -127,7 +127,7 @@ S3Helper::DownloadResult S3Helper::getObject(
 
     try {
 
-        auto result = checkAws(fmt("AWS error fetching ‘%s’", key),
+        auto result = checkAws(fmt("AWS error fetching '%s'", key),
             client->GetObject(request));
 
         res.data = decodeContent(
@@ -185,9 +185,9 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
 
             if (!res.IsSuccess()) {
                 if (res.GetError().GetErrorType() != Aws::S3::S3Errors::NO_SUCH_BUCKET)
-                    throw Error(format("AWS error checking bucket ‘%s’: %s") % bucketName % res.GetError().GetMessage());
+                    throw Error(format("AWS error checking bucket '%s': %s") % bucketName % res.GetError().GetMessage());
 
-                printInfo("creating S3 bucket ‘%s’...", bucketName);
+                printInfo("creating S3 bucket '%s'...", bucketName);
 
                 // Stupid S3 bucket locations.
                 auto bucketConfig = Aws::S3::Model::CreateBucketConfiguration();
@@ -196,7 +196,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
                         Aws::S3::Model::BucketLocationConstraintMapper::GetBucketLocationConstraintForName(
                             s3Helper.config->region));
 
-                checkAws(format("AWS error creating bucket ‘%s’") % bucketName,
+                checkAws(format("AWS error creating bucket '%s'") % bucketName,
                     s3Helper.client->CreateBucket(
                         Aws::S3::Model::CreateBucketRequest()
                         .WithBucket(bucketName)
@@ -244,7 +244,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
                 || (error.GetErrorType() == Aws::S3::S3Errors::UNKNOWN // FIXME
                     && error.GetMessage().find("404") != std::string::npos))
                 return false;
-            throw Error(format("AWS error fetching ‘%s’: %s") % path % error.GetMessage());
+            throw Error(format("AWS error fetching '%s': %s") % path % error.GetMessage());
         }
 
         return true;
@@ -273,14 +273,14 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
 
         auto now1 = std::chrono::steady_clock::now();
 
-        auto result = checkAws(format("AWS error uploading ‘%s’") % path,
+        auto result = checkAws(format("AWS error uploading '%s'") % path,
             s3Helper.client->PutObject(request));
 
         auto now2 = std::chrono::steady_clock::now();
 
         auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now2 - now1).count();
 
-        printInfo(format("uploaded ‘s3://%1%/%2%’ (%3% bytes) in %4% ms")
+        printInfo(format("uploaded 's3://%1%/%2%' (%3% bytes) in %4% ms")
             % bucketName % path % data.size() % duration);
 
         stats.putTimeMs += duration;
@@ -312,7 +312,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
             stats.getTimeMs += res.durationMs;
 
             if (res.data)
-                printTalkative("downloaded ‘s3://%s/%s’ (%d bytes) in %d ms",
+                printTalkative("downloaded 's3://%s/%s' (%d bytes) in %d ms",
                     bucketName, path, res.data->size(), res.durationMs);
 
             return res.data;
@@ -325,9 +325,9 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
         std::string marker;
 
         do {
-            debug(format("listing bucket ‘s3://%s’ from key ‘%s’...") % bucketName % marker);
+            debug(format("listing bucket 's3://%s' from key '%s'...") % bucketName % marker);
 
-            auto res = checkAws(format("AWS error listing bucket ‘%s’") % bucketName,
+            auto res = checkAws(format("AWS error listing bucket '%s'") % bucketName,
                 s3Helper.client->ListObjects(
                     Aws::S3::Model::ListObjectsRequest()
                     .WithBucket(bucketName)
@@ -336,7 +336,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
 
             auto & contents = res.GetContents();
 
-            debug(format("got %d keys, next marker ‘%s’")
+            debug(format("got %d keys, next marker '%s'")
                 % contents.size() % res.GetNextMarker());
 
             for (auto object : contents) {
diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc
index a81e62dbd6eb..b13001b06d57 100644
--- a/src/libstore/sqlite.cc
+++ b/src/libstore/sqlite.cc
@@ -17,18 +17,18 @@ namespace nix {
     if (err == SQLITE_BUSY || err == SQLITE_PROTOCOL) {
         throw SQLiteBusy(
             err == SQLITE_PROTOCOL
-            ? fmt("SQLite database ‘%s’ is busy (SQLITE_PROTOCOL)", path)
-            : fmt("SQLite database ‘%s’ is busy", path));
+            ? fmt("SQLite database '%s' is busy (SQLITE_PROTOCOL)", path)
+            : fmt("SQLite database '%s' is busy", path));
     }
     else
-        throw SQLiteError("%s: %s (in ‘%s’)", f.str(), sqlite3_errstr(err), path);
+        throw SQLiteError("%s: %s (in '%s')", f.str(), sqlite3_errstr(err), path);
 }
 
 SQLite::SQLite(const Path & path)
 {
     if (sqlite3_open_v2(path.c_str(), &db,
             SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0) != SQLITE_OK)
-        throw Error(format("cannot open SQLite database ‘%s’") % path);
+        throw Error(format("cannot open SQLite database '%s'") % path);
 }
 
 SQLite::~SQLite()
@@ -45,7 +45,7 @@ void SQLite::exec(const std::string & stmt)
 {
     retrySQLite<void>([&]() {
         if (sqlite3_exec(db, stmt.c_str(), 0, 0, 0) != SQLITE_OK)
-            throwSQLiteError(db, format("executing SQLite statement ‘%s’") % stmt);
+            throwSQLiteError(db, format("executing SQLite statement '%s'") % stmt);
     });
 }
 
@@ -54,7 +54,7 @@ void SQLiteStmt::create(sqlite3 * db, const string & sql)
     checkInterrupt();
     assert(!stmt);
     if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, 0) != SQLITE_OK)
-        throwSQLiteError(db, fmt("creating statement ‘%s’", sql));
+        throwSQLiteError(db, fmt("creating statement '%s'", sql));
     this->db = db;
     this->sql = sql;
 }
@@ -63,7 +63,7 @@ SQLiteStmt::~SQLiteStmt()
 {
     try {
         if (stmt && sqlite3_finalize(stmt) != SQLITE_OK)
-            throwSQLiteError(db, fmt("finalizing statement ‘%s’", sql));
+            throwSQLiteError(db, fmt("finalizing statement '%s'", sql));
     } catch (...) {
         ignoreException();
     }
@@ -120,14 +120,14 @@ void SQLiteStmt::Use::exec()
     int r = step();
     assert(r != SQLITE_ROW);
     if (r != SQLITE_DONE)
-        throwSQLiteError(stmt.db, fmt("executing SQLite statement ‘%s’", stmt.sql));
+        throwSQLiteError(stmt.db, fmt("executing SQLite statement '%s'", stmt.sql));
 }
 
 bool SQLiteStmt::Use::next()
 {
     int r = step();
     if (r != SQLITE_DONE && r != SQLITE_ROW)
-        throwSQLiteError(stmt.db, fmt("executing SQLite query ‘%s’", stmt.sql));
+        throwSQLiteError(stmt.db, fmt("executing SQLite query '%s'", stmt.sql));
     return r == SQLITE_ROW;
 }
 
diff --git a/src/libstore/ssh.cc b/src/libstore/ssh.cc
index 6edabaa3a1d9..776ffdb83431 100644
--- a/src/libstore/ssh.cc
+++ b/src/libstore/ssh.cc
@@ -41,7 +41,7 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(const std::string
         args.push_back(command);
         execvp(args.begin()->c_str(), stringsToCharPtrs(args).data());
 
-        throw SysError("executing ‘%s’ on ‘%s’", command, host);
+        throw SysError("executing '%s' on '%s'", command, host);
     });
 
 
@@ -96,7 +96,7 @@ Path SSHMaster::startMaster()
     } catch (EndOfFile & e) { }
 
     if (reply != "started")
-        throw Error("failed to start SSH master connection to ‘%s’", host);
+        throw Error("failed to start SSH master connection to '%s'", host);
 
     return state->socketPath;
 }
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 27bfbcb8f129..dd87a046e380 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -30,14 +30,14 @@ bool Store::isStorePath(const Path & path) const
 void Store::assertStorePath(const Path & path) const
 {
     if (!isStorePath(path))
-        throw Error(format("path ‘%1%’ is not in the Nix store") % path);
+        throw Error(format("path '%1%' is not in the Nix store") % path);
 }
 
 
 Path Store::toStorePath(const Path & path) const
 {
     if (!isInStore(path))
-        throw Error(format("path ‘%1%’ is not in the Nix store") % path);
+        throw Error(format("path '%1%' is not in the Nix store") % path);
     Path::size_type slash = path.find('/', storeDir.size() + 1);
     if (slash == Path::npos)
         return path;
@@ -55,7 +55,7 @@ Path Store::followLinksToStore(const Path & _path) const
         path = absPath(target, dirOf(path));
     }
     if (!isInStore(path))
-        throw Error(format("path ‘%1%’ is not in the Nix store") % path);
+        throw Error(format("path '%1%' is not in the Nix store") % path);
     return path;
 }
 
@@ -88,14 +88,14 @@ void checkStoreName(const string & name)
     /* Disallow names starting with a dot for possible security
        reasons (e.g., "." and ".."). */
     if (string(name, 0, 1) == ".")
-        throw Error(format("illegal name: ‘%1%’") % name);
+        throw Error(format("illegal name: '%1%'") % name);
     for (auto & i : name)
         if (!((i >= 'A' && i <= 'Z') ||
               (i >= 'a' && i <= 'z') ||
               (i >= '0' && i <= '9') ||
               validChars.find(i) != string::npos))
         {
-            throw Error(format("invalid character ‘%1%’ in name ‘%2%’")
+            throw Error(format("invalid character '%1%' in name '%2%'")
                 % i % name);
         }
 }
@@ -328,7 +328,7 @@ void Store::queryPathInfo(const Path & storePath,
             if (res) {
                 stats.narInfoReadAverted++;
                 if (!*res)
-                    throw InvalidPath(format("path ‘%s’ is not valid") % storePath);
+                    throw InvalidPath(format("path '%s' is not valid") % storePath);
                 return success(ref<ValidPathInfo>(*res));
             }
         }
@@ -343,7 +343,7 @@ void Store::queryPathInfo(const Path & storePath,
                         res.first == NarInfoDiskCache::oInvalid ? 0 : res.second);
                     if (res.first == NarInfoDiskCache::oInvalid ||
                         (res.second->path != storePath && storePathToName(storePath) != ""))
-                        throw InvalidPath(format("path ‘%s’ is not valid") % storePath);
+                        throw InvalidPath(format("path '%s' is not valid") % storePath);
                 }
                 return success(ref<ValidPathInfo>(res.second));
             }
@@ -368,7 +368,7 @@ void Store::queryPathInfo(const Path & storePath,
                 || (info->path != storePath && storePathToName(storePath) != ""))
             {
                 stats.narInfoMissing++;
-                return failure(std::make_exception_ptr(InvalidPath(format("path ‘%s’ is not valid") % storePath)));
+                return failure(std::make_exception_ptr(InvalidPath(format("path '%s' is not valid") % storePath)));
             }
 
             callSuccess(success, failure, ref<ValidPathInfo>(info));
@@ -614,7 +614,7 @@ void copyPaths(ref<Store> srcStore, ref<Store> dstStore, const PathSet & storePa
             checkInterrupt();
 
             if (!dstStore->isValidPath(storePath)) {
-                printInfo("copying ‘%s’...", storePath);
+                printInfo("copying '%s'...", storePath);
                 copyStorePath(srcStore, dstStore, storePath, repair, checkSigs);
             }
         });
@@ -661,7 +661,7 @@ string showPaths(const PathSet & paths)
     string s;
     for (auto & i : paths) {
         if (s.size() != 0) s += ", ";
-        s += "‘" + i + "’";
+        s += "'" + i + "'";
     }
     return s;
 }
@@ -670,7 +670,7 @@ string showPaths(const PathSet & paths)
 std::string ValidPathInfo::fingerprint() const
 {
     if (narSize == 0 || !narHash)
-        throw Error(format("cannot calculate fingerprint of path ‘%s’ because its size/hash is not known")
+        throw Error(format("cannot calculate fingerprint of path '%s' because its size/hash is not known")
             % path);
     return
         "1;" + path + ";"
@@ -689,7 +689,7 @@ void ValidPathInfo::sign(const SecretKey & secretKey)
 bool ValidPathInfo::isContentAddressed(const Store & store) const
 {
     auto warn = [&]() {
-        printError(format("warning: path ‘%s’ claims to be content-addressed but isn't") % path);
+        printError(format("warning: path '%s' claims to be content-addressed but isn't") % path);
     };
 
     if (hasPrefix(ca, "text:")) {
@@ -782,7 +782,7 @@ ref<Store> openStore(const std::string & uri_,
         }
     }
 
-    throw Error("don't know how to open Nix store ‘%s’", uri);
+    throw Error("don't know how to open Nix store '%s'", uri);
 }
 
 
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 3247a67678cf..5f3d8c7b9529 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -604,7 +604,7 @@ protected:
     /* Unsupported methods. */
     [[noreturn]] void unsupported()
     {
-        throw Unsupported("requested operation is not supported by store ‘%s’", getUri());
+        throw Unsupported("requested operation is not supported by store '%s'", getUri());
     }
 
 };
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc
index e0e6f5dfd73c..be527450c464 100644
--- a/src/libutil/archive.cc
+++ b/src/libutil/archive.cc
@@ -38,7 +38,7 @@ static void dumpContents(const Path & path, size_t size,
     sink << "contents" << size;
 
     AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
-    if (!fd) throw SysError(format("opening file ‘%1%’") % path);
+    if (!fd) throw SysError(format("opening file '%1%'") % path);
 
     unsigned char buf[65536];
     size_t left = size;
@@ -58,7 +58,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
 {
     struct stat st;
     if (lstat(path.c_str(), &st))
-        throw SysError(format("getting attributes of path ‘%1%’") % path);
+        throw SysError(format("getting attributes of path '%1%'") % path);
 
     sink << "(";
 
@@ -80,11 +80,11 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
                 string name(i.name);
                 size_t pos = i.name.find(caseHackSuffix);
                 if (pos != string::npos) {
-                    debug(format("removing case hack suffix from ‘%1%’") % (path + "/" + i.name));
+                    debug(format("removing case hack suffix from '%1%'") % (path + "/" + i.name));
                     name.erase(pos);
                 }
                 if (unhacked.find(name) != unhacked.end())
-                    throw Error(format("file name collision in between ‘%1%’ and ‘%2%’")
+                    throw Error(format("file name collision in between '%1%' and '%2%'")
                         % (path + "/" + unhacked[name]) % (path + "/" + i.name));
                 unhacked[name] = i.name;
             } else
@@ -101,7 +101,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
     else if (S_ISLNK(st.st_mode))
         sink << "type" << "symlink" << "target" << readLink(path);
 
-    else throw Error(format("file ‘%1%’ has an unsupported type") % path);
+    else throw Error(format("file '%1%' has an unsupported type") % path);
 
     sink << ")";
 }
@@ -237,14 +237,14 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
                 } else if (s == "name") {
                     name = readString(source);
                     if (name.empty() || name == "." || name == ".." || name.find('/') != string::npos || name.find((char) 0) != string::npos)
-                        throw Error(format("NAR contains invalid file name ‘%1%’") % name);
+                        throw Error(format("NAR contains invalid file name '%1%'") % name);
                     if (name <= prevName)
                         throw Error("NAR directory is not sorted");
                     prevName = name;
                     if (useCaseHack) {
                         auto i = names.find(name);
                         if (i != names.end()) {
-                            debug(format("case collision between ‘%1%’ and ‘%2%’") % i->first % name);
+                            debug(format("case collision between '%1%' and '%2%'") % i->first % name);
                             name += caseHackSuffix;
                             name += std::to_string(++i->second);
                         } else
@@ -293,14 +293,14 @@ struct RestoreSink : ParseSink
     {
         Path p = dstPath + path;
         if (mkdir(p.c_str(), 0777) == -1)
-            throw SysError(format("creating directory ‘%1%’") % p);
+            throw SysError(format("creating directory '%1%'") % p);
     };
 
     void createRegularFile(const Path & path)
     {
         Path p = dstPath + path;
         fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666);
-        if (!fd) throw SysError(format("creating file ‘%1%’") % p);
+        if (!fd) throw SysError(format("creating file '%1%'") % p);
     }
 
     void isExecutable()
diff --git a/src/libutil/args.cc b/src/libutil/args.cc
index 19a45d7e9b37..2b72079f2b47 100644
--- a/src/libutil/args.cc
+++ b/src/libutil/args.cc
@@ -47,7 +47,7 @@ void Args::parseCmdline(const Strings & _cmdline)
         }
         else if (!dashDash && std::string(arg, 0, 1) == "-") {
             if (!processFlag(pos, cmdline.end()))
-                throw UsageError(format("unrecognised flag ‘%1%’") % arg);
+                throw UsageError(format("unrecognised flag '%1%'") % arg);
         }
         else {
             pendingArgs.push_back(*pos++);
@@ -103,7 +103,7 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
         Strings args;
         for (size_t n = 0 ; n < flag.arity; ++n) {
             if (pos == end)
-                throw UsageError(format("flag ‘%1%’ requires %2% argument(s)")
+                throw UsageError(format("flag '%1%' requires %2% argument(s)")
                     % name % flag.arity);
             args.push_back(*pos++);
         }
@@ -131,7 +131,7 @@ bool Args::processArgs(const Strings & args, bool finish)
 {
     if (expectedArgs.empty()) {
         if (!args.empty())
-            throw UsageError(format("unexpected argument ‘%1%’") % args.front());
+            throw UsageError(format("unexpected argument '%1%'") % args.front());
         return true;
     }
 
@@ -155,10 +155,10 @@ bool Args::processArgs(const Strings & args, bool finish)
 
 void Args::mkHashTypeFlag(const std::string & name, HashType * ht)
 {
-    mkFlag1(0, name, "TYPE", "hash algorithm (‘md5’, ‘sha1’, ‘sha256’, or ‘sha512’)", [=](std::string s) {
+    mkFlag1(0, name, "TYPE", "hash algorithm ('md5', 'sha1', 'sha256', or 'sha512')", [=](std::string s) {
         *ht = parseHashType(s);
         if (*ht == htUnknown)
-            throw UsageError(format("unknown hash type ‘%1%’") % s);
+            throw UsageError(format("unknown hash type '%1%'") % s);
     });
 }
 
diff --git a/src/libutil/args.hh b/src/libutil/args.hh
index 37e780dd1748..fd910b965ccc 100644
--- a/src/libutil/args.hh
+++ b/src/libutil/args.hh
@@ -158,7 +158,7 @@ public:
             .handler([=](Strings ss) {
                 I n;
                 if (!string2Int(ss.front(), n))
-                    throw UsageError(format("flag ‘--%1%’ requires a integer argument") % longName);
+                    throw UsageError(format("flag '--%1%' requires a integer argument") % longName);
                 fun(n);
             });
     }
diff --git a/src/libutil/compression.cc b/src/libutil/compression.cc
index b0b1d709fa44..2b3dff3a5ea1 100644
--- a/src/libutil/compression.cc
+++ b/src/libutil/compression.cc
@@ -118,7 +118,7 @@ ref<std::string> decompress(const std::string & method, const std::string & in)
     else if (method == "br")
         return decompressBrotli(in);
     else
-        throw UnknownCompressionMethod(format("unknown compression method ‘%s’") % method);
+        throw UnknownCompressionMethod(format("unknown compression method '%s'") % method);
 }
 
 struct NoneSink : CompressionSink
@@ -309,7 +309,7 @@ ref<CompressionSink> makeCompressionSink(const std::string & method, Sink & next
     else if (method == "br")
         return make_ref<BrotliSink>(nextSink);
     else
-        throw UnknownCompressionMethod(format("unknown compression method ‘%s’") % method);
+        throw UnknownCompressionMethod(format("unknown compression method '%s'") % method);
 }
 
 }
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index 0682bcd5dbc3..27157a83178a 100644
--- a/src/libutil/config.cc
+++ b/src/libutil/config.cc
@@ -81,7 +81,7 @@ void Config::applyConfigFile(const Path & path, bool fatal)
             if (tokens.empty()) continue;
 
             if (tokens.size() < 2 || tokens[1] != "=")
-                throw UsageError("illegal configuration line ‘%1%’ in ‘%2%’", line, path);
+                throw UsageError("illegal configuration line '%1%' in '%2%'", line, path);
 
             string name = tokens[0];
 
diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc
index e16c3b6ea93f..11e3c9dca58a 100644
--- a/src/libutil/hash.cc
+++ b/src/libutil/hash.cc
@@ -133,14 +133,14 @@ Hash::Hash(const std::string & s, HashType type)
 
     if (colon == string::npos) {
         if (type == htUnknown)
-            throw BadHash("hash ‘%s’ does not include a type", s);
+            throw BadHash("hash '%s' does not include a type", s);
     } else {
         string hts = string(s, 0, colon);
         this->type = parseHashType(hts);
         if (this->type == htUnknown)
-            throw BadHash("unknown hash type ‘%s’", hts);
+            throw BadHash("unknown hash type '%s'", hts);
         if (type != htUnknown && type != this->type)
-            throw BadHash("hash ‘%s’ should have type ‘%s’", s, printHashType(type));
+            throw BadHash("hash '%s' should have type '%s'", s, printHashType(type));
         pos = colon + 1;
     }
 
@@ -154,7 +154,7 @@ Hash::Hash(const std::string & s, HashType type)
             if (c >= '0' && c <= '9') return c - '0';
             if (c >= 'A' && c <= 'F') return c - 'A' + 10;
             if (c >= 'a' && c <= 'f') return c - 'a' + 10;
-            throw BadHash("invalid base-16 hash ‘%s’", s);
+            throw BadHash("invalid base-16 hash '%s'", s);
         };
 
         for (unsigned int i = 0; i < hashSize; i++) {
@@ -172,7 +172,7 @@ Hash::Hash(const std::string & s, HashType type)
             for (digit = 0; digit < base32Chars.size(); ++digit) /* !!! slow */
                 if (base32Chars[digit] == c) break;
             if (digit >= 32)
-                throw BadHash("invalid base-32 hash ‘%s’", s);
+                throw BadHash("invalid base-32 hash '%s'", s);
             unsigned int b = n * 5;
             unsigned int i = b / 8;
             unsigned int j = b % 8;
@@ -182,7 +182,7 @@ Hash::Hash(const std::string & s, HashType type)
                 hash[i + 1] |= digit >> (8 - j);
             } else {
                 if (digit >> (8 - j))
-                    throw BadHash("invalid base-32 hash ‘%s’", s);
+                    throw BadHash("invalid base-32 hash '%s'", s);
             }
         }
     }
@@ -194,7 +194,7 @@ Hash::Hash(const std::string & s, HashType type)
     }
 
     else
-        throw BadHash("hash ‘%s’ has wrong length for hash type ‘%s’", s, printHashType(type));
+        throw BadHash("hash '%s' has wrong length for hash type '%s'", s, printHashType(type));
 }
 
 
@@ -253,13 +253,13 @@ Hash hashFile(HashType ht, const Path & path)
     start(ht, ctx);
 
     AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
-    if (!fd) throw SysError(format("opening file ‘%1%’") % path);
+    if (!fd) throw SysError(format("opening file '%1%'") % path);
 
     unsigned char buf[8192];
     ssize_t n;
     while ((n = read(fd.get(), buf, sizeof(buf)))) {
         checkInterrupt();
-        if (n == -1) throw SysError(format("reading file ‘%1%’") % path);
+        if (n == -1) throw SysError(format("reading file '%1%'") % path);
         update(ht, ctx, buf, n);
     }
 
diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh
index b8b432256c97..d83049b02368 100644
--- a/src/libutil/hash.hh
+++ b/src/libutil/hash.hh
@@ -38,7 +38,7 @@ struct Hash
     Hash(HashType type) : type(type) { init(); };
 
     /* Initialize the hash from a string representation, in the format
-       "[<type>:]<base16|base32|base64>". If the ‘type’ argument is
+       "[<type>:]<base16|base32|base64>". If the 'type' argument is
        htUnknown, then the hash type must be specified in the
        string. */
     Hash(const std::string & s, HashType type = htUnknown);
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh
index 2bdee70807be..70b193941638 100644
--- a/src/libutil/serialise.hh
+++ b/src/libutil/serialise.hh
@@ -198,7 +198,7 @@ T readNum(Source & source)
         ((unsigned long long) buf[7] << 56);
 
     if (n > std::numeric_limits<T>::max())
-        throw SerialisationError("serialised integer %d is too large for type ‘%s’", n, typeid(T).name());
+        throw SerialisationError("serialised integer %d is too large for type '%s'", n, typeid(T).name());
 
     return n;
 }
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index d9f8011b6fb9..27f4fea187d2 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -104,7 +104,7 @@ Path canonPath(const Path & path, bool resolveSymlinks)
     string s;
 
     if (path[0] != '/')
-        throw Error(format("not an absolute path: ‘%1%’") % path);
+        throw Error(format("not an absolute path: '%1%'") % path);
 
     string::const_iterator i = path.begin(), end = path.end();
     string temp;
@@ -140,7 +140,7 @@ Path canonPath(const Path & path, bool resolveSymlinks)
                the symlink target might contain new symlinks). */
             if (resolveSymlinks && isLink(s)) {
                 if (++followCount >= maxFollow)
-                    throw Error(format("infinite symlink recursion in path ‘%1%’") % path);
+                    throw Error(format("infinite symlink recursion in path '%1%'") % path);
                 temp = absPath(readLink(s), dirOf(s))
                     + string(i, end);
                 i = temp.begin(); /* restart */
@@ -158,7 +158,7 @@ Path dirOf(const Path & path)
 {
     Path::size_type pos = path.rfind('/');
     if (pos == string::npos)
-        throw Error(format("invalid file name ‘%1%’") % path);
+        throw Error(format("invalid file name '%1%'") % path);
     return pos == 0 ? "/" : Path(path, 0, pos);
 }
 
@@ -195,7 +195,7 @@ struct stat lstat(const Path & path)
 {
     struct stat st;
     if (lstat(path.c_str(), &st))
-        throw SysError(format("getting status of ‘%1%’") % path);
+        throw SysError(format("getting status of '%1%'") % path);
     return st;
 }
 
@@ -217,13 +217,13 @@ Path readLink(const Path & path)
     checkInterrupt();
     struct stat st = lstat(path);
     if (!S_ISLNK(st.st_mode))
-        throw Error(format("‘%1%’ is not a symlink") % path);
+        throw Error(format("'%1%' is not a symlink") % path);
     char buf[st.st_size];
     ssize_t rlsize = readlink(path.c_str(), buf, st.st_size);
     if (rlsize == -1)
-        throw SysError(format("reading symbolic link ‘%1%’") % path);
+        throw SysError(format("reading symbolic link '%1%'") % path);
     else if (rlsize > st.st_size)
-        throw Error(format("symbolic link ‘%1%’ size overflow %2% > %3%")
+        throw Error(format("symbolic link '%1%' size overflow %2% > %3%")
             % path % rlsize % st.st_size);
     return string(buf, rlsize);
 }
@@ -242,7 +242,7 @@ DirEntries readDirectory(const Path & path)
     entries.reserve(64);
 
     AutoCloseDir dir(opendir(path.c_str()));
-    if (!dir) throw SysError(format("opening directory ‘%1%’") % path);
+    if (!dir) throw SysError(format("opening directory '%1%'") % path);
 
     struct dirent * dirent;
     while (errno = 0, dirent = readdir(dir.get())) { /* sic */
@@ -257,7 +257,7 @@ DirEntries readDirectory(const Path & path)
 #endif
         );
     }
-    if (errno) throw SysError(format("reading directory ‘%1%’") % path);
+    if (errno) throw SysError(format("reading directory '%1%'") % path);
 
     return entries;
 }
@@ -290,7 +290,7 @@ string readFile(const Path & path, bool drain)
 {
     AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
     if (!fd)
-        throw SysError(format("opening file ‘%1%’") % path);
+        throw SysError(format("opening file '%1%'") % path);
     return drain ? drainFD(fd.get()) : readFile(fd.get());
 }
 
@@ -299,7 +299,7 @@ void writeFile(const Path & path, const string & s, mode_t mode)
 {
     AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode);
     if (!fd)
-        throw SysError(format("opening file ‘%1%’") % path);
+        throw SysError(format("opening file '%1%'") % path);
     writeFull(fd.get(), s);
 }
 
@@ -338,7 +338,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
     struct stat st;
     if (lstat(path.c_str(), &st) == -1) {
         if (errno == ENOENT) return;
-        throw SysError(format("getting status of ‘%1%’") % path);
+        throw SysError(format("getting status of '%1%'") % path);
     }
 
     if (!S_ISDIR(st.st_mode) && st.st_nlink == 1)
@@ -349,7 +349,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
         const auto PERM_MASK = S_IRUSR | S_IWUSR | S_IXUSR;
         if ((st.st_mode & PERM_MASK) != PERM_MASK) {
             if (chmod(path.c_str(), st.st_mode | PERM_MASK) == -1)
-                throw SysError(format("chmod ‘%1%’") % path);
+                throw SysError(format("chmod '%1%'") % path);
         }
 
         for (auto & i : readDirectory(path))
@@ -358,7 +358,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed)
 
     if (remove(path.c_str()) == -1) {
         if (errno == ENOENT) return;
-        throw SysError(format("cannot unlink ‘%1%’") % path);
+        throw SysError(format("cannot unlink '%1%'") % path);
     }
 }
 
@@ -372,7 +372,7 @@ void deletePath(const Path & path)
 
 void deletePath(const Path & path, unsigned long long & bytesFreed)
 {
-    //Activity act(*logger, lvlDebug, format("recursively deleting path ‘%1%’") % path);
+    //Activity act(*logger, lvlDebug, format("recursively deleting path '%1%'") % path);
     bytesFreed = 0;
     _deletePath(path, bytesFreed);
 }
@@ -410,12 +410,12 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix,
                "wheel", then "tar" will fail to unpack archives that
                have the setgid bit set on directories. */
             if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0)
-                throw SysError(format("setting group of directory ‘%1%’") % tmpDir);
+                throw SysError(format("setting group of directory '%1%'") % tmpDir);
 #endif
             return tmpDir;
         }
         if (errno != EEXIST)
-            throw SysError(format("creating directory ‘%1%’") % tmpDir);
+            throw SysError(format("creating directory '%1%'") % tmpDir);
     }
 }
 
@@ -473,15 +473,15 @@ Paths createDirs(const Path & path)
     if (lstat(path.c_str(), &st) == -1) {
         created = createDirs(dirOf(path));
         if (mkdir(path.c_str(), 0777) == -1 && errno != EEXIST)
-            throw SysError(format("creating directory ‘%1%’") % path);
+            throw SysError(format("creating directory '%1%'") % path);
         st = lstat(path);
         created.push_back(path);
     }
 
     if (S_ISLNK(st.st_mode) && stat(path.c_str(), &st) == -1)
-        throw SysError(format("statting symlink ‘%1%’") % path);
+        throw SysError(format("statting symlink '%1%'") % path);
 
-    if (!S_ISDIR(st.st_mode)) throw Error(format("‘%1%’ is not a directory") % path);
+    if (!S_ISDIR(st.st_mode)) throw Error(format("'%1%' is not a directory") % path);
 
     return created;
 }
@@ -490,7 +490,7 @@ Paths createDirs(const Path & path)
 void createSymlink(const Path & target, const Path & link)
 {
     if (symlink(target.c_str(), link.c_str()))
-        throw SysError(format("creating symlink from ‘%1%’ to ‘%2%’") % link % target);
+        throw SysError(format("creating symlink from '%1%' to '%2%'") % link % target);
 }
 
 
@@ -507,7 +507,7 @@ void replaceSymlink(const Path & target, const Path & link)
         }
 
         if (rename(tmp.c_str(), link.c_str()) != 0)
-            throw SysError(format("renaming ‘%1%’ to ‘%2%’") % tmp % link);
+            throw SysError(format("renaming '%1%' to '%2%'") % tmp % link);
 
         break;
     }
@@ -589,7 +589,7 @@ AutoDelete::~AutoDelete()
                 deletePath(path);
             else {
                 if (remove(path.c_str()) == -1)
-                    throw SysError(format("cannot unlink ‘%1%’") % path);
+                    throw SysError(format("cannot unlink '%1%'") % path);
             }
         }
     } catch (...) {
@@ -786,7 +786,7 @@ pid_t Pid::release()
 
 void killUser(uid_t uid)
 {
-    debug(format("killing all processes running under uid ‘%1%’") % uid);
+    debug(format("killing all processes running under uid '%1%'") % uid);
 
     assert(uid != 0); /* just to be safe... */
 
@@ -815,7 +815,7 @@ void killUser(uid_t uid)
 #endif
             if (errno == ESRCH) break; /* no more processes */
             if (errno != EINTR)
-                throw SysError(format("cannot kill processes for uid ‘%1%’") % uid);
+                throw SysError(format("cannot kill processes for uid '%1%'") % uid);
         }
 
         _exit(0);
@@ -823,7 +823,7 @@ void killUser(uid_t uid)
 
     int status = pid.wait();
     if (status != 0)
-        throw Error(format("cannot kill processes for uid ‘%1%’: %2%") % uid % statusToString(status));
+        throw Error(format("cannot kill processes for uid '%1%': %2%") % uid % statusToString(status));
 
     /* !!! We should really do some check to make sure that there are
        no processes left running under `uid', but there is no portable
@@ -917,7 +917,7 @@ string runProgram(Path program, bool searchPath, const Strings & args,
         else
             execv(program.c_str(), stringsToCharPtrs(args_).data());
 
-        throw SysError(format("executing ‘%1%’") % program);
+        throw SysError(format("executing '%1%'") % program);
     });
 
     out.writeSide = -1;
@@ -950,7 +950,7 @@ string runProgram(Path program, bool searchPath, const Strings & args,
     /* Wait for the child to finish. */
     int status = pid.wait();
     if (!statusOk(status))
-        throw ExecError(status, format("program ‘%1%’ %2%")
+        throw ExecError(status, format("program '%1%' %2%")
             % program % statusToString(status));
 
     /* Wait for the writer thread to finish. */
diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc
index 769ca8cd03a2..b36933a0ac21 100755
--- a/src/nix-build/nix-build.cc
+++ b/src/nix-build/nix-build.cc
@@ -238,7 +238,7 @@ void mainWrapped(int argc, char * * argv)
     });
 
     if (packages && fromArgs)
-        throw UsageError("‘-p’ and ‘-E’ are mutually exclusive");
+        throw UsageError("'-p' and '-E' are mutually exclusive");
 
     auto store = openStore();
 
@@ -336,7 +336,7 @@ void mainWrapped(int argc, char * * argv)
 
                 auto drv = getDerivation(state, v, false);
                 if (!drv)
-                    throw Error("the ‘bashInteractive’ attribute in <nixpkgs> did not evaluate to a derivation");
+                    throw Error("the 'bashInteractive' attribute in <nixpkgs> did not evaluate to a derivation");
 
                 pathsToBuild.insert(drv->queryDrvPath());
 
@@ -440,7 +440,7 @@ void mainWrapped(int argc, char * * argv)
 
         execvp(shell.c_str(), argPtrs.data());
 
-        throw SysError("executing shell ‘%s’", shell);
+        throw SysError("executing shell '%s'", shell);
     }
 
     else {
@@ -457,7 +457,7 @@ void mainWrapped(int argc, char * * argv)
 
             auto outputName = drvInfo.queryOutputName();
             if (outputName == "")
-                throw Error("derivation ‘%s’ lacks an ‘outputName’ attribute", drvPath);
+                throw Error("derivation '%s' lacks an 'outputName' attribute", drvPath);
 
             pathsToBuild.insert(drvPath + "!" + outputName);
 
diff --git a/src/nix-channel/nix-channel.cc b/src/nix-channel/nix-channel.cc
index f2742bc3bbda..370f216abccd 100755
--- a/src/nix-channel/nix-channel.cc
+++ b/src/nix-channel/nix-channel.cc
@@ -35,7 +35,7 @@ static void writeChannels()
 {
     auto channelsFD = AutoCloseFD{open(channelsList.c_str(), O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC, 0644)};
     if (!channelsFD)
-        throw SysError(format("opening ‘%1%’ for writing") % channelsList);
+        throw SysError(format("opening '%1%' for writing") % channelsList);
     for (const auto & channel : channels)
         writeFull(channelsFD.get(), channel.second + " " + channel.first + "\n");
 }
@@ -44,9 +44,9 @@ static void writeChannels()
 static void addChannel(const string & url, const string & name)
 {
     if (!regex_search(url, std::regex("^(file|http|https)://")))
-        throw Error(format("invalid channel URL ‘%1%’") % url);
+        throw Error(format("invalid channel URL '%1%'") % url);
     if (!regex_search(name, std::regex("^[a-zA-Z0-9_][a-zA-Z0-9_\\.-]*$")))
-        throw Error(format("invalid channel identifier ‘%1%’") % name);
+        throw Error(format("invalid channel identifier '%1%'") % name);
     readChannels();
     channels[name] = url;
     writeChannels();
@@ -218,7 +218,7 @@ int main(int argc, char ** argv)
                 throw UsageError("no command specified");
             case cAdd:
                 if (args.size() < 1 || args.size() > 2)
-                    throw UsageError("‘--add’ requires one or two arguments");
+                    throw UsageError("'--add' requires one or two arguments");
                 {
                 auto url = args[0];
                 auto name = string{};
@@ -234,12 +234,12 @@ int main(int argc, char ** argv)
                 break;
             case cRemove:
                 if (args.size() != 1)
-                    throw UsageError("‘--remove’ requires one argument");
+                    throw UsageError("'--remove' requires one argument");
                 removeChannel(args[0]);
                 break;
             case cList:
                 if (!args.empty())
-                    throw UsageError("‘--list’ expects no arguments");
+                    throw UsageError("'--list' expects no arguments");
                 readChannels();
                 for (const auto & channel : channels)
                     std::cout << channel.first << ' ' << channel.second << '\n';
@@ -249,7 +249,7 @@ int main(int argc, char ** argv)
                 break;
             case cRollback:
                 if (args.size() > 1)
-                    throw UsageError("‘--rollback’ has at most one argument");
+                    throw UsageError("'--rollback' has at most one argument");
                 auto envArgs = Strings{"--profile", profile};
                 if (args.size() == 1) {
                     envArgs.push_back("--switch-generation");
diff --git a/src/nix-copy-closure/nix-copy-closure.cc b/src/nix-copy-closure/nix-copy-closure.cc
index 0c69bd413569..861fc2e5cd64 100755
--- a/src/nix-copy-closure/nix-copy-closure.cc
+++ b/src/nix-copy-closure/nix-copy-closure.cc
@@ -23,7 +23,7 @@ int main(int argc, char ** argv)
                 printVersion("nix-copy-closure");
             else if (*arg == "--gzip" || *arg == "--bzip2" || *arg == "--xz") {
                 if (*arg != "--gzip")
-                    printMsg(lvlError, format("Warning: ‘%1%’ is not implemented, falling back to gzip") % *arg);
+                    printMsg(lvlError, format("Warning: '%1%' is not implemented, falling back to gzip") % *arg);
                 gzip = true;
             } else if (*arg == "--from")
                 toMode = false;
@@ -32,7 +32,7 @@ int main(int argc, char ** argv)
             else if (*arg == "--include-outputs")
                 includeOutputs = true;
             else if (*arg == "--show-progress")
-                printMsg(lvlError, "Warning: ‘--show-progress’ is not implemented");
+                printMsg(lvlError, "Warning: '--show-progress' is not implemented");
             else if (*arg == "--dry-run")
                 dryRun = true;
             else if (*arg == "--use-substitutes" || *arg == "-s")
diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc
index b029b92db15c..2b223c882647 100644
--- a/src/nix-daemon/nix-daemon.cc
+++ b/src/nix-daemon/nix-daemon.cc
@@ -682,7 +682,7 @@ static void processConnection(bool trusted)
         /* Prevent users from doing something very dangerous. */
         if (geteuid() == 0 &&
             querySetting("build-users-group", "") == "")
-            throw Error("if you run ‘nix-daemon’ as root, then you MUST set ‘build-users-group’!");
+            throw Error("if you run 'nix-daemon' as root, then you MUST set 'build-users-group'!");
 #endif
 
         /* Open the store. */
@@ -866,7 +866,7 @@ static void daemonLoop(char * * argv)
         struct sockaddr_un addr;
         addr.sun_family = AF_UNIX;
         if (socketPathRel.size() >= sizeof(addr.sun_path))
-            throw Error(format("socket path ‘%1%’ is too long") % socketPathRel);
+            throw Error(format("socket path '%1%' is too long") % socketPathRel);
         strcpy(addr.sun_path, socketPathRel.c_str());
 
         unlink(socketPath.c_str());
@@ -878,13 +878,13 @@ static void daemonLoop(char * * argv)
         int res = bind(fdSocket.get(), (struct sockaddr *) &addr, sizeof(addr));
         umask(oldMode);
         if (res == -1)
-            throw SysError(format("cannot bind to socket ‘%1%’") % socketPath);
+            throw SysError(format("cannot bind to socket '%1%'") % socketPath);
 
         if (chdir("/") == -1) /* back to the root */
             throw SysError("cannot change current directory");
 
         if (listen(fdSocket.get(), 5) == -1)
-            throw SysError(format("cannot listen on socket ‘%1%’") % socketPath);
+            throw SysError(format("cannot listen on socket '%1%'") % socketPath);
     }
 
     closeOnExec(fdSocket.get());
@@ -923,7 +923,7 @@ static void daemonLoop(char * * argv)
                 trusted = true;
 
             if (!trusted && !matchUser(user, group, allowedUsers))
-                throw Error(format("user ‘%1%’ is not allowed to connect to the Nix daemon") % user);
+                throw Error(format("user '%1%' is not allowed to connect to the Nix daemon") % user);
 
             printInfo(format((string) "accepted connection from pid %1%, user %2%" + (trusted ? " (trusted)" : ""))
                 % (peer.pidKnown ? std::to_string(peer.pid) : "<unknown>")
@@ -998,7 +998,7 @@ int main(int argc, char * * argv)
 
                 auto socketDir = dirOf(socketPath);
                 if (chdir(socketDir.c_str()) == -1)
-                    throw SysError(format("changing to socket directory ‘%1%’") % socketDir);
+                    throw SysError(format("changing to socket directory '%1%'") % socketDir);
 
                 auto socketName = baseNameOf(socketPath);
                 auto addr = sockaddr_un{};
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index 8620cd25574e..94fbc09f6642 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -70,7 +70,7 @@ static string needArg(Strings::iterator & i,
     Strings & args, const string & arg)
 {
     if (i == args.end()) throw UsageError(
-        format("‘%1%’ requires an argument") % arg);
+        format("'%1%' requires an argument") % arg);
     return *i++;
 }
 
@@ -124,7 +124,7 @@ static void getAllExprs(EvalState & state,
             if (hasSuffix(attrName, ".nix"))
                 attrName = string(attrName, 0, attrName.size() - 4);
             if (attrs.find(attrName) != attrs.end()) {
-                printError(format("warning: name collision in input Nix expressions, skipping ‘%1%’") % path2);
+                printError(format("warning: name collision in input Nix expressions, skipping '%1%'") % path2);
                 continue;
             }
             attrs.insert(attrName);
@@ -133,7 +133,7 @@ static void getAllExprs(EvalState & state,
             Value & vArg(*state.allocValue());
             mkString(vArg, path2);
             if (v.attrs->size() == v.attrs->capacity())
-                throw Error(format("too many Nix expressions in directory ‘%1%’") % path);
+                throw Error(format("too many Nix expressions in directory '%1%'") % path);
             mkApp(*state.allocAttr(v, state.symbols.create(attrName)), vFun, vArg);
         }
         else if (S_ISDIR(st.st_mode))
@@ -148,7 +148,7 @@ static void loadSourceExpr(EvalState & state, const Path & path, Value & v)
 {
     struct stat st;
     if (stat(path.c_str(), &st) == -1)
-        throw SysError(format("getting information about ‘%1%’") % path);
+        throw SysError(format("getting information about '%1%'") % path);
 
     if (isNixExpr(path, st)) {
         state.evalFile(path, v);
@@ -226,7 +226,7 @@ static void checkSelectorUse(DrvNames & selectors)
     /* Check that all selectors have been used. */
     for (auto & i : selectors)
         if (i.hits == 0 && i.fullName != "*")
-            throw Error(format("selector ‘%1%’ matches no derivations") % i.fullName);
+            throw Error(format("selector '%1%' matches no derivations") % i.fullName);
 }
 
 
@@ -297,7 +297,7 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems,
             for (auto & j : newest) {
                 if (multiple.find(j.second.first.queryName()) != multiple.end())
                     printInfo(
-                        "warning: there are multiple derivations named ‘%1%’; using the first one",
+                        "warning: there are multiple derivations named '%1%'; using the first one",
                         j.second.first.queryName());
                 matches.push_back(j.second);
             }
@@ -489,13 +489,13 @@ static void installDerivations(Globals & globals,
                 if (!globals.preserveInstalled &&
                     newNames.find(drvName.name) != newNames.end() &&
                     !keep(i))
-                    printInfo("replacing old ‘%s’", i.queryName());
+                    printInfo("replacing old '%s'", i.queryName());
                 else
                     allElems.push_back(i);
             }
 
             for (auto & i : newElems)
-                printInfo("installing ‘%s’", i.queryName());
+                printInfo("installing '%s'", i.queryName());
         }
 
         printMissing(*globals.state, newElems);
@@ -517,7 +517,7 @@ static void opInstall(Globals & globals, Strings opFlags, Strings opArgs)
             globals.preserveInstalled = true;
         else if (arg == "--remove-all" || arg == "-r")
             globals.removeAll = true;
-        else throw UsageError(format("unknown flag ‘%1%’") % arg);
+        else throw UsageError(format("unknown flag '%1%'") % arg);
     }
 
     installDerivations(globals, opArgs, globals.profile);
@@ -597,13 +597,13 @@ static void upgradeDerivations(Globals & globals,
                 {
                     const char * action = compareVersions(drvName.version, bestVersion) <= 0
                         ? "upgrading" : "downgrading";
-                    printInfo("%1% ‘%2%’ to ‘%3%’",
+                    printInfo("%1% '%2%' to '%3%'",
                         action, i.queryName(), bestElem->queryName());
                     newElems.push_back(*bestElem);
                 } else newElems.push_back(i);
 
             } catch (Error & e) {
-                e.addPrefix(fmt("while trying to find an upgrade for ‘%s’:\n", i.queryName()));
+                e.addPrefix(fmt("while trying to find an upgrade for '%s':\n", i.queryName()));
                 throw;
             }
         }
@@ -628,7 +628,7 @@ static void opUpgrade(Globals & globals, Strings opFlags, Strings opArgs)
         else if (arg == "--leq") upgradeType = utLeq;
         else if (arg == "--eq") upgradeType = utEq;
         else if (arg == "--always") upgradeType = utAlways;
-        else throw UsageError(format("unknown flag ‘%1%’") % arg);
+        else throw UsageError(format("unknown flag '%1%'") % arg);
     }
 
     upgradeDerivations(globals, opArgs, upgradeType);
@@ -647,9 +647,9 @@ static void setMetaFlag(EvalState & state, DrvInfo & drv,
 static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)
 {
     if (opFlags.size() > 0)
-        throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
+        throw UsageError(format("unknown flag '%1%'") % opFlags.front());
     if (opArgs.size() < 2)
-        throw UsageError("not enough arguments to ‘--set-flag’");
+        throw UsageError("not enough arguments to '--set-flag'");
 
     Strings::iterator arg = opArgs.begin();
     string flagName = *arg++;
@@ -666,7 +666,7 @@ static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)
             DrvName drvName(i.queryName());
             for (auto & j : selectors)
                 if (j.matches(drvName)) {
-                    printInfo("setting flag on ‘%1%’", i.queryName());
+                    printInfo("setting flag on '%1%'", i.queryName());
                     j.hits++;
                     setMetaFlag(*globals.state, i, flagName, flagValue);
                     break;
@@ -690,7 +690,7 @@ static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
     for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
         string arg = *i++;
         if (parseInstallSourceOptions(globals, i, opFlags, arg)) ;
-        else throw UsageError(format("unknown flag ‘%1%’") % arg);
+        else throw UsageError(format("unknown flag '%1%'") % arg);
     }
 
     DrvInfos elems;
@@ -740,7 +740,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
                 if ((isPath(j) && i.queryOutPath() == globals.state->store->followLinksToStorePath(j))
                     || DrvName(j).matches(drvName))
                 {
-                    printInfo("uninstalling ‘%s’", i.queryName());
+                    printInfo("uninstalling '%s'", i.queryName());
                     found = true;
                     break;
                 }
@@ -758,7 +758,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
 static void opUninstall(Globals & globals, Strings opFlags, Strings opArgs)
 {
     if (opFlags.size() > 0)
-        throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
+        throw UsageError(format("unknown flag '%1%'") % opFlags.front());
     uninstallDerivations(globals, opArgs, globals.profile);
 }
 
@@ -868,7 +868,7 @@ static void queryJSON(Globals & globals, vector<DrvInfo> & elems)
             auto placeholder = metaObj.placeholder(j);
             Value * v = i.queryMeta(j);
             if (!v) {
-                printError("derivation ‘%s’ has invalid meta attribute ‘%s’", i.queryName(), j);
+                printError("derivation '%s' has invalid meta attribute '%s'", i.queryName(), j);
                 placeholder.write(nullptr);
             } else {
                 PathSet context;
@@ -918,7 +918,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
         else if (arg == "--attr" || arg == "-A")
             attrPath = needArg(i, opFlags, arg);
         else
-            throw UsageError(format("unknown flag ‘%1%’") % arg);
+            throw UsageError(format("unknown flag '%1%'") % arg);
     }
 
 
@@ -965,7 +965,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
             try {
                 paths.insert(i.queryOutPath());
             } catch (AssertionError & e) {
-                printMsg(lvlTalkative, "skipping derivation named ‘%s’ which gives an assertion failure", i.queryName());
+                printMsg(lvlTalkative, "skipping derivation named '%s' which gives an assertion failure", i.queryName());
                 i.setFailed();
             }
         validPaths = globals.state->store->queryValidPaths(paths);
@@ -991,7 +991,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
         try {
             if (i.hasFailed()) continue;
 
-            //Activity act(*logger, lvlDebug, format("outputting query result ‘%1%’") % i.attrPath);
+            //Activity act(*logger, lvlDebug, format("outputting query result '%1%'") % i.attrPath);
 
             if (globals.prebuiltOnly &&
                 validPaths.find(i.queryOutPath()) == validPaths.end() &&
@@ -1112,7 +1112,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
                             attrs2["name"] = j;
                             Value * v = i.queryMeta(j);
                             if (!v)
-                                printError("derivation ‘%s’ has invalid meta attribute ‘%s’", i.queryName(), j);
+                                printError("derivation '%s' has invalid meta attribute '%s'", i.queryName(), j);
                             else {
                                 if (v->type == tString) {
                                     attrs2["type"] = "string";
@@ -1163,9 +1163,9 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
             cout.flush();
 
         } catch (AssertionError & e) {
-            printMsg(lvlTalkative, "skipping derivation named ‘%1%’ which gives an assertion failure", i.queryName());
+            printMsg(lvlTalkative, "skipping derivation named '%1%' which gives an assertion failure", i.queryName());
         } catch (Error & e) {
-            e.addPrefix(fmt("while querying the derivation named ‘%1%’:\n", i.queryName()));
+            e.addPrefix(fmt("while querying the derivation named '%1%':\n", i.queryName()));
             throw;
         }
     }
@@ -1177,7 +1177,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
 static void opSwitchProfile(Globals & globals, Strings opFlags, Strings opArgs)
 {
     if (opFlags.size() > 0)
-        throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
+        throw UsageError(format("unknown flag '%1%'") % opFlags.front());
     if (opArgs.size() != 1)
         throw UsageError(format("exactly one argument expected"));
 
@@ -1225,7 +1225,7 @@ static void switchGeneration(Globals & globals, int dstGen)
 static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArgs)
 {
     if (opFlags.size() > 0)
-        throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
+        throw UsageError(format("unknown flag '%1%'") % opFlags.front());
     if (opArgs.size() != 1)
         throw UsageError(format("exactly one argument expected"));
 
@@ -1240,7 +1240,7 @@ static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArg
 static void opRollback(Globals & globals, Strings opFlags, Strings opArgs)
 {
     if (opFlags.size() > 0)
-        throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
+        throw UsageError(format("unknown flag '%1%'") % opFlags.front());
     if (opArgs.size() != 0)
         throw UsageError(format("no arguments expected"));
 
@@ -1251,7 +1251,7 @@ static void opRollback(Globals & globals, Strings opFlags, Strings opArgs)
 static void opListGenerations(Globals & globals, Strings opFlags, Strings opArgs)
 {
     if (opFlags.size() > 0)
-        throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
+        throw UsageError(format("unknown flag '%1%'") % opFlags.front());
     if (opArgs.size() != 0)
         throw UsageError(format("no arguments expected"));
 
@@ -1278,7 +1278,7 @@ static void opListGenerations(Globals & globals, Strings opFlags, Strings opArgs
 static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opArgs)
 {
     if (opFlags.size() > 0)
-        throw UsageError(format("unknown flag ‘%1%’") % opFlags.front());
+        throw UsageError(format("unknown flag '%1%'") % opFlags.front());
 
     if (opArgs.size() == 1 && opArgs.front() == "old") {
         deleteOldGenerations(globals.profile, globals.dryRun);
@@ -1289,7 +1289,7 @@ static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opAr
         for (auto & i : opArgs) {
             unsigned int n;
             if (!string2Int(i, n))
-                throw UsageError(format("invalid generation number ‘%1%’") % i);
+                throw UsageError(format("invalid generation number '%1%'") % i);
             gens.insert(n);
         }
         deleteGenerations(globals.profile, gens, globals.dryRun);
diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc
index df5105f12c2a..7b9a88281171 100644
--- a/src/nix-env/user-env.cc
+++ b/src/nix-env/user-env.cc
@@ -140,7 +140,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
 
         Path lockTokenCur = optimisticLockProfile(profile);
         if (lockToken != lockTokenCur) {
-            printError(format("profile ‘%1%’ changed while we were busy; restarting") % profile);
+            printError(format("profile '%1%' changed while we were busy; restarting") % profile);
             return false;
         }
 
diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc
index 49a14cb64458..2498df0f0d72 100644
--- a/src/nix-instantiate/nix-instantiate.cc
+++ b/src/nix-instantiate/nix-instantiate.cc
@@ -65,7 +65,7 @@ void processExpr(EvalState & state, const Strings & attrPaths,
                 /* What output do we want? */
                 string outputName = i.queryOutputName();
                 if (outputName == "")
-                    throw Error(format("derivation ‘%1%’ lacks an ‘outputName’ attribute ") % drvPath);
+                    throw Error(format("derivation '%1%' lacks an 'outputName' attribute ") % drvPath);
 
                 if (gcRoot == "")
                     printGCWarning();
@@ -164,7 +164,7 @@ int main(int argc, char * * argv)
         if (findFile) {
             for (auto & i : files) {
                 Path p = state.findFile(i);
-                if (p == "") throw Error(format("unable to find ‘%1%’") % i);
+                if (p == "") throw Error(format("unable to find '%1%'") % i);
                 std::cout << p << std::endl;
             }
             return;
diff --git a/src/nix-prefetch-url/nix-prefetch-url.cc b/src/nix-prefetch-url/nix-prefetch-url.cc
index 47e66eaa6513..791a1eeb53cb 100644
--- a/src/nix-prefetch-url/nix-prefetch-url.cc
+++ b/src/nix-prefetch-url/nix-prefetch-url.cc
@@ -29,11 +29,11 @@ string resolveMirrorUri(EvalState & state, string uri)
 
     auto mirrorList = vMirrors.attrs->find(state.symbols.create(mirrorName));
     if (mirrorList == vMirrors.attrs->end())
-        throw Error(format("unknown mirror name ‘%1%’") % mirrorName);
+        throw Error(format("unknown mirror name '%1%'") % mirrorName);
     state.forceList(*mirrorList->value);
 
     if (mirrorList->value->listSize() < 1)
-        throw Error(format("mirror URI ‘%1%’ did not expand to anything") % uri);
+        throw Error(format("mirror URI '%1%' did not expand to anything") % uri);
 
     string mirror = state.forceString(*mirrorList->value->listElems()[0]);
     return mirror + (hasSuffix(mirror, "/") ? "" : "/") + string(s, p + 1);
@@ -65,7 +65,7 @@ int main(int argc, char * * argv)
                 string s = getArg(*arg, arg, end);
                 ht = parseHashType(s);
                 if (ht == htUnknown)
-                    throw UsageError(format("unknown hash type ‘%1%’") % s);
+                    throw UsageError(format("unknown hash type '%1%'") % s);
             }
             else if (*arg == "--print-path")
                 printPath = true;
@@ -113,10 +113,10 @@ int main(int argc, char * * argv)
             /* Extract the URI. */
             auto attr = v.attrs->find(state.symbols.create("urls"));
             if (attr == v.attrs->end())
-                throw Error("attribute set does not contain a ‘urls’ attribute");
+                throw Error("attribute set does not contain a 'urls' attribute");
             state.forceList(*attr->value);
             if (attr->value->listSize() < 1)
-                throw Error("‘urls’ list is empty");
+                throw Error("'urls' list is empty");
             uri = state.forceString(*attr->value->listElems()[0]);
 
             /* Extract the hash mode. */
@@ -138,7 +138,7 @@ int main(int argc, char * * argv)
         if (name.empty())
             name = baseNameOf(uri);
         if (name.empty())
-            throw Error(format("cannot figure out file name for ‘%1%’") % uri);
+            throw Error(format("cannot figure out file name for '%1%'") % uri);
 
         /* If an expected hash is given, the file may already exist in
            the store. */
@@ -189,7 +189,7 @@ int main(int argc, char * * argv)
             hash = unpack ? hashPath(ht, tmpFile).first : hashString(ht, *result.data);
 
             if (expectedHash != Hash(ht) && expectedHash != hash)
-                throw Error(format("hash mismatch for ‘%1%’") % uri);
+                throw Error(format("hash mismatch for '%1%'") % uri);
 
             /* Copy the file to the Nix store. FIXME: if RemoteStore
                implemented addToStoreFromDump() and downloadFile()
@@ -201,7 +201,7 @@ int main(int argc, char * * argv)
         }
 
         if (!printPath)
-            printInfo(format("path is ‘%1%’") % storePath);
+            printInfo(format("path is '%1%'") % storePath);
 
         std::cout << printHash16or32(hash) << std::endl;
         if (printPath)
diff --git a/src/nix-store/dotgraph.cc b/src/nix-store/dotgraph.cc
index 356a82510124..51dedcf0a092 100644
--- a/src/nix-store/dotgraph.cc
+++ b/src/nix-store/dotgraph.cc
@@ -77,7 +77,7 @@ void printClosure(const Path & nePath, const StoreExpr & fs)
 
             ClosureElems::const_iterator elem = fs.closure.elems.find(path);
             if (elem == fs.closure.elems.end())
-                throw Error(format("bad closure, missing path ‘%1%’") % path);
+                throw Error(format("bad closure, missing path '%1%'") % path);
 
             for (StringSet::const_iterator i = elem->second.refs.begin();
                  i != elem->second.refs.end(); ++i)
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 6cea57a76714..1668fdb2d037 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -51,7 +51,7 @@ static Path useDeriver(Path path)
     if (isDerivation(path)) return path;
     Path drvPath = store->queryPathInfo(path)->deriver;
     if (drvPath == "")
-        throw Error(format("deriver of path ‘%1%’ is not known") % path);
+        throw Error(format("deriver of path '%1%' is not known") % path);
     return drvPath;
 }
 
@@ -76,7 +76,7 @@ static PathSet realisePath(Path path, bool build = true)
         for (auto & j : p.second) {
             DerivationOutputs::iterator i = drv.outputs.find(j);
             if (i == drv.outputs.end())
-                throw Error(format("derivation ‘%1%’ does not have an output named ‘%2%’") % p.first % j);
+                throw Error(format("derivation '%1%' does not have an output named '%2%'") % p.first % j);
             Path outPath = i->second.path;
             if (store2) {
                 if (gcRoot == "")
@@ -95,7 +95,7 @@ static PathSet realisePath(Path path, bool build = true)
 
     else {
         if (build) store->ensurePath(path);
-        else if (!store->isValidPath(path)) throw Error(format("path ‘%1%’ does not exist and cannot be created") % path);
+        else if (!store->isValidPath(path)) throw Error(format("path '%1%' does not exist and cannot be created") % path);
         if (store2) {
             if (gcRoot == "")
                 printGCWarning();
@@ -124,7 +124,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
         else if (i == "--check") buildMode = bmCheck;
         else if (i == "--hash") buildMode = bmHash;
         else if (i == "--ignore-unknown") ignoreUnknown = true;
-        else throw UsageError(format("unknown flag ‘%1%’") % i);
+        else throw UsageError(format("unknown flag '%1%'") % i);
 
     Paths paths;
     for (auto & i : opArgs) {
@@ -181,7 +181,7 @@ static void opAddFixed(Strings opFlags, Strings opArgs)
 
     for (auto & i : opFlags)
         if (i == "--recursive") recursive = true;
-        else throw UsageError(format("unknown flag ‘%1%’") % i);
+        else throw UsageError(format("unknown flag '%1%'") % i);
 
     if (opArgs.empty())
         throw UsageError("first argument must be hash algorithm");
@@ -201,10 +201,10 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs)
 
     for (auto i : opFlags)
         if (i == "--recursive") recursive = true;
-        else throw UsageError(format("unknown flag ‘%1%’") % i);
+        else throw UsageError(format("unknown flag '%1%'") % i);
 
     if (opArgs.size() != 3)
-        throw UsageError(format("‘--print-fixed-path’ requires three arguments"));
+        throw UsageError(format("'--print-fixed-path' requires three arguments"));
 
     Strings::iterator i = opArgs.begin();
     HashType hashAlgo = parseHashType(*i++);
@@ -306,9 +306,9 @@ static void opQuery(Strings opFlags, Strings opArgs)
         else if (i == "--use-output" || i == "-u") useOutput = true;
         else if (i == "--force-realise" || i == "--force-realize" || i == "-f") forceRealise = true;
         else if (i == "--include-outputs") includeOutputs = true;
-        else throw UsageError(format("unknown flag ‘%1%’") % i);
+        else throw UsageError(format("unknown flag '%1%'") % i);
         if (prev != qDefault && prev != query)
-            throw UsageError(format("query type ‘%1%’ conflicts with earlier flag") % i);
+            throw UsageError(format("query type '%1%' conflicts with earlier flag") % i);
     }
 
     if (query == qDefault) query = qOutputs;
@@ -366,7 +366,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
                 Derivation drv = store->derivationFromPath(path);
                 StringPairs::iterator j = drv.env.find(bindingName);
                 if (j == drv.env.end())
-                    throw Error(format("derivation ‘%1%’ has no environment binding named ‘%2%’")
+                    throw Error(format("derivation '%1%' has no environment binding named '%2%'")
                         % path % bindingName);
                 cout << format("%1%\n") % j->second;
             }
@@ -452,7 +452,7 @@ static string shellEscape(const string & s)
 static void opPrintEnv(Strings opFlags, Strings opArgs)
 {
     if (!opFlags.empty()) throw UsageError("unknown flag");
-    if (opArgs.size() != 1) throw UsageError("‘--print-env’ requires one derivation store path");
+    if (opArgs.size() != 1) throw UsageError("'--print-env' requires one derivation store path");
 
     Path drvPath = opArgs.front();
     Derivation drv = store->derivationFromPath(drvPath);
@@ -485,7 +485,7 @@ static void opReadLog(Strings opFlags, Strings opArgs)
         auto path = store->followLinksToStorePath(i);
         auto log = store->getBuildLog(path);
         if (!log)
-            throw Error("build log of derivation ‘%s’ is not available", path);
+            throw Error("build log of derivation '%s' is not available", path);
         std::cout << *log;
     }
 }
@@ -543,7 +543,7 @@ static void opRegisterValidity(Strings opFlags, Strings opArgs)
     for (auto & i : opFlags)
         if (i == "--reregister") reregister = true;
         else if (i == "--hash-given") hashGiven = true;
-        else throw UsageError(format("unknown flag ‘%1%’") % i);
+        else throw UsageError(format("unknown flag '%1%'") % i);
 
     if (!opArgs.empty()) throw UsageError("no arguments expected");
 
@@ -557,7 +557,7 @@ static void opCheckValidity(Strings opFlags, Strings opArgs)
 
     for (auto & i : opFlags)
         if (i == "--print-invalid") printInvalid = true;
-        else throw UsageError(format("unknown flag ‘%1%’") % i);
+        else throw UsageError(format("unknown flag '%1%'") % i);
 
     for (auto & i : opArgs) {
         Path path = store->followLinksToStorePath(i);
@@ -565,7 +565,7 @@ static void opCheckValidity(Strings opFlags, Strings opArgs)
             if (printInvalid)
                 cout << format("%1%\n") % path;
             else
-                throw Error(format("path ‘%1%’ is not valid") % path);
+                throw Error(format("path '%1%' is not valid") % path);
         }
     }
 }
@@ -589,7 +589,7 @@ static void opGC(Strings opFlags, Strings opArgs)
             long long maxFreed = getIntArg<long long>(*i, i, opFlags.end(), true);
             options.maxFreed = maxFreed >= 0 ? maxFreed : 0;
         }
-        else throw UsageError(format("bad sub-operation ‘%1%’ in GC") % *i);
+        else throw UsageError(format("bad sub-operation '%1%' in GC") % *i);
 
     if (!opArgs.empty()) throw UsageError("no arguments expected");
 
@@ -620,7 +620,7 @@ static void opDelete(Strings opFlags, Strings opArgs)
 
     for (auto & i : opFlags)
         if (i == "--ignore-liveness") options.ignoreLiveness = true;
-        else throw UsageError(format("unknown flag ‘%1%’") % i);
+        else throw UsageError(format("unknown flag '%1%'") % i);
 
     for (auto & i : opArgs)
         options.pathsToDelete.insert(store->followLinksToStorePath(i));
@@ -659,7 +659,7 @@ static void opRestore(Strings opFlags, Strings opArgs)
 static void opExport(Strings opFlags, Strings opArgs)
 {
     for (auto & i : opFlags)
-        throw UsageError(format("unknown flag ‘%1%’") % i);
+        throw UsageError(format("unknown flag '%1%'") % i);
 
     for (auto & i : opArgs)
         i = store->followLinksToStorePath(i);
@@ -672,7 +672,7 @@ static void opExport(Strings opFlags, Strings opArgs)
 static void opImport(Strings opFlags, Strings opArgs)
 {
     for (auto & i : opFlags)
-        throw UsageError(format("unknown flag ‘%1%’") % i);
+        throw UsageError(format("unknown flag '%1%'") % i);
 
     if (!opArgs.empty()) throw UsageError("no arguments expected");
 
@@ -707,7 +707,7 @@ static void opVerify(Strings opFlags, Strings opArgs)
     for (auto & i : opFlags)
         if (i == "--check-contents") checkContents = true;
         else if (i == "--repair") repair = Repair;
-        else throw UsageError(format("unknown flag ‘%1%’") % i);
+        else throw UsageError(format("unknown flag '%1%'") % i);
 
     if (store->verifyStore(checkContents, repair)) {
         printError("warning: not all errors were fixed");
@@ -726,14 +726,14 @@ static void opVerifyPath(Strings opFlags, Strings opArgs)
 
     for (auto & i : opArgs) {
         Path path = store->followLinksToStorePath(i);
-        printMsg(lvlTalkative, format("checking path ‘%1%’...") % path);
+        printMsg(lvlTalkative, format("checking path '%1%'...") % path);
         auto info = store->queryPathInfo(path);
         HashSink sink(info->narHash.type);
         store->narFromPath(path, sink);
         auto current = sink.finish();
         if (current.first != info->narHash) {
             printError(
-                format("path ‘%1%’ was modified! expected hash ‘%2%’, got ‘%3%’")
+                format("path '%1%' was modified! expected hash '%2%', got '%3%'")
                 % path % info->narHash.to_string() % current.first.to_string());
             status = 1;
         }
@@ -772,7 +772,7 @@ static void opServe(Strings opFlags, Strings opArgs)
     bool writeAllowed = false;
     for (auto & i : opFlags)
         if (i == "--write") writeAllowed = true;
-        else throw UsageError(format("unknown flag ‘%1%’") % i);
+        else throw UsageError(format("unknown flag '%1%'") % i);
 
     if (!opArgs.empty()) throw UsageError("no arguments expected");
 
@@ -942,7 +942,7 @@ static void opServe(Strings opFlags, Strings opArgs)
 static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs)
 {
     for (auto & i : opFlags)
-        throw UsageError(format("unknown flag ‘%1%’") % i);
+        throw UsageError(format("unknown flag '%1%'") % i);
 
     if (opArgs.size() != 3) throw UsageError("three arguments expected");
     auto i = opArgs.begin();
diff --git a/src/nix/cat.cc b/src/nix/cat.cc
index 2405a8cb44ef..a35f640d8840 100644
--- a/src/nix/cat.cc
+++ b/src/nix/cat.cc
@@ -13,9 +13,9 @@ struct MixCat : virtual Args
     {
         auto st = accessor->stat(path);
         if (st.type == FSAccessor::Type::tMissing)
-            throw Error(format("path ‘%1%’ does not exist") % path);
+            throw Error(format("path '%1%' does not exist") % path);
         if (st.type != FSAccessor::Type::tRegular)
-            throw Error(format("path ‘%1%’ is not a regular file") % path);
+            throw Error(format("path '%1%' is not a regular file") % path);
 
         std::cout << accessor->readFile(path);
     }
diff --git a/src/nix/command.cc b/src/nix/command.cc
index 6b608a708eea..e88c834abc50 100644
--- a/src/nix/command.cc
+++ b/src/nix/command.cc
@@ -28,7 +28,7 @@ MultiCommand::MultiCommand(const Commands & _commands)
         assert(!command);
         auto i = commands.find(ss.front());
         if (i == commands.end())
-            throw UsageError(format("‘%1%’ is not a recognised command") % ss.front());
+            throw UsageError(format("'%1%' is not a recognised command") % ss.front());
         command = i->second;
     }});
 }
@@ -55,7 +55,7 @@ void MultiCommand::printHelp(const string & programName, std::ostream & out)
     printTable(out, table);
 
     out << "\n";
-    out << "For full documentation, run ‘man " << programName << "’ or ‘man " << programName << "-<COMMAND>’.\n";
+    out << "For full documentation, run 'man " << programName << "' or 'man " << programName << "-<COMMAND>'.\n";
 }
 
 bool MultiCommand::processFlag(Strings::iterator & pos, Strings::iterator end)
@@ -109,7 +109,7 @@ void StorePathsCommand::run(ref<Store> store)
 
     if (all) {
         if (installables.size())
-            throw UsageError("‘--all’ does not expect arguments");
+            throw UsageError("'--all' does not expect arguments");
         for (auto & p : store->queryAllValidPaths())
             storePaths.push_back(p);
     }
diff --git a/src/nix/command.hh b/src/nix/command.hh
index 536802653819..b159408c3a98 100644
--- a/src/nix/command.hh
+++ b/src/nix/command.hh
@@ -53,12 +53,12 @@ struct Installable
 
     virtual Buildables toBuildable()
     {
-        throw Error("argument ‘%s’ cannot be built", what());
+        throw Error("argument '%s' cannot be built", what());
     }
 
     virtual Value * toValue(EvalState & state)
     {
-        throw Error("argument ‘%s’ cannot be evaluated", what());
+        throw Error("argument '%s' cannot be evaluated", what());
     }
 };
 
diff --git a/src/nix/copy.cc b/src/nix/copy.cc
index b2165cb8f85c..9f1a80d07bea 100644
--- a/src/nix/copy.cc
+++ b/src/nix/copy.cc
@@ -46,7 +46,7 @@ struct CmdCopy : StorePathsCommand
     void run(ref<Store> srcStore, Paths storePaths) override
     {
         if (srcUri.empty() && dstUri.empty())
-            throw UsageError("you must pass ‘--from’ and/or ‘--to’");
+            throw UsageError("you must pass '--from' and/or '--to'");
 
         ref<Store> dstStore = dstUri.empty() ? openStore() : openStore(dstUri);
 
diff --git a/src/nix/edit.cc b/src/nix/edit.cc
index 632b555771c2..5cf9c7200d03 100644
--- a/src/nix/edit.cc
+++ b/src/nix/edit.cc
@@ -41,7 +41,7 @@ struct CmdEdit : InstallablesCommand
                 auto dummyArgs = state->allocBindings(0);
                 v2 = findAlongAttrPath(*state, "meta.position", *dummyArgs, *v);
             } catch (Error &) {
-                throw Error("package ‘%s’ has no source location information", i->what());
+                throw Error("package '%s' has no source location information", i->what());
             }
 
             auto pos = state->forceString(*v2);
@@ -49,7 +49,7 @@ struct CmdEdit : InstallablesCommand
 
             auto colon = pos.rfind(':');
             if (colon == std::string::npos)
-                throw Error("cannot parse meta.position attribute ‘%s’", pos);
+                throw Error("cannot parse meta.position attribute '%s'", pos);
 
             std::string filename(pos, 0, colon);
             int lineno = std::stoi(std::string(pos, colon + 1));
@@ -67,7 +67,7 @@ struct CmdEdit : InstallablesCommand
 
             execvp(editor.c_str(), stringsToCharPtrs(args).data());
 
-            throw SysError("cannot run editor ‘%s’", editor);
+            throw SysError("cannot run editor '%s'", editor);
         }
     }
 };
diff --git a/src/nix/hash.cc b/src/nix/hash.cc
index 98de88971127..923dabb103d3 100644
--- a/src/nix/hash.cc
+++ b/src/nix/hash.cc
@@ -109,7 +109,7 @@ static int compatNixHash(int argc, char * * argv)
             string s = getArg(*arg, arg, end);
             ht = parseHashType(s);
             if (ht == htUnknown)
-                throw UsageError(format("unknown hash type ‘%1%’") % s);
+                throw UsageError(format("unknown hash type '%1%'") % s);
         }
         else if (*arg == "--to-base16") op = opTo16;
         else if (*arg == "--to-base32") op = opTo32;
diff --git a/src/nix/installables.cc b/src/nix/installables.cc
index 59162fdc1163..54c9f7841fe0 100644
--- a/src/nix/installables.cc
+++ b/src/nix/installables.cc
@@ -221,7 +221,7 @@ std::vector<std::shared_ptr<Installable>> InstallablesCommand::parseInstallables
             result.push_back(std::make_shared<InstallableAttrPath>(*this, s));
 
         else
-            throw UsageError("don't know what to do with argument ‘%s’", s);
+            throw UsageError("don't know what to do with argument '%s'", s);
     }
 
     return result;
diff --git a/src/nix/log.cc b/src/nix/log.cc
index 62ae6b8facf0..0fb45c1454cb 100644
--- a/src/nix/log.cc
+++ b/src/nix/log.cc
@@ -39,7 +39,7 @@ struct CmdLog : InstallablesCommand
                     break;
                 }
                 if (!found)
-                    throw Error("build log of path ‘%s’ is not available", path);
+                    throw Error("build log of path '%s' is not available", path);
             }
         }
     }
diff --git a/src/nix/ls.cc b/src/nix/ls.cc
index 417b7b421b1c..a08e4c42c670 100644
--- a/src/nix/ls.cc
+++ b/src/nix/ls.cc
@@ -67,7 +67,7 @@ struct MixLs : virtual Args
 
         auto st = accessor->stat(path);
         if (st.type == FSAccessor::Type::tMissing)
-            throw Error(format("path ‘%1%’ does not exist") % path);
+            throw Error(format("path '%1%' does not exist") % path);
         doPath(st, path,
             st.type == FSAccessor::Type::tDirectory ? "." : baseNameOf(path),
             showDirectory);
diff --git a/src/nix/main.cc b/src/nix/main.cc
index 4b51c5ee14a0..7fece5b87b0b 100644
--- a/src/nix/main.cc
+++ b/src/nix/main.cc
@@ -39,9 +39,9 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
         Args::printFlags(out);
         std::cout <<
             "\n"
-            "In addition, most configuration settings can be overriden using ‘--<name> <value>’.\n"
-            "Boolean settings can be overriden using ‘--<name>’ or ‘--no-<name>’. See ‘nix\n"
-            "--help-config’ for a list of configuration settings.\n";
+            "In addition, most configuration settings can be overriden using '--<name> <value>'.\n"
+            "Boolean settings can be overriden using '--<name>' or '--no-<name>'. See 'nix\n"
+            "--help-config' for a list of configuration settings.\n";
     }
 
     void showHelpAndExit()
diff --git a/src/nix/repl.cc b/src/nix/repl.cc
index 7d5b8f4668af..e5a597addf4b 100644
--- a/src/nix/repl.cc
+++ b/src/nix/repl.cc
@@ -397,7 +397,7 @@ bool NixRepl::processLine(string line)
         return false;
 
     else if (command != "")
-        throw Error(format("unknown command ‘%1%’") % command);
+        throw Error(format("unknown command '%1%'") % command);
 
     else {
         size_t p = line.find('=');
@@ -460,7 +460,7 @@ void NixRepl::reloadFiles()
     for (auto & i : old) {
         if (!first) std::cout << std::endl;
         first = false;
-        std::cout << format("Loading ‘%1%’...") % i << std::endl;
+        std::cout << format("Loading '%1%'...") % i << std::endl;
         loadFile(i);
     }
 }
diff --git a/src/nix/run.cc b/src/nix/run.cc
index 49fe4e7a0c6d..f67fd637c4fa 100644
--- a/src/nix/run.cc
+++ b/src/nix/run.cc
@@ -57,15 +57,15 @@ struct CmdRun : InstallablesCommand
                 createDirs(tmpDir + store->storeDir);
 
                 if (mount(store2->realStoreDir.c_str(), (tmpDir + store->storeDir).c_str(), "", MS_BIND, 0) == -1)
-                    throw SysError(format("mounting ‘%s’ on ‘%s’") % store2->realStoreDir % store->storeDir);
+                    throw SysError(format("mounting '%s' on '%s'") % store2->realStoreDir % store->storeDir);
 
                 for (auto entry : readDirectory("/")) {
                     Path dst = tmpDir + "/" + entry.name;
                     if (pathExists(dst)) continue;
                     if (mkdir(dst.c_str(), 0700) == -1)
-                        throw SysError(format("creating directory ‘%s’") % dst);
+                        throw SysError(format("creating directory '%s'") % dst);
                     if (mount(("/" + entry.name).c_str(), dst.c_str(), "", MS_BIND | MS_REC, 0) == -1)
-                        throw SysError(format("mounting ‘%s’ on ‘%s’") %  ("/" + entry.name) % dst);
+                        throw SysError(format("mounting '%s' on '%s'") %  ("/" + entry.name) % dst);
                 }
 
                 char * cwd = getcwd(0, 0);
@@ -73,19 +73,19 @@ struct CmdRun : InstallablesCommand
                 Finally freeCwd([&]() { free(cwd); });
 
                 if (chroot(tmpDir.c_str()) == -1)
-                    throw SysError(format("chrooting into ‘%s’") % tmpDir);
+                    throw SysError(format("chrooting into '%s'") % tmpDir);
 
                 if (chdir(cwd) == -1)
-                    throw SysError(format("chdir to ‘%s’ in chroot") % cwd);
+                    throw SysError(format("chdir to '%s' in chroot") % cwd);
             } else
                 if (mount(store2->realStoreDir.c_str(), store->storeDir.c_str(), "", MS_BIND, 0) == -1)
-                    throw SysError(format("mounting ‘%s’ on ‘%s’") % store2->realStoreDir % store->storeDir);
+                    throw SysError(format("mounting '%s' on '%s'") % store2->realStoreDir % store->storeDir);
 
             writeFile("/proc/self/setgroups", "deny");
             writeFile("/proc/self/uid_map", (format("%d %d %d") % uid % uid % 1).str());
             writeFile("/proc/self/gid_map", (format("%d %d %d") % gid % gid % 1).str());
 #else
-            throw Error(format("mounting the Nix store on ‘%s’ is not supported on this platform") % store->storeDir);
+            throw Error(format("mounting the Nix store on '%s' is not supported on this platform") % store->storeDir);
 #endif
         }
 
@@ -97,7 +97,7 @@ struct CmdRun : InstallablesCommand
         setenv("PATH", concatStringsSep(":", unixPath).c_str(), 1);
 
         if (execlp("bash", "bash", nullptr) == -1)
-            throw SysError("unable to exec ‘bash’");
+            throw SysError("unable to exec 'bash'");
     }
 };
 
diff --git a/src/nix/search.cc b/src/nix/search.cc
index d3e018876a09..5bb376f8f2d1 100644
--- a/src/nix/search.cc
+++ b/src/nix/search.cc
@@ -76,7 +76,7 @@ struct CmdSearch : SourceExprCommand, MixJSON
         std::function<void(Value *, std::string, bool, JSONObject *)> doExpr;
 
         doExpr = [&](Value * v, std::string attrPath, bool toplevel, JSONObject * cache) {
-            debug("at attribute ‘%s’", attrPath);
+            debug("at attribute '%s'", attrPath);
 
             try {
 
@@ -152,7 +152,7 @@ struct CmdSearch : SourceExprCommand, MixJSON
                         auto attrs = v->attrs;
                         Bindings::iterator j = attrs->find(sRecurse);
                         if (j == attrs->end() || !state->forceBool(*j->value, *j->pos)) {
-                            debug("skip attribute ‘%s’", attrPath);
+                            debug("skip attribute '%s'", attrPath);
                             return;
                         }
                     }
@@ -175,7 +175,7 @@ struct CmdSearch : SourceExprCommand, MixJSON
             } catch (AssertionError & e) {
             } catch (Error & e) {
                 if (!toplevel) {
-                    e.addPrefix(fmt("While evaluating the attribute ‘%s’:\n", attrPath));
+                    e.addPrefix(fmt("While evaluating the attribute '%s':\n", attrPath));
                     throw;
                 }
             }
@@ -203,7 +203,7 @@ struct CmdSearch : SourceExprCommand, MixJSON
             doExpr(getSourceExpr(*state), "", true, cache.get());
 
             if (rename(tmpFile.c_str(), jsonCacheFileName.c_str()) == -1)
-                throw SysError("cannot rename ‘%s’ to ‘%s’", tmpFile, jsonCacheFileName);
+                throw SysError("cannot rename '%s' to '%s'", tmpFile, jsonCacheFileName);
         }
     }
 };
diff --git a/src/nix/sigs.cc b/src/nix/sigs.cc
index 0e3eb9b694b4..992ff742835e 100644
--- a/src/nix/sigs.cc
+++ b/src/nix/sigs.cc
@@ -35,7 +35,7 @@ struct CmdCopySigs : StorePathsCommand
     void run(ref<Store> store, Paths storePaths) override
     {
         if (substituterUris.empty())
-            throw UsageError("you must specify at least one substituter using ‘-s’");
+            throw UsageError("you must specify at least one substituter using '-s'");
 
         // FIXME: factor out commonality with MixVerify.
         std::vector<ref<Store>> substituters;
@@ -50,7 +50,7 @@ struct CmdCopySigs : StorePathsCommand
         //logger->setExpected(doneLabel, storePaths.size());
 
         auto doPath = [&](const Path & storePath) {
-            //Activity act(*logger, lvlInfo, format("getting signatures for ‘%s’") % storePath);
+            //Activity act(*logger, lvlInfo, format("getting signatures for '%s'") % storePath);
 
             checkInterrupt();
 
@@ -117,7 +117,7 @@ struct CmdSignPaths : StorePathsCommand
     void run(ref<Store> store, Paths storePaths) override
     {
         if (secretKeyFile.empty())
-            throw UsageError("you must specify a secret key file using ‘-k’");
+            throw UsageError("you must specify a secret key file using '-k'");
 
         SecretKey secretKey(readFile(secretKeyFile));
 
diff --git a/src/nix/verify.cc b/src/nix/verify.cc
index 973f60a74ffe..0d9739314b53 100644
--- a/src/nix/verify.cc
+++ b/src/nix/verify.cc
@@ -78,7 +78,7 @@ struct CmdVerify : StorePathsCommand
             try {
                 checkInterrupt();
 
-                //Activity act(*logger, lvlInfo, format("checking ‘%s’") % storePath);
+                //Activity act(*logger, lvlInfo, format("checking '%s'") % storePath);
 
                 auto info = store->queryPathInfo(storePath);
 
@@ -93,7 +93,7 @@ struct CmdVerify : StorePathsCommand
                         //logger->incProgress(corruptedLabel);
                         corrupted = 1;
                         printError(
-                            format("path ‘%s’ was modified! expected hash ‘%s’, got ‘%s’")
+                            format("path '%s' was modified! expected hash '%s', got '%s'")
                             % info->path % info->narHash.to_string() % hash.first.to_string());
                     }
 
@@ -144,7 +144,7 @@ struct CmdVerify : StorePathsCommand
                     if (!good) {
                         //logger->incProgress(untrustedLabel);
                         untrusted++;
-                        printError(format("path ‘%s’ is untrusted") % info->path);
+                        printError(format("path '%s' is untrusted") % info->path);
                     }
 
                 }
diff --git a/src/resolve-system-dependencies/resolve-system-dependencies.cc b/src/resolve-system-dependencies/resolve-system-dependencies.cc
index 63e557ec5f1c..e02cfc03ec97 100644
--- a/src/resolve-system-dependencies/resolve-system-dependencies.cc
+++ b/src/resolve-system-dependencies/resolve-system-dependencies.cc
@@ -32,25 +32,25 @@ std::set<std::string> runResolver(const Path & filename)
 {
     AutoCloseFD fd = open(filename.c_str(), O_RDONLY);
     if (!fd)
-        throw SysError("opening ‘%s’", filename);
+        throw SysError("opening '%s'", filename);
 
     struct stat st;
     if (fstat(fd.get(), &st))
-        throw SysError("statting ‘%s’", filename);
+        throw SysError("statting '%s'", filename);
 
     if (!S_ISREG(st.st_mode)) {
-        printError("file ‘%s’ is not a regular file", filename);
+        printError("file '%s' is not a regular file", filename);
         return {};
     }
 
     if (st.st_size < sizeof(mach_header_64)) {
-        printError("file ‘%s’ is too short for a MACH binary", filename);
+        printError("file '%s' is too short for a MACH binary", filename);
         return {};
     }
 
     char* obj = (char*) mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd.get(), 0);
     if (!obj)
-        throw SysError("mmapping ‘%s’", filename);
+        throw SysError("mmapping '%s'", filename);
 
     ptrdiff_t mach64_offset = 0;
 
@@ -66,13 +66,13 @@ std::set<std::string> runResolver(const Path & filename)
             }
         }
         if (mach64_offset == 0) {
-            printError(format("Could not find any mach64 blobs in file ‘%1%’, continuing...") % filename);
+            printError(format("Could not find any mach64 blobs in file '%1%', continuing...") % filename);
             return {};
         }
     } else if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64) {
         mach64_offset = 0;
     } else {
-        printError(format("Object file has unknown magic number ‘%1%’, skipping it...") % magic);
+        printError(format("Object file has unknown magic number '%1%', skipping it...") % magic);
         return {};
     }
 
@@ -101,7 +101,7 @@ bool isSymlink(const Path & path)
 {
     struct stat st;
     if (lstat(path.c_str(), &st) == -1)
-        throw SysError("getting attributes of path ‘%1%’", path);
+        throw SysError("getting attributes of path '%1%'", path);
 
     return S_ISLNK(st.st_mode);
 }
diff --git a/tests/timeout.nix b/tests/timeout.nix
index e18d717eff1f..d0e949e31498 100644
--- a/tests/timeout.nix
+++ b/tests/timeout.nix
@@ -6,7 +6,7 @@ with import ./config.nix;
     name = "timeout";
     buildCommand = ''
       touch $out
-      echo "‘timeout’ builder entering an infinite loop"
+      echo "'timeout' builder entering an infinite loop"
       while true ; do echo -n .; done
     '';
   };
diff --git a/tests/timeout.sh b/tests/timeout.sh
index 77b227e89ba5..2b864b86dca4 100644
--- a/tests/timeout.sh
+++ b/tests/timeout.sh
@@ -5,7 +5,7 @@ source common.sh
 failed=0
 messages="`nix-build -Q timeout.nix -A infiniteLoop --timeout 2 2>&1 || failed=1`"
 if [ $failed -ne 0 ]; then
-    echo "error: ‘nix-store’ succeeded; should have timed out"
+    echo "error: 'nix-store' succeeded; should have timed out"
     exit 1
 fi