blob: 7109333f12be55b02adc3a891d71bb65bf5668ef [file] [log] [blame]
// Copyright 2016 The Shaderc Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "resource_parse.h"
#include <algorithm>
#include <cstring>
#include <iterator>
#include <sstream>
#include <vector>
namespace {
// Converts a limit string to a limit enum. Returns true on successful
// conversion.
bool StringToLimit(const std::string& str, shaderc_limit* limit) {
const char* cstr = str.c_str();
#define RESOURCE(NAME, FIELD, ENUM) \
if (0 == std::strcmp(#NAME, cstr)) { \
*limit = shaderc_limit_##ENUM; \
return true; \
}
#include "libshaderc_util/resources.inc"
#undef RESOURCE
return false;
}
// Returns true if we should ignore the setting.
bool IgnoreSetting(const std::string& str) {
const std::string ignore_list[] = {
"nonInductiveForLoops",
"whileLoops",
"doWhileLoops",
"generalUniformIndexing",
"generalAttributeMatrixVectorIndexing",
"generalVaryingIndexing",
"generalSamplerIndexing",
"generalVariableIndexing",
"generalConstantMatrixVectorIndexing",
};
return std::find(std::begin(ignore_list), std::end(ignore_list), str) !=
std::end(ignore_list);
}
} // anonymous namespace
namespace glslc {
bool ParseResourceSettings(const std::string& input,
std::vector<ResourceSetting>* limits,
std::string* err) {
auto failure = [err, limits](std::string msg) {
*err = msg;
limits->clear();
return false;
};
std::istringstream input_stream(input);
std::istream_iterator<std::string> pos((input_stream));
limits->clear();
while (pos != std::istream_iterator<std::string>()) {
const std::string limit_name = *pos++;
shaderc_limit limit = static_cast<shaderc_limit>(0);
bool ignore = IgnoreSetting(limit_name);
if (!ignore) {
if (!StringToLimit(limit_name, &limit))
return failure(std::string("invalid resource limit: " + limit_name));
}
if (pos == std::istream_iterator<std::string>())
return failure(std::string("missing value after limit: ") + limit_name);
const std::string value_str = *pos;
int value;
std::istringstream value_stream(value_str);
value_stream >> value;
if (value_stream.bad() || !value_stream.eof() || value_stream.fail())
return failure(std::string("invalid integer: ") + value_str);
if (!ignore) limits->push_back({limit, value});
++pos;
}
return true;
}
} // anonymous namespace