| 199 | } |
| 200 | |
| 201 | bool spvReadEnvironmentFromText(const std::vector<char>& text, |
| 202 | spv_target_env* env) { |
| 203 | // Version is expected to match "; Version: 1.X" |
| 204 | // Version string must occur in header, that is, initial lines of comments |
| 205 | // Once a non-comment line occurs, the header has ended |
| 206 | for (std::size_t i = 0; i < text.size(); ++i) { |
| 207 | char c = text[i]; |
| 208 | |
| 209 | if (c == ';') { |
| 210 | // Try to match against the expected version string |
| 211 | constexpr const char* kVersionPrefix = "; Version: 1."; |
| 212 | constexpr const auto kPrefixLength = 13; |
| 213 | // 'minor_digit_pos' is the expected position of the version digit. |
| 214 | const auto minor_digit_pos = i + kPrefixLength; |
| 215 | if (minor_digit_pos >= text.size()) return false; |
| 216 | |
| 217 | // Match the prefix. |
| 218 | auto j = 1; |
| 219 | for (; j < kPrefixLength; ++j) { |
| 220 | if (kVersionPrefix[j] != text[i + j]) break; |
| 221 | } |
| 222 | // j will match the prefix length if all characters before matched |
| 223 | if (j == kPrefixLength) { |
| 224 | // This expects only one digit in the minor number. |
| 225 | static_assert(((spv::Version >> 8) & 0xff) < 10); |
| 226 | char minor = text[minor_digit_pos]; |
| 227 | char next_char = |
| 228 | minor_digit_pos + 1 < text.size() ? text[minor_digit_pos + 1] : 0; |
| 229 | if (std::isdigit(minor) && !std::isdigit(next_char)) { |
| 230 | const auto index = minor - '0'; |
| 231 | assert(index >= 0); |
| 232 | if (static_cast<size_t>(index) < ordered_universal_envs.size()) { |
| 233 | *env = ordered_universal_envs[index]; |
| 234 | return true; |
| 235 | } |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | // If no match, determine whether the header has ended (in which case, |
| 240 | // assumption has failed.) |
| 241 | // Skip until the next line. |
| 242 | i += j; |
| 243 | for (; i < text.size(); ++i) { |
| 244 | if (text[i] == '\n') break; |
| 245 | } |
| 246 | } else if (!std::isspace(c)) { |
| 247 | // Allow blanks, but end the search if we find something else. |
| 248 | break; |
| 249 | } |
| 250 | } |
| 251 | return false; |
| 252 | } |
| 253 | |
| 254 | #define VULKAN_VER(MAJOR, MINOR) ((MAJOR << 22) | (MINOR << 12)) |
| 255 | #define SPIRV_VER(MAJOR, MINOR) ((MAJOR << 16) | (MINOR << 8)) |