File: parse_string_literal.h

package info (click to toggle)
pytorch-cuda 2.6.0%2Bdfsg-7
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid, trixie
  • size: 161,620 kB
  • sloc: python: 1,278,832; cpp: 900,322; ansic: 82,710; asm: 7,754; java: 3,363; sh: 2,811; javascript: 2,443; makefile: 597; ruby: 195; xml: 84; objc: 68
file content (87 lines) | stat: -rw-r--r-- 2,294 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#pragma once
#include <torch/csrc/jit/frontend/error_report.h>
#include <torch/csrc/jit/frontend/lexer.h>
#include <optional>

namespace torch::jit {

inline bool isCharCount(char c, const std::string& str, size_t start, int len) {
  // count checks from [start, start + len)
  return start + len <= str.size() &&
      std::count(
          str.begin() + static_cast<ptrdiff_t>(start),
          str.begin() + static_cast<ptrdiff_t>(start + len),
          c) == len;
}

inline std::optional<char> parseOctal(const std::string& str, size_t pos) {
  //\xxx where x are 0-7
  if (pos + 3 >= str.size())
    return std::nullopt;
  size_t c = 0;
  for (size_t i = 1, b = 64; i < 4; ++i, b /= 8) {
    auto d = str[pos + i];
    if (d < '0' || d > '7')
      return std::nullopt;
    c += b * (d - '0');
  }
  if (c >= 256)
    return std::nullopt;
  return c;
}

inline std::string parseStringLiteral(
    const SourceRange& range,
    const std::string& str) {
  size_t quote_len = isCharCount(str[0], str, 0, 3) ? 3 : 1;
  auto ret_str = str.substr(quote_len, str.size() - quote_len * 2);
  size_t pos = ret_str.find('\\');
  while (pos != std::string::npos) {
    // invariant: pos has to escape a character because it is a valid string
    char c = ret_str[pos + 1];
    size_t to_erase = 2;
    switch (ret_str[pos + 1]) {
      case '\\':
      case '\'':
      case '\"':
      case '\n':
        break;
      case 'a':
        c = '\a';
        break;
      case 'b':
        c = '\b';
        break;
      case 'f':
        c = '\f';
        break;
      case 'n':
        c = '\n';
        break;
      case 'v':
        c = '\v';
        break;
      case 't':
        c = '\t';
        break;
      case 'x':
        throw(ErrorReport(range) << "unsupported hex specifier");
      case 'u':
      case 'U':
        throw(ErrorReport(range) << "unsupported unicode specifier");
      default:
        // octal value in format \nnn, n is [0-7]
        if (auto v = parseOctal(ret_str, pos)) {
          to_erase = 4;
          c = *v;
        } else {
          throw(ErrorReport(range) << " ill formed octal specifier");
        }
    }
    ret_str.replace(pos, to_erase, /* num copies */ 1, c);
    pos = ret_str.find('\\', pos + 1);
  }
  return ret_str;
}

} // namespace torch::jit