// Copyright 2016 The SwiftShader 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 "Configurator.hpp" #include <iostream> #include <fstream> using namespace std; #include <stdio.h> #include <stdarg.h> #include <ctype.h> #if defined(__unix__) #include <unistd.h> #endif namespace sw { Configurator::Configurator(string iniPath) { path = iniPath; readFile(); } Configurator::~Configurator() { } bool Configurator::readFile() { #if defined(__unix__) if(access(path.c_str(), R_OK) != 0) { return false; } #endif fstream file(path.c_str(), ios::in); if(file.fail()) return false; string line; string keyName; while(getline(file, line)) { if(line.length()) { if(line[line.length() - 1] == '\r') { line = line.substr(0, line.length() - 1); } if(!isprint(line[0])) { // printf("Failing on char %d\n", line[0]); file.close(); return false; } string::size_type pLeft = line.find_first_of(";#[="); if(pLeft != string::npos) { switch(line[pLeft]) { case '[': { string::size_type pRight = line.find_last_of("]"); if(pRight != string::npos && pRight > pLeft) { keyName = line.substr(pLeft + 1, pRight - pLeft - 1); addKeyName(keyName); } } break; case '=': { string valueName = line.substr(0, pLeft); string value = line.substr(pLeft + 1); addValue(keyName, valueName, value); } break; case ';': case '#': // Ignore comments break; } } } } file.close(); if(names.size()) { return true; } return false; } void Configurator::writeFile(std::string title) { #if defined(__unix__) if(access(path.c_str(), W_OK) != 0) { return; } #endif fstream file(path.c_str(), ios::out); if(file.fail()) return; file << "; " << title << endl << endl; for(unsigned int keyID = 0; keyID < sections.size(); keyID++) { file << "[" << names[keyID] << "]" << endl; for(unsigned int valueID = 0; valueID < sections[keyID].names.size(); valueID++) { file << sections[keyID].names[valueID] << "=" << sections[keyID].values[valueID] << endl; } file << endl; } file.close(); } int Configurator::findKey(string keyName) const { for(unsigned int keyID = 0; keyID < names.size(); keyID++) { if(names[keyID] == keyName) { return keyID; } } return -1; } int Configurator::findValue(unsigned int keyID, string valueName) const { if(!sections.size() || keyID >= sections.size()) { return -1; } for(unsigned int valueID = 0; valueID < sections[keyID].names.size(); ++valueID) { if(sections[keyID].names[valueID] == valueName) { return valueID; } } return -1; } unsigned int Configurator::addKeyName(string keyName) { names.resize(names.size() + 1, keyName); sections.resize(sections.size() + 1); return (unsigned int)names.size() - 1; } void Configurator::addValue(string const keyName, string const valueName, string const value) { int keyID = findKey(keyName); if(keyID == -1) { keyID = addKeyName(keyName); } int valueID = findValue(keyID, valueName); if(valueID == -1) { sections[keyID].names.resize(sections[keyID].names.size() + 1, valueName); sections[keyID].values.resize(sections[keyID].values.size() + 1, value); } else { sections[keyID].values[valueID] = value; } } string Configurator::getValue(string keyName, string valueName, string defaultValue) const { int keyID = findKey(keyName); if(keyID == -1) return defaultValue; int valueID = findValue((unsigned int)keyID, valueName); if(valueID == -1) return defaultValue; return sections[keyID].values[valueID]; } int Configurator::getInteger(string keyName, string valueName, int defaultValue) const { char svalue[256]; sprintf(svalue, "%d", defaultValue); return atoi(getValue(keyName, valueName, svalue).c_str()); } bool Configurator::getBoolean(string keyName, string valueName, bool defaultValue) const { return getInteger(keyName, valueName, (int)defaultValue) != 0; } double Configurator::getFloat(string keyName, string valueName, double defaultValue) const { char svalue[256]; sprintf(svalue, "%f", defaultValue); return atof(getValue(keyName, valueName, svalue).c_str()); } unsigned int Configurator::getFormatted(string keyName, string valueName, char *format, void *v1, void *v2, void *v3, void *v4, void *v5, void *v6, void *v7, void *v8, void *v9, void *v10, void *v11, void *v12, void *v13, void *v14, void *v15, void *v16) { string value = getValue(keyName, valueName); if(!value.length()) return false; unsigned int nVals = sscanf(value.c_str(), format, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16); return nVals; } }