Home | History | Annotate | Download | only in Common
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      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 #include "Configurator.hpp"
     16 
     17 #include <iostream>
     18 #include <fstream>
     19 
     20 using namespace std;
     21 
     22 #include <stdio.h>
     23 #include <stdarg.h>
     24 #include <ctype.h>
     25 
     26 #if defined(__unix__)
     27 #include <unistd.h>
     28 #endif
     29 
     30 namespace sw
     31 {
     32 	Configurator::Configurator(string iniPath)
     33 	{
     34 		path = iniPath;
     35 
     36 		readFile();
     37 	}
     38 
     39 	Configurator::~Configurator()
     40 	{
     41 	}
     42 
     43 	bool Configurator::readFile()
     44 	{
     45 		#if defined(__unix__)
     46 			if(access(path.c_str(), R_OK) != 0)
     47 			{
     48 				return false;
     49 			}
     50 		#endif
     51 
     52 		fstream file(path.c_str(), ios::in);
     53 		if(file.fail()) return false;
     54 
     55 		string line;
     56 		string keyName;
     57 
     58 		while(getline(file, line))
     59 		{
     60 			if(line.length())
     61 			{
     62 				if(line[line.length() - 1] == '\r')
     63 				{
     64 					line = line.substr(0, line.length() - 1);
     65 				}
     66 
     67 				if(!isprint(line[0]))
     68 				{
     69 					printf("Failing on char %d\n", line[0]);
     70 					file.close();
     71 					return false;
     72 				}
     73 
     74 				string::size_type pLeft = line.find_first_of(";#[=");
     75 
     76 				if(pLeft != string::npos)
     77 				{
     78 					switch(line[pLeft])
     79 					{
     80 					case '[':
     81 						{
     82 							string::size_type pRight = line.find_last_of("]");
     83 
     84 							if(pRight != string::npos && pRight > pLeft)
     85 							{
     86 								keyName = line.substr(pLeft + 1, pRight - pLeft - 1);
     87 								addKeyName(keyName);
     88 							}
     89 						}
     90 						break;
     91 					case '=':
     92 						{
     93 							string valueName = line.substr(0, pLeft);
     94 							string value = line.substr(pLeft + 1);
     95 							addValue(keyName, valueName, value);
     96 						}
     97 						break;
     98 					case ';':
     99 					case '#':
    100 						// Ignore comments
    101 						break;
    102 					}
    103 				}
    104 			}
    105 		}
    106 
    107 		file.close();
    108 
    109 		if(names.size())
    110 		{
    111 			return true;
    112 		}
    113 
    114 		return false;
    115 	}
    116 
    117 	void Configurator::writeFile(std::string title)
    118 	{
    119 		#if defined(__unix__)
    120 			if(access(path.c_str(), W_OK) != 0)
    121 			{
    122 				return;
    123 			}
    124 		#endif
    125 
    126 		fstream file(path.c_str(), ios::out);
    127 		if(file.fail()) return;
    128 
    129 		file << "; " << title << endl << endl;
    130 
    131 		for(unsigned int keyID = 0; keyID < sections.size(); keyID++)
    132 		{
    133 			file << "[" << names[keyID] << "]" << endl;
    134 
    135 			for(unsigned int valueID = 0; valueID < sections[keyID].names.size(); valueID++)
    136 			{
    137 				file << sections[keyID].names[valueID] << "=" << sections[keyID].values[valueID] << endl;
    138 			}
    139 
    140 			file << endl;
    141 		}
    142 
    143 		file.close();
    144 	}
    145 
    146 	int Configurator::findKey(string keyName) const
    147 	{
    148 		for(unsigned int keyID = 0; keyID < names.size(); keyID++)
    149 		{
    150 			if(names[keyID] == keyName)
    151 			{
    152 				return keyID;
    153 			}
    154 		}
    155 
    156 		return -1;
    157 	}
    158 
    159 	int Configurator::findValue(unsigned int keyID, string valueName) const
    160 	{
    161 		if(!sections.size() || keyID >= sections.size())
    162 		{
    163 			return -1;
    164 		}
    165 
    166 		for(unsigned int valueID = 0; valueID < sections[keyID].names.size(); ++valueID)
    167 		{
    168 			if(sections[keyID].names[valueID] == valueName)
    169 			{
    170 				return valueID;
    171 			}
    172 		}
    173 
    174 		return -1;
    175 	}
    176 
    177 	unsigned int Configurator::addKeyName(string keyName)
    178 	{
    179 		names.resize(names.size() + 1, keyName);
    180 		sections.resize(sections.size() + 1);
    181 		return (unsigned int)names.size() - 1;
    182 	}
    183 
    184 	void Configurator::addValue(string const keyName, string const valueName, string const value)
    185 	{
    186 		int keyID = findKey(keyName);
    187 
    188 		if(keyID == -1)
    189 		{
    190 			keyID = addKeyName(keyName);
    191 		}
    192 
    193 		int valueID = findValue(keyID, valueName);
    194 
    195 		if(valueID == -1)
    196 		{
    197 			sections[keyID].names.resize(sections[keyID].names.size() + 1, valueName);
    198 			sections[keyID].values.resize(sections[keyID].values.size() + 1, value);
    199 		}
    200 		else
    201 		{
    202 			sections[keyID].values[valueID] = value;
    203 		}
    204 	}
    205 
    206 	string Configurator::getValue(string keyName, string valueName, string defaultValue) const
    207 	{
    208 		int keyID = findKey(keyName);
    209 		if(keyID == -1) return defaultValue;
    210 		int valueID = findValue((unsigned int)keyID, valueName);
    211 		if(valueID == -1) return defaultValue;
    212 
    213 		return sections[keyID].values[valueID];
    214 	}
    215 
    216 	int Configurator::getInteger(string keyName, string valueName, int defaultValue) const
    217 	{
    218 		char svalue[256];
    219 
    220 		sprintf(svalue, "%d", defaultValue);
    221 
    222 		return atoi(getValue(keyName, valueName, svalue).c_str());
    223 	}
    224 
    225 	bool Configurator::getBoolean(string keyName, string valueName, bool defaultValue) const
    226 	{
    227 		return getInteger(keyName, valueName, (int)defaultValue) != 0;
    228 	}
    229 
    230 	double Configurator::getFloat(string keyName, string valueName, double defaultValue) const
    231 	{
    232 		char svalue[256];
    233 
    234 		sprintf(svalue, "%f", defaultValue);
    235 
    236 		return atof(getValue(keyName, valueName, svalue).c_str());
    237 	}
    238 
    239 	unsigned int Configurator::getFormatted(string keyName, string valueName, char *format,
    240 											void *v1, void *v2, void *v3, void *v4,
    241 											void *v5, void *v6, void *v7, void *v8,
    242 											void *v9, void *v10, void *v11, void *v12,
    243 											void *v13, void *v14, void *v15, void *v16)
    244 	{
    245 		string value = getValue(keyName, valueName);
    246 
    247 		if(!value.length()) return false;
    248 
    249 		unsigned int nVals = sscanf(value.c_str(), format,
    250 									v1, v2, v3, v4, v5, v6, v7, v8,
    251 									v9, v10, v11, v12, v13, v14, v15, v16);
    252 
    253 		return nVals;
    254 	}
    255 }
    256