StringRef ScalarNode::unescapeDoubleQuoted()

in lib/llvm/Support/YAMLParser.cpp [1911:2052]


StringRef ScalarNode::unescapeDoubleQuoted( StringRef UnquotedValue
                                          , StringRef::size_type i
                                          , SmallVectorImpl<char> &Storage)
                                          const {
  // Use Storage to build proper value.
  Storage.clear();
  Storage.reserve(UnquotedValue.size());
  for (; i != StringRef::npos; i = UnquotedValue.find_first_of("\\\r\n")) {
    // Insert all previous chars into Storage.
    StringRef Valid(UnquotedValue.begin(), i);
    Storage.insert(Storage.end(), Valid.begin(), Valid.end());
    // Chop off inserted chars.
    UnquotedValue = UnquotedValue.substr(i);

    assert(!UnquotedValue.empty() && "Can't be empty!");

    // Parse escape or line break.
    switch (UnquotedValue[0]) {
    case '\r':
    case '\n':
      Storage.push_back('\n');
      if (   UnquotedValue.size() > 1
          && (UnquotedValue[1] == '\r' || UnquotedValue[1] == '\n'))
        UnquotedValue = UnquotedValue.substr(1);
      UnquotedValue = UnquotedValue.substr(1);
      break;
    default:
      if (UnquotedValue.size() == 1)
        // TODO: Report error.
        break;
      UnquotedValue = UnquotedValue.substr(1);
      switch (UnquotedValue[0]) {
      default: {
          Token T;
          T.Range = StringRef(UnquotedValue.begin(), 1);
          setError("Unrecognized escape code!", T);
          return "";
        }
      case '\r':
      case '\n':
        // Remove the new line.
        if (   UnquotedValue.size() > 1
            && (UnquotedValue[1] == '\r' || UnquotedValue[1] == '\n'))
          UnquotedValue = UnquotedValue.substr(1);
        // If this was just a single byte newline, it will get skipped
        // below.
        break;
      case '0':
        Storage.push_back(0x00);
        break;
      case 'a':
        Storage.push_back(0x07);
        break;
      case 'b':
        Storage.push_back(0x08);
        break;
      case 't':
      case 0x09:
        Storage.push_back(0x09);
        break;
      case 'n':
        Storage.push_back(0x0A);
        break;
      case 'v':
        Storage.push_back(0x0B);
        break;
      case 'f':
        Storage.push_back(0x0C);
        break;
      case 'r':
        Storage.push_back(0x0D);
        break;
      case 'e':
        Storage.push_back(0x1B);
        break;
      case ' ':
        Storage.push_back(0x20);
        break;
      case '"':
        Storage.push_back(0x22);
        break;
      case '/':
        Storage.push_back(0x2F);
        break;
      case '\\':
        Storage.push_back(0x5C);
        break;
      case 'N':
        encodeUTF8(0x85, Storage);
        break;
      case '_':
        encodeUTF8(0xA0, Storage);
        break;
      case 'L':
        encodeUTF8(0x2028, Storage);
        break;
      case 'P':
        encodeUTF8(0x2029, Storage);
        break;
      case 'x': {
          if (UnquotedValue.size() < 3)
            // TODO: Report error.
            break;
          unsigned int UnicodeScalarValue;
          if (UnquotedValue.substr(1, 2).getAsInteger(16, UnicodeScalarValue))
            // TODO: Report error.
            UnicodeScalarValue = 0xFFFD;
          encodeUTF8(UnicodeScalarValue, Storage);
          UnquotedValue = UnquotedValue.substr(2);
          break;
        }
      case 'u': {
          if (UnquotedValue.size() < 5)
            // TODO: Report error.
            break;
          unsigned int UnicodeScalarValue;
          if (UnquotedValue.substr(1, 4).getAsInteger(16, UnicodeScalarValue))
            // TODO: Report error.
            UnicodeScalarValue = 0xFFFD;
          encodeUTF8(UnicodeScalarValue, Storage);
          UnquotedValue = UnquotedValue.substr(4);
          break;
        }
      case 'U': {
          if (UnquotedValue.size() < 9)
            // TODO: Report error.
            break;
          unsigned int UnicodeScalarValue;
          if (UnquotedValue.substr(1, 8).getAsInteger(16, UnicodeScalarValue))
            // TODO: Report error.
            UnicodeScalarValue = 0xFFFD;
          encodeUTF8(UnicodeScalarValue, Storage);
          UnquotedValue = UnquotedValue.substr(8);
          break;
        }
      }
      UnquotedValue = UnquotedValue.substr(1);
    }
  }
  Storage.insert(Storage.end(), UnquotedValue.begin(), UnquotedValue.end());
  return StringRef(Storage.begin(), Storage.size());
}