Move escapeString
to its own file
Change-Id: Ie5c954ec73c46c9d3c679ef99a83a29cc7a08352
This commit is contained in:
parent
5a54b0a20c
commit
a5a25894c1
10 changed files with 142 additions and 74 deletions
|
@ -4,6 +4,7 @@
|
|||
#include "symbol-table.hh"
|
||||
#include "util.hh"
|
||||
#include "print.hh"
|
||||
#include "escape-string.hh"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
|
@ -36,7 +37,7 @@ void ExprFloat::show(const SymbolTable & symbols, std::ostream & str) const
|
|||
|
||||
void ExprString::show(const SymbolTable & symbols, std::ostream & str) const
|
||||
{
|
||||
printLiteralString(str, s);
|
||||
escapeString(str, s);
|
||||
}
|
||||
|
||||
void ExprPath::show(const SymbolTable & symbols, std::ostream & str) const
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "print.hh"
|
||||
#include "eval.hh"
|
||||
#include "signals.hh"
|
||||
#include "escape-string.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
@ -27,7 +28,7 @@ void printAmbiguous(
|
|||
printLiteralBool(str, v.boolean);
|
||||
break;
|
||||
case nString:
|
||||
printLiteralString(str, v.string.s);
|
||||
escapeString(str, v.string.s);
|
||||
break;
|
||||
case nPath:
|
||||
str << v.path().to_string(); // !!! escaping?
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <span>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "escape-string.hh"
|
||||
#include "print.hh"
|
||||
#include "ansicolor.hh"
|
||||
#include "store-api.hh"
|
||||
|
@ -11,57 +12,6 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
void printElided(
|
||||
std::ostream & output,
|
||||
unsigned int value,
|
||||
const std::string_view single,
|
||||
const std::string_view plural,
|
||||
bool ansiColors)
|
||||
{
|
||||
if (ansiColors)
|
||||
output << ANSI_FAINT;
|
||||
output << "«";
|
||||
pluralize(output, value, single, plural);
|
||||
output << " elided»";
|
||||
if (ansiColors)
|
||||
output << ANSI_NORMAL;
|
||||
}
|
||||
|
||||
|
||||
std::ostream &
|
||||
printLiteralString(std::ostream & str, const std::string_view string, size_t maxLength, bool ansiColors)
|
||||
{
|
||||
size_t charsPrinted = 0;
|
||||
if (ansiColors)
|
||||
str << ANSI_MAGENTA;
|
||||
str << "\"";
|
||||
for (auto i = string.begin(); i != string.end(); ++i) {
|
||||
if (charsPrinted >= maxLength) {
|
||||
str << "\" ";
|
||||
printElided(str, string.length() - charsPrinted, "byte", "bytes", ansiColors);
|
||||
return str;
|
||||
}
|
||||
|
||||
if (*i == '\"' || *i == '\\') str << "\\" << *i;
|
||||
else if (*i == '\n') str << "\\n";
|
||||
else if (*i == '\r') str << "\\r";
|
||||
else if (*i == '\t') str << "\\t";
|
||||
else if (*i == '$' && *(i+1) == '{') str << "\\" << *i;
|
||||
else str << *i;
|
||||
charsPrinted++;
|
||||
}
|
||||
str << "\"";
|
||||
if (ansiColors)
|
||||
str << ANSI_NORMAL;
|
||||
return str;
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
printLiteralString(std::ostream & str, const std::string_view string)
|
||||
{
|
||||
return printLiteralString(str, string, std::numeric_limits<size_t>::max(), false);
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
printLiteralBool(std::ostream & str, bool boolean)
|
||||
{
|
||||
|
@ -93,7 +43,7 @@ printIdentifier(std::ostream & str, std::string_view s) {
|
|||
else {
|
||||
char c = s[0];
|
||||
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')) {
|
||||
printLiteralString(str, s);
|
||||
escapeString(str, s);
|
||||
return str;
|
||||
}
|
||||
for (auto c : s)
|
||||
|
@ -101,7 +51,7 @@ printIdentifier(std::ostream & str, std::string_view s) {
|
|||
(c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9') ||
|
||||
c == '_' || c == '\'' || c == '-')) {
|
||||
printLiteralString(str, s);
|
||||
escapeString(str, s);
|
||||
return str;
|
||||
}
|
||||
str << s;
|
||||
|
@ -129,7 +79,7 @@ printAttributeName(std::ostream & str, std::string_view name) {
|
|||
if (isVarName(name))
|
||||
str << name;
|
||||
else
|
||||
printLiteralString(str, name);
|
||||
escapeString(str, name);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -248,7 +198,13 @@ private:
|
|||
|
||||
void printString(Value & v)
|
||||
{
|
||||
printLiteralString(output, v.string.s, options.maxStringLength, options.ansiColors);
|
||||
// NB: Non-printing characters won't be escaped.
|
||||
escapeString(
|
||||
output,
|
||||
v.string.s,
|
||||
options.maxStringLength,
|
||||
options.ansiColors
|
||||
);
|
||||
}
|
||||
|
||||
void printPath(Value & v)
|
||||
|
|
|
@ -11,28 +11,13 @@
|
|||
|
||||
#include "fmt.hh"
|
||||
#include "print-options.hh"
|
||||
#include "print-elided.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
class EvalState;
|
||||
struct Value;
|
||||
|
||||
/**
|
||||
* Print a string as a Nix string literal.
|
||||
*
|
||||
* Quotes and fairly minimal escaping are added.
|
||||
*
|
||||
* @param o The output stream to print to
|
||||
* @param s The logical string
|
||||
*/
|
||||
std::ostream & printLiteralString(std::ostream & o, std::string_view s);
|
||||
inline std::ostream & printLiteralString(std::ostream & o, const char * s) {
|
||||
return printLiteralString(o, std::string_view(s));
|
||||
}
|
||||
inline std::ostream & printLiteralString(std::ostream & o, const std::string & s) {
|
||||
return printLiteralString(o, std::string_view(s));
|
||||
}
|
||||
|
||||
/** Print `true` or `false`. */
|
||||
std::ostream & printLiteralBool(std::ostream & o, bool b);
|
||||
|
||||
|
|
40
src/libutil/escape-string.cc
Normal file
40
src/libutil/escape-string.cc
Normal file
|
@ -0,0 +1,40 @@
|
|||
#include <iomanip>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "ansicolor.hh"
|
||||
#include "escape-char.hh"
|
||||
#include "english.hh"
|
||||
#include "escape-string.hh"
|
||||
#include "print-elided.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
std::ostream &
|
||||
escapeString(std::ostream & str, const std::string_view string, size_t maxLength, bool ansiColors)
|
||||
{
|
||||
size_t charsPrinted = 0;
|
||||
if (ansiColors)
|
||||
str << ANSI_MAGENTA;
|
||||
str << "\"";
|
||||
for (auto i = string.begin(); i != string.end(); ++i) {
|
||||
if (charsPrinted >= maxLength) {
|
||||
str << "\" ";
|
||||
printElided(str, string.length() - charsPrinted, "byte", "bytes", ansiColors);
|
||||
return str;
|
||||
}
|
||||
if (*i == '\"' || *i == '\\') str << "\\" << *i;
|
||||
else if (*i == '\n') str << "\\n";
|
||||
else if (*i == '\r') str << "\\r";
|
||||
else if (*i == '\t') str << "\\t";
|
||||
else if (*i == '$' && *(i+1) == '{') str << "\\" << *i;
|
||||
else str << *i;
|
||||
charsPrinted++;
|
||||
}
|
||||
str << "\"";
|
||||
if (ansiColors)
|
||||
str << ANSI_NORMAL;
|
||||
return str;
|
||||
}
|
||||
|
||||
}; // namespace nix
|
34
src/libutil/escape-string.hh
Normal file
34
src/libutil/escape-string.hh
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
#include <ostream>
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* Escape a string for output.
|
||||
*
|
||||
* With default optional parameters, the output string will round-trip through
|
||||
* the Nix evaluator (i.e. you can copy/paste this function's output into the
|
||||
* REPL and have it evaluate as the string that got passed in).
|
||||
*
|
||||
* With non-default optional parameters, the output string will be
|
||||
* human-readable.
|
||||
*/
|
||||
|
||||
std::ostream & escapeString(
|
||||
std::ostream & output,
|
||||
const std::string_view string,
|
||||
size_t maxLength = std::numeric_limits<size_t>::max(),
|
||||
bool ansiColors = false
|
||||
);
|
||||
|
||||
/**
|
||||
* Escape a string for output, writing the escaped result to a new string.
|
||||
*/
|
||||
inline std::ostream & escapeString(std::ostream & output, const char * string)
|
||||
{
|
||||
return escapeString(output, std::string_view(string));
|
||||
}
|
||||
|
||||
} // namespace nix
|
|
@ -9,6 +9,7 @@ libutil_sources = files(
|
|||
'english.cc',
|
||||
'error.cc',
|
||||
'escape-char.cc',
|
||||
'escape-string.cc',
|
||||
'exit.cc',
|
||||
'experimental-features.cc',
|
||||
'filesystem.cc',
|
||||
|
@ -19,6 +20,7 @@ libutil_sources = files(
|
|||
'logging.cc',
|
||||
'namespaces.cc',
|
||||
'position.cc',
|
||||
'print-elided.cc',
|
||||
'references.cc',
|
||||
'serialise.cc',
|
||||
'shlex.cc',
|
||||
|
@ -52,6 +54,7 @@ libutil_headers = files(
|
|||
'english.hh',
|
||||
'error.hh',
|
||||
'escape-char.hh',
|
||||
'escape-string.hh',
|
||||
'exit.hh',
|
||||
'experimental-features.hh',
|
||||
'experimental-features-json.hh',
|
||||
|
@ -70,6 +73,7 @@ libutil_headers = files(
|
|||
'namespaces.hh',
|
||||
'pool.hh',
|
||||
'position.hh',
|
||||
'print-elided.hh',
|
||||
'ref.hh',
|
||||
'references.hh',
|
||||
'regex-combinators.hh',
|
||||
|
|
23
src/libutil/print-elided.cc
Normal file
23
src/libutil/print-elided.cc
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "print-elided.hh"
|
||||
#include "ansicolor.hh"
|
||||
#include "english.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
void printElided(
|
||||
std::ostream & output,
|
||||
unsigned int value,
|
||||
const std::string_view single,
|
||||
const std::string_view plural,
|
||||
bool ansiColors)
|
||||
{
|
||||
if (ansiColors)
|
||||
output << ANSI_FAINT;
|
||||
output << "«";
|
||||
pluralize(output, value, single, plural);
|
||||
output << " elided»";
|
||||
if (ansiColors)
|
||||
output << ANSI_NORMAL;
|
||||
}
|
||||
|
||||
}
|
23
src/libutil/print-elided.hh
Normal file
23
src/libutil/print-elided.hh
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* Print an `«... elided»` placeholder.
|
||||
*
|
||||
* Arguments are forwarded to `pluralize`.
|
||||
*
|
||||
* If `ansiColors` is set, the output will be wrapped in `ANSI_FAINT`.
|
||||
*/
|
||||
void printElided(
|
||||
std::ostream & output,
|
||||
unsigned int value,
|
||||
const std::string_view single,
|
||||
const std::string_view plural,
|
||||
bool ansiColors
|
||||
);
|
||||
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
#include "cli-literate-parser.hh"
|
||||
#include "escape-string.hh"
|
||||
#include "libexpr/print.hh"
|
||||
#include "escape-char.hh"
|
||||
#include "types.hh"
|
||||
|
@ -41,7 +42,7 @@ auto CLILiterateParser::Node::print() const -> std::string
|
|||
s << "Output ";
|
||||
break;
|
||||
}
|
||||
printLiteralString(s, this->text);
|
||||
escapeString(s, this->text);
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue