gfx/skia/trunk/src/utils/SkRTConf.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * Copyright 2013 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #include "SkRTConf.h"
michael@0 9 #include "SkOSFile.h"
michael@0 10
michael@0 11 SkRTConfRegistry::SkRTConfRegistry(): fConfs(100) {
michael@0 12
michael@0 13 SkFILE *fp = sk_fopen(configFileLocation(), kRead_SkFILE_Flag);
michael@0 14
michael@0 15 if (!fp) {
michael@0 16 return;
michael@0 17 }
michael@0 18
michael@0 19 char line[1024];
michael@0 20
michael@0 21 while (!sk_feof(fp)) {
michael@0 22
michael@0 23 if (!sk_fgets(line, sizeof(line), fp)) {
michael@0 24 break;
michael@0 25 }
michael@0 26
michael@0 27 char *commentptr = strchr(line, '#');
michael@0 28 if (commentptr == line) {
michael@0 29 continue;
michael@0 30 }
michael@0 31 if (NULL != commentptr) {
michael@0 32 *commentptr = '\0';
michael@0 33 }
michael@0 34
michael@0 35 char sep[] = " \t\r\n";
michael@0 36
michael@0 37 char *keyptr = strtok(line, sep);
michael@0 38 if (!keyptr) {
michael@0 39 continue;
michael@0 40 }
michael@0 41
michael@0 42 char *valptr = strtok(NULL, sep);
michael@0 43 if (!valptr) {
michael@0 44 continue;
michael@0 45 }
michael@0 46
michael@0 47 SkString* key = SkNEW_ARGS(SkString,(keyptr));
michael@0 48 SkString* val = SkNEW_ARGS(SkString,(valptr));
michael@0 49
michael@0 50 fConfigFileKeys.append(1, &key);
michael@0 51 fConfigFileValues.append(1, &val);
michael@0 52 }
michael@0 53 sk_fclose(fp);
michael@0 54 }
michael@0 55
michael@0 56 SkRTConfRegistry::~SkRTConfRegistry() {
michael@0 57 ConfMap::Iter iter(fConfs);
michael@0 58 SkTDArray<SkRTConfBase *> *confArray;
michael@0 59
michael@0 60 while (iter.next(&confArray)) {
michael@0 61 delete confArray;
michael@0 62 }
michael@0 63
michael@0 64 for (int i = 0 ; i < fConfigFileKeys.count() ; i++) {
michael@0 65 SkDELETE(fConfigFileKeys[i]);
michael@0 66 SkDELETE(fConfigFileValues[i]);
michael@0 67 }
michael@0 68 }
michael@0 69
michael@0 70 const char *SkRTConfRegistry::configFileLocation() const {
michael@0 71 return "skia.conf"; // for now -- should probably do something fancier like home directories or whatever.
michael@0 72 }
michael@0 73
michael@0 74 // dump all known runtime config options to the file with their default values.
michael@0 75 // to trigger this, make a config file of zero size.
michael@0 76 void SkRTConfRegistry::possiblyDumpFile() const {
michael@0 77 const char *path = configFileLocation();
michael@0 78 SkFILE *fp = sk_fopen(path, kRead_SkFILE_Flag);
michael@0 79 if (!fp) {
michael@0 80 return;
michael@0 81 }
michael@0 82 size_t configFileSize = sk_fgetsize(fp);
michael@0 83 if (configFileSize == 0) {
michael@0 84 printAll(path);
michael@0 85 }
michael@0 86 sk_fclose(fp);
michael@0 87 }
michael@0 88
michael@0 89 // Run through every provided configuration option and print a warning if the user hasn't
michael@0 90 // declared a correponding configuration object somewhere.
michael@0 91 void SkRTConfRegistry::validate() const {
michael@0 92 for (int i = 0 ; i < fConfigFileKeys.count() ; i++) {
michael@0 93 if (!fConfs.find(fConfigFileKeys[i]->c_str())) {
michael@0 94 SkDebugf("WARNING: You have config value %s in your configuration file, but I've never heard of that.\n", fConfigFileKeys[i]->c_str());
michael@0 95 }
michael@0 96 }
michael@0 97 }
michael@0 98
michael@0 99 void SkRTConfRegistry::printAll(const char *fname) const {
michael@0 100 SkWStream *o;
michael@0 101
michael@0 102 if (NULL != fname) {
michael@0 103 o = new SkFILEWStream(fname);
michael@0 104 } else {
michael@0 105 o = new SkDebugWStream();
michael@0 106 }
michael@0 107
michael@0 108 ConfMap::Iter iter(fConfs);
michael@0 109 SkTDArray<SkRTConfBase *> *confArray;
michael@0 110
michael@0 111 while (iter.next(&confArray)) {
michael@0 112 if (confArray->getAt(0)->isDefault()) {
michael@0 113 o->writeText("# ");
michael@0 114 }
michael@0 115 confArray->getAt(0)->print(o);
michael@0 116 o->newline();
michael@0 117 }
michael@0 118
michael@0 119 delete o;
michael@0 120 }
michael@0 121
michael@0 122 bool SkRTConfRegistry::hasNonDefault() const {
michael@0 123 ConfMap::Iter iter(fConfs);
michael@0 124 SkTDArray<SkRTConfBase *> *confArray;
michael@0 125 while (iter.next(&confArray)) {
michael@0 126 if (!confArray->getAt(0)->isDefault()) {
michael@0 127 return true;
michael@0 128 }
michael@0 129 }
michael@0 130 return false;
michael@0 131 }
michael@0 132
michael@0 133 void SkRTConfRegistry::printNonDefault(const char *fname) const {
michael@0 134 SkWStream *o;
michael@0 135
michael@0 136 if (NULL != fname) {
michael@0 137 o = new SkFILEWStream(fname);
michael@0 138 } else {
michael@0 139 o = new SkDebugWStream();
michael@0 140 }
michael@0 141 ConfMap::Iter iter(fConfs);
michael@0 142 SkTDArray<SkRTConfBase *> *confArray;
michael@0 143
michael@0 144 while (iter.next(&confArray)) {
michael@0 145 if (!confArray->getAt(0)->isDefault()) {
michael@0 146 confArray->getAt(0)->print(o);
michael@0 147 o->newline();
michael@0 148 }
michael@0 149 }
michael@0 150
michael@0 151 delete o;
michael@0 152 }
michael@0 153
michael@0 154 // register a configuration variable after its value has been set by the parser.
michael@0 155 // we maintain a vector of these things instead of just a single one because the
michael@0 156 // user might set the value after initialization time and we need to have
michael@0 157 // all the pointers lying around, not just one.
michael@0 158 void SkRTConfRegistry::registerConf(SkRTConfBase *conf) {
michael@0 159 SkTDArray<SkRTConfBase *> *confArray;
michael@0 160 if (fConfs.find(conf->getName(), &confArray)) {
michael@0 161 if (!conf->equals(confArray->getAt(0))) {
michael@0 162 SkDebugf("WARNING: Skia config \"%s\" was registered more than once in incompatible ways.\n", conf->getName());
michael@0 163 } else {
michael@0 164 confArray->append(1, &conf);
michael@0 165 }
michael@0 166 } else {
michael@0 167 confArray = new SkTDArray<SkRTConfBase *>;
michael@0 168 confArray->append(1, &conf);
michael@0 169 fConfs.set(conf->getName(),confArray);
michael@0 170 }
michael@0 171 }
michael@0 172
michael@0 173 template <typename T> T doParse(const char *, bool *success ) {
michael@0 174 SkDebugf("WARNING: Invoked non-specialized doParse function...\n");
michael@0 175 if (success) {
michael@0 176 *success = false;
michael@0 177 }
michael@0 178 return (T) 0;
michael@0 179 }
michael@0 180
michael@0 181 template<> bool doParse<bool>(const char *s, bool *success) {
michael@0 182 if (success) {
michael@0 183 *success = true;
michael@0 184 }
michael@0 185 if (!strcmp(s,"1") || !strcmp(s,"true")) {
michael@0 186 return true;
michael@0 187 }
michael@0 188 if (!strcmp(s,"0") || !strcmp(s,"false")) {
michael@0 189 return false;
michael@0 190 }
michael@0 191 if (success) {
michael@0 192 *success = false;
michael@0 193 }
michael@0 194 return false;
michael@0 195 }
michael@0 196
michael@0 197 template<> const char * doParse<const char *>(const char * s, bool *success) {
michael@0 198 if (success) {
michael@0 199 *success = true;
michael@0 200 }
michael@0 201 return s;
michael@0 202 }
michael@0 203
michael@0 204 template<> int doParse<int>(const char * s, bool *success) {
michael@0 205 if (success) {
michael@0 206 *success = true;
michael@0 207 }
michael@0 208 return atoi(s);
michael@0 209 }
michael@0 210
michael@0 211 template<> unsigned int doParse<unsigned int>(const char * s, bool *success) {
michael@0 212 if (success) {
michael@0 213 *success = true;
michael@0 214 }
michael@0 215 return (unsigned int) atoi(s);
michael@0 216 }
michael@0 217
michael@0 218 template<> float doParse<float>(const char * s, bool *success) {
michael@0 219 if (success) {
michael@0 220 *success = true;
michael@0 221 }
michael@0 222 return (float) atof(s);
michael@0 223 }
michael@0 224
michael@0 225 template<> double doParse<double>(const char * s, bool *success) {
michael@0 226 if (success) {
michael@0 227 *success = true;
michael@0 228 }
michael@0 229 return atof(s);
michael@0 230 }
michael@0 231
michael@0 232 static inline void str_replace(char *s, char search, char replace) {
michael@0 233 for (char *ptr = s ; *ptr ; ptr++) {
michael@0 234 if (*ptr == search) {
michael@0 235 *ptr = replace;
michael@0 236 }
michael@0 237 }
michael@0 238 }
michael@0 239
michael@0 240 template<typename T> bool SkRTConfRegistry::parse(const char *name, T* value) {
michael@0 241 const char *str = NULL;
michael@0 242
michael@0 243 for (int i = fConfigFileKeys.count() - 1 ; i >= 0; i--) {
michael@0 244 if (fConfigFileKeys[i]->equals(name)) {
michael@0 245 str = fConfigFileValues[i]->c_str();
michael@0 246 break;
michael@0 247 }
michael@0 248 }
michael@0 249
michael@0 250 SkString environment_variable("skia.");
michael@0 251 environment_variable.append(name);
michael@0 252
michael@0 253 const char *environment_value = getenv(environment_variable.c_str());
michael@0 254 if (environment_value) {
michael@0 255 str = environment_value;
michael@0 256 } else {
michael@0 257 // apparently my shell doesn't let me have environment variables that
michael@0 258 // have periods in them, so also let the user substitute underscores.
michael@0 259 SkAutoTMalloc<char> underscore_name(SkStrDup(environment_variable.c_str()));
michael@0 260 str_replace(underscore_name.get(), '.', '_');
michael@0 261 environment_value = getenv(underscore_name.get());
michael@0 262 if (environment_value) {
michael@0 263 str = environment_value;
michael@0 264 }
michael@0 265 }
michael@0 266
michael@0 267 if (!str) {
michael@0 268 return false;
michael@0 269 }
michael@0 270
michael@0 271 bool success;
michael@0 272 T new_value = doParse<T>(str, &success);
michael@0 273 if (success) {
michael@0 274 *value = new_value;
michael@0 275 } else {
michael@0 276 SkDebugf("WARNING: Couldn't parse value \'%s\' for variable \'%s\'\n",
michael@0 277 str, name);
michael@0 278 }
michael@0 279 return success;
michael@0 280 }
michael@0 281
michael@0 282 // need to explicitly instantiate the parsing function for every config type we might have...
michael@0 283
michael@0 284 template bool SkRTConfRegistry::parse(const char *name, bool *value);
michael@0 285 template bool SkRTConfRegistry::parse(const char *name, int *value);
michael@0 286 template bool SkRTConfRegistry::parse(const char *name, unsigned int *value);
michael@0 287 template bool SkRTConfRegistry::parse(const char *name, float *value);
michael@0 288 template bool SkRTConfRegistry::parse(const char *name, double *value);
michael@0 289 template bool SkRTConfRegistry::parse(const char *name, const char **value);
michael@0 290
michael@0 291 template <typename T> void SkRTConfRegistry::set(const char *name,
michael@0 292 T value,
michael@0 293 bool warnIfNotFound) {
michael@0 294 SkTDArray<SkRTConfBase *> *confArray;
michael@0 295 if (!fConfs.find(name, &confArray)) {
michael@0 296 if (warnIfNotFound) {
michael@0 297 SkDebugf("WARNING: Attempting to set configuration value \"%s\","
michael@0 298 " but I've never heard of that.\n", name);
michael@0 299 }
michael@0 300 return;
michael@0 301 }
michael@0 302 SkASSERT(confArray != NULL);
michael@0 303 for (SkRTConfBase **confBase = confArray->begin(); confBase != confArray->end(); confBase++) {
michael@0 304 // static_cast here is okay because there's only one kind of child class.
michael@0 305 SkRTConf<T> *concrete = static_cast<SkRTConf<T> *>(*confBase);
michael@0 306
michael@0 307 if (concrete) {
michael@0 308 concrete->set(value);
michael@0 309 }
michael@0 310 }
michael@0 311 }
michael@0 312
michael@0 313 template void SkRTConfRegistry::set(const char *name, bool value, bool);
michael@0 314 template void SkRTConfRegistry::set(const char *name, int value, bool);
michael@0 315 template void SkRTConfRegistry::set(const char *name, unsigned int value, bool);
michael@0 316 template void SkRTConfRegistry::set(const char *name, float value, bool);
michael@0 317 template void SkRTConfRegistry::set(const char *name, double value, bool);
michael@0 318 template void SkRTConfRegistry::set(const char *name, char * value, bool);
michael@0 319
michael@0 320 SkRTConfRegistry &skRTConfRegistry() {
michael@0 321 static SkRTConfRegistry r;
michael@0 322 return r;
michael@0 323 }
michael@0 324
michael@0 325
michael@0 326 #ifdef SK_SUPPORT_UNITTEST
michael@0 327
michael@0 328 #ifdef SK_BUILD_FOR_WIN32
michael@0 329 static void sk_setenv(const char* key, const char* value) {
michael@0 330 _putenv_s(key, value);
michael@0 331 }
michael@0 332 #else
michael@0 333 static void sk_setenv(const char* key, const char* value) {
michael@0 334 setenv(key, value, 1);
michael@0 335 }
michael@0 336 #endif
michael@0 337
michael@0 338 void SkRTConfRegistry::UnitTest() {
michael@0 339 SkRTConfRegistry registryWithoutContents(true);
michael@0 340
michael@0 341 sk_setenv("skia_nonexistent_item", "132");
michael@0 342 int result = 0;
michael@0 343 registryWithoutContents.parse("nonexistent.item", &result);
michael@0 344 SkASSERT(result == 132);
michael@0 345 }
michael@0 346
michael@0 347 SkRTConfRegistry::SkRTConfRegistry(bool)
michael@0 348 : fConfs(100) {
michael@0 349 }
michael@0 350 #endif

mercurial