Coverage Report

Created: 2025-06-13 06:49

/src/spirv-tools/source/util/string_utils.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2017 Google Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#ifndef SOURCE_UTIL_STRING_UTILS_H_
16
#define SOURCE_UTIL_STRING_UTILS_H_
17
18
#include <assert.h>
19
20
#include <cstdint>
21
#include <cstring>
22
#include <sstream>
23
#include <string>
24
#include <vector>
25
26
namespace spvtools {
27
namespace utils {
28
29
// Converts arithmetic value |val| to its default string representation.
30
template <class T>
31
448
std::string ToString(T val) {
32
448
  static_assert(
33
448
      std::is_arithmetic<T>::value,
34
448
      "spvtools::utils::ToString is restricted to only arithmetic values");
35
448
  std::stringstream os;
36
448
  os << val;
37
448
  return os.str();
38
448
}
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > spvtools::utils::ToString<unsigned int>(unsigned int)
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > spvtools::utils::ToString<unsigned long>(unsigned long)
Line
Count
Source
31
448
std::string ToString(T val) {
32
448
  static_assert(
33
448
      std::is_arithmetic<T>::value,
34
448
      "spvtools::utils::ToString is restricted to only arithmetic values");
35
448
  std::stringstream os;
36
448
  os << val;
37
448
  return os.str();
38
448
}
39
40
// Converts cardinal number to ordinal number string.
41
std::string CardinalToOrdinal(size_t cardinal);
42
43
// Splits the string |flag|, of the form '--pass_name[=pass_args]' into two
44
// strings "pass_name" and "pass_args".  If |flag| has no arguments, the second
45
// string will be empty.
46
std::pair<std::string, std::string> SplitFlagArgs(const std::string& flag);
47
48
// Encodes a string as a sequence of words, using the SPIR-V encoding, appending
49
// to an existing vector.
50
template <class VectorType = std::vector<uint32_t>>
51
61.2k
inline void AppendToVector(const std::string& input, VectorType* result) {
52
61.2k
  static_assert(std::is_same<uint32_t, typename VectorType::value_type>::value);
53
61.2k
  uint32_t word = 0;
54
61.2k
  size_t num_bytes = input.size();
55
  // SPIR-V strings are null-terminated.  The byte_index == num_bytes
56
  // case is used to push the terminating null byte.
57
25.1M
  for (size_t byte_index = 0; byte_index <= num_bytes; byte_index++) {
58
25.1M
    const auto new_byte =
59
25.1M
        (byte_index < num_bytes ? uint8_t(input[byte_index]) : uint8_t(0));
60
25.1M
    word |= (new_byte << (8 * (byte_index % sizeof(uint32_t))));
61
25.1M
    if (3 == (byte_index % sizeof(uint32_t))) {
62
6.25M
      result->push_back(word);
63
6.25M
      word = 0;
64
6.25M
    }
65
25.1M
  }
66
  // Emit a trailing partial word.
67
61.2k
  if ((num_bytes + 1) % sizeof(uint32_t)) {
68
52.3k
    result->push_back(word);
69
52.3k
  }
70
61.2k
}
void spvtools::utils::AppendToVector<std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >*)
Line
Count
Source
51
61.2k
inline void AppendToVector(const std::string& input, VectorType* result) {
52
61.2k
  static_assert(std::is_same<uint32_t, typename VectorType::value_type>::value);
53
61.2k
  uint32_t word = 0;
54
61.2k
  size_t num_bytes = input.size();
55
  // SPIR-V strings are null-terminated.  The byte_index == num_bytes
56
  // case is used to push the terminating null byte.
57
25.1M
  for (size_t byte_index = 0; byte_index <= num_bytes; byte_index++) {
58
25.1M
    const auto new_byte =
59
25.1M
        (byte_index < num_bytes ? uint8_t(input[byte_index]) : uint8_t(0));
60
25.1M
    word |= (new_byte << (8 * (byte_index % sizeof(uint32_t))));
61
25.1M
    if (3 == (byte_index % sizeof(uint32_t))) {
62
6.25M
      result->push_back(word);
63
6.25M
      word = 0;
64
6.25M
    }
65
25.1M
  }
66
  // Emit a trailing partial word.
67
61.2k
  if ((num_bytes + 1) % sizeof(uint32_t)) {
68
52.3k
    result->push_back(word);
69
52.3k
  }
70
61.2k
}
Unexecuted instantiation: void spvtools::utils::AppendToVector<spvtools::utils::SmallVector<unsigned int, 2ul> >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, spvtools::utils::SmallVector<unsigned int, 2ul>*)
71
72
// Encodes a string as a sequence of words, using the SPIR-V encoding.
73
template <class VectorType = std::vector<uint32_t>>
74
0
inline VectorType MakeVector(const std::string& input) {
75
0
  static_assert(std::is_same<uint32_t, typename VectorType::value_type>::value);
76
0
  VectorType result;
77
0
  AppendToVector(input, &result);
78
0
  return result;
79
0
}
Unexecuted instantiation: std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > spvtools::utils::MakeVector<std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: spvtools::utils::SmallVector<unsigned int, 2ul> spvtools::utils::MakeVector<spvtools::utils::SmallVector<unsigned int, 2ul> >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
80
81
// Decode a string from a sequence of words between first and last, using the
82
// SPIR-V encoding. Assert that a terminating 0-byte was found (unless
83
// assert_found_terminating_null is passed as false).
84
template <class InputIt>
85
inline std::string MakeString(InputIt first, InputIt last,
86
7.35M
                              bool assert_found_terminating_null = true) {
87
7.35M
  std::string result;
88
7.35M
  constexpr size_t kCharsPerWord = sizeof(*first);
89
7.35M
  static_assert(kCharsPerWord == 4, "expect 4-byte word");
90
91
355M
  for (InputIt pos = first; pos != last; ++pos) {
92
355M
    uint32_t word = *pos;
93
1.75G
    for (size_t byte_index = 0; byte_index < kCharsPerWord; byte_index++) {
94
1.40G
      uint32_t extracted_word = (word >> (8 * byte_index)) & 0xFF;
95
1.40G
      char c = static_cast<char>(extracted_word);
96
1.40G
      if (c == 0) {
97
7.35M
        return result;
98
7.35M
      }
99
1.39G
      result += c;
100
1.39G
    }
101
355M
  }
102
3.03k
  assert(!assert_found_terminating_null &&
103
3.03k
         "Did not find terminating null for the string.");
104
3.03k
  (void)assert_found_terminating_null; /* No unused parameters in release
105
                                          builds. */
106
3.03k
  return result;
107
3.03k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > spvtools::utils::MakeString<unsigned int const*>(unsigned int const*, unsigned int const*, bool)
Line
Count
Source
86
7.35M
                              bool assert_found_terminating_null = true) {
87
7.35M
  std::string result;
88
7.35M
  constexpr size_t kCharsPerWord = sizeof(*first);
89
7.35M
  static_assert(kCharsPerWord == 4, "expect 4-byte word");
90
91
355M
  for (InputIt pos = first; pos != last; ++pos) {
92
355M
    uint32_t word = *pos;
93
1.75G
    for (size_t byte_index = 0; byte_index < kCharsPerWord; byte_index++) {
94
1.40G
      uint32_t extracted_word = (word >> (8 * byte_index)) & 0xFF;
95
1.40G
      char c = static_cast<char>(extracted_word);
96
1.40G
      if (c == 0) {
97
7.35M
        return result;
98
7.35M
      }
99
1.39G
      result += c;
100
1.39G
    }
101
355M
  }
102
3.03k
  assert(!assert_found_terminating_null &&
103
3.03k
         "Did not find terminating null for the string.");
104
3.03k
  (void)assert_found_terminating_null; /* No unused parameters in release
105
                                          builds. */
106
3.03k
  return result;
107
3.03k
}
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > spvtools::utils::MakeString<std::__1::__wrap_iter<unsigned int const*> >(std::__1::__wrap_iter<unsigned int const*>, std::__1::__wrap_iter<unsigned int const*>, bool)
108
109
// Decode a string from a sequence of words in a vector, using the SPIR-V
110
// encoding.
111
template <class VectorType>
112
inline std::string MakeString(const VectorType& words,
113
873k
                              bool assert_found_terminating_null = true) {
114
873k
  return MakeString(words.cbegin(), words.cend(),
115
873k
                    assert_found_terminating_null);
116
873k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > spvtools::utils::MakeString<spvtools::utils::SmallVector<unsigned int, 2ul> >(spvtools::utils::SmallVector<unsigned int, 2ul> const&, bool)
Line
Count
Source
113
873k
                              bool assert_found_terminating_null = true) {
114
873k
  return MakeString(words.cbegin(), words.cend(),
115
873k
                    assert_found_terminating_null);
116
873k
}
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > spvtools::utils::MakeString<std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > >(std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, bool)
117
118
// Decode a string from array words, consuming up to count words, using the
119
// SPIR-V encoding.
120
inline std::string MakeString(const uint32_t* words, size_t num_words,
121
6.48M
                              bool assert_found_terminating_null = true) {
122
6.48M
  return MakeString(words, words + num_words, assert_found_terminating_null);
123
6.48M
}
124
125
// Check if str starts with prefix (only included since C++20)
126
64.2k
inline bool starts_with(const std::string& str, const char* prefix) {
127
64.2k
  return 0 == str.compare(0, std::strlen(prefix), prefix);
128
64.2k
}
129
130
}  // namespace utils
131
}  // namespace spvtools
132
133
#endif  // SOURCE_UTIL_STRING_UTILS_H_