std::string quoteArg(const std::string &arg) { if (!needsQuotes(arg)) return arg; std::string quotedArg; quotedArg.reserve(3 + 2 * arg.size()); // worst case quotedArg.push_back('"'); const size_t argLength = arg.length(); for (size_t i = 0; i < argLength; ++i) { if (arg[i] == '"') { // Escape all preceding backslashes (if any). // Note that we *don't* need to escape runs of backslashes that don't // precede a double quote! See MSDN: // http://msdn.microsoft.com/en-us/library/17w5ykft%28v=vs.85%29.aspx quotedArg.append(countPrecedingBackslashes(arg, i), '\\'); // Escape the double quote. quotedArg.push_back('\\'); } quotedArg.push_back(arg[i]); } // Make sure our final double quote doesn't get escaped by a trailing // backslash. quotedArg.append(countPrecedingBackslashes(arg, argLength), '\\'); quotedArg.push_back('"'); return quotedArg; }
bool ScalarTraits<uuid_t>::mustQuote(StringRef S) { return needsQuotes(S); }
bool ScalarTraits<char_16>::mustQuote(StringRef S) { return needsQuotes(S); }
// TODO: if the output will fit on one line, compress tables and arrays into a single line void Any::serialize(TextOutput& to) const { beforeRead(); if (m_data && !m_data->comment.empty()) { to.printf("\n/* %s */\n", m_data->comment.c_str()); } switch (m_type) { case NONE: to.writeSymbol("NONE"); break; case BOOLEAN: to.writeBoolean(m_simpleValue.b); break; case NUMBER: to.writeNumber(m_simpleValue.n); break; case STRING: debugAssert(m_data != NULL); to.writeString(*(m_data->value.s)); break; case TABLE: { debugAssert(m_data != NULL); if (!m_data->name.empty()) { if (needsQuotes(m_data->name)) { to.writeString(m_data->name); } else { to.writeSymbol(m_data->name); } } to.writeSymbol("{"); to.writeNewline(); to.pushIndent(); AnyTable& table = *(m_data->value.t); Array<std::string> keys; table.getKeys(keys); keys.sort(); for (int i = 0; i < keys.size(); ++i) { to.writeSymbol(keys[i]); to.writeSymbol("="); table[keys[i]].serialize(to); if (i < keys.size() - 1) { to.writeSymbol(","); } to.writeNewline(); // Skip a line between table entries to.writeNewline(); } to.popIndent(); to.writeSymbol("}"); break; } case ARRAY: { debugAssert(m_data != NULL); if (!m_data->name.empty()) { // For arrays, leave no trailing space between the name and the paren to.writeSymbol(format("%s(", m_data->name.c_str())); } else { to.writeSymbol("("); } to.writeNewline(); to.pushIndent(); Array<Any>& array = *(m_data->value.a); for (int ii = 0; ii < size(); ++ii) { array[ii].serialize(to); if (ii < size() - 1) { to.writeSymbol(","); to.writeNewline(); } // Put the close paren on an array right behind the last element } to.popIndent(); to.writeSymbol(")"); break; } } }
static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }