17af56bee17764a0c118c8856a035bb3d27766969humper@google.com/* 27af56bee17764a0c118c8856a035bb3d27766969humper@google.com * Copyright 2013 Google Inc. 37af56bee17764a0c118c8856a035bb3d27766969humper@google.com * 47af56bee17764a0c118c8856a035bb3d27766969humper@google.com * Use of this source code is governed by a BSD-style license that can be 57af56bee17764a0c118c8856a035bb3d27766969humper@google.com * found in the LICENSE file. 67af56bee17764a0c118c8856a035bb3d27766969humper@google.com */ 77af56bee17764a0c118c8856a035bb3d27766969humper@google.com 87af56bee17764a0c118c8856a035bb3d27766969humper@google.com#include "SkRTConf.h" 97af56bee17764a0c118c8856a035bb3d27766969humper@google.com#include "SkOSFile.h" 107af56bee17764a0c118c8856a035bb3d27766969humper@google.com 1160e0fee6d4acff638ccc9670c4055aced529a7a0bungeman#include <stdlib.h> 1260e0fee6d4acff638ccc9670c4055aced529a7a0bungeman 137af56bee17764a0c118c8856a035bb3d27766969humper@google.comSkRTConfRegistry::SkRTConfRegistry(): fConfs(100) { 147fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 15d76be9c79baa1530d3dc95c58022e83607a1bb2ahalcanary FILE *fp = sk_fopen(configFileLocation(), kRead_SkFILE_Flag); 167af56bee17764a0c118c8856a035bb3d27766969humper@google.com 177af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (!fp) { 187af56bee17764a0c118c8856a035bb3d27766969humper@google.com return; 197af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 207fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 2118a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com char line[1024]; 227fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 237af56bee17764a0c118c8856a035bb3d27766969humper@google.com while (!sk_feof(fp)) { 247fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 2518a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com if (!sk_fgets(line, sizeof(line), fp)) { 2618a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com break; 2718a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com } 287fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 297af56bee17764a0c118c8856a035bb3d27766969humper@google.com char *commentptr = strchr(line, '#'); 307af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (commentptr == line) { 317af56bee17764a0c118c8856a035bb3d27766969humper@google.com continue; 327af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 3349f085dddff10473b6ebf832a974288300224e60bsalomon if (commentptr) { 3418a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com *commentptr = '\0'; 357af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 367fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 3718a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com char sep[] = " \t\r\n"; 387fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 397af56bee17764a0c118c8856a035bb3d27766969humper@google.com char *keyptr = strtok(line, sep); 407af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (!keyptr) { 417af56bee17764a0c118c8856a035bb3d27766969humper@google.com continue; 427af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 437af56bee17764a0c118c8856a035bb3d27766969humper@google.com 4496fcdcc219d2a0d3579719b84b28bede76efba64halcanary char *valptr = strtok(nullptr, sep); 457af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (!valptr) { 467af56bee17764a0c118c8856a035bb3d27766969humper@google.com continue; 477af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 487fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 49385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkString *key = new SkString(keyptr); 50385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkString *val = new SkString(valptr); 517af56bee17764a0c118c8856a035bb3d27766969humper@google.com 527af56bee17764a0c118c8856a035bb3d27766969humper@google.com fConfigFileKeys.append(1, &key); 537af56bee17764a0c118c8856a035bb3d27766969humper@google.com fConfigFileValues.append(1, &val); 547af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 557af56bee17764a0c118c8856a035bb3d27766969humper@google.com sk_fclose(fp); 567af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 577af56bee17764a0c118c8856a035bb3d27766969humper@google.com 58bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.orgSkRTConfRegistry::~SkRTConfRegistry() { 59bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org ConfMap::Iter iter(fConfs); 60bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org SkTDArray<SkRTConfBase *> *confArray; 61bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org 62bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org while (iter.next(&confArray)) { 63bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org delete confArray; 64bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org } 65bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org 66bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org for (int i = 0 ; i < fConfigFileKeys.count() ; i++) { 67385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fConfigFileKeys[i]; 68385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fConfigFileValues[i]; 69bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org } 70bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org} 71bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org 727af56bee17764a0c118c8856a035bb3d27766969humper@google.comconst char *SkRTConfRegistry::configFileLocation() const { 737af56bee17764a0c118c8856a035bb3d27766969humper@google.com return "skia.conf"; // for now -- should probably do something fancier like home directories or whatever. 747af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 757af56bee17764a0c118c8856a035bb3d27766969humper@google.com 767af56bee17764a0c118c8856a035bb3d27766969humper@google.com// dump all known runtime config options to the file with their default values. 777af56bee17764a0c118c8856a035bb3d27766969humper@google.com// to trigger this, make a config file of zero size. 787af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConfRegistry::possiblyDumpFile() const { 797af56bee17764a0c118c8856a035bb3d27766969humper@google.com const char *path = configFileLocation(); 80d76be9c79baa1530d3dc95c58022e83607a1bb2ahalcanary FILE *fp = sk_fopen(path, kRead_SkFILE_Flag); 817af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (!fp) { 827af56bee17764a0c118c8856a035bb3d27766969humper@google.com return; 837af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 847af56bee17764a0c118c8856a035bb3d27766969humper@google.com size_t configFileSize = sk_fgetsize(fp); 857af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (configFileSize == 0) { 867af56bee17764a0c118c8856a035bb3d27766969humper@google.com printAll(path); 877af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 887af56bee17764a0c118c8856a035bb3d27766969humper@google.com sk_fclose(fp); 897af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 907af56bee17764a0c118c8856a035bb3d27766969humper@google.com 917af56bee17764a0c118c8856a035bb3d27766969humper@google.com// Run through every provided configuration option and print a warning if the user hasn't 927af56bee17764a0c118c8856a035bb3d27766969humper@google.com// declared a correponding configuration object somewhere. 937af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConfRegistry::validate() const { 947af56bee17764a0c118c8856a035bb3d27766969humper@google.com for (int i = 0 ; i < fConfigFileKeys.count() ; i++) { 952b71c439afaf2912f6eba211d0631ef07beaec1bhumper@google.com if (!fConfs.find(fConfigFileKeys[i]->c_str())) { 967af56bee17764a0c118c8856a035bb3d27766969humper@google.com SkDebugf("WARNING: You have config value %s in your configuration file, but I've never heard of that.\n", fConfigFileKeys[i]->c_str()); 977af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 987af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 997af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 1007af56bee17764a0c118c8856a035bb3d27766969humper@google.com 1017af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConfRegistry::printAll(const char *fname) const { 1027af56bee17764a0c118c8856a035bb3d27766969humper@google.com SkWStream *o; 1037fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 10449f085dddff10473b6ebf832a974288300224e60bsalomon if (fname) { 1057af56bee17764a0c118c8856a035bb3d27766969humper@google.com o = new SkFILEWStream(fname); 1067af56bee17764a0c118c8856a035bb3d27766969humper@google.com } else { 1077af56bee17764a0c118c8856a035bb3d27766969humper@google.com o = new SkDebugWStream(); 1087af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 1097fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 1107af56bee17764a0c118c8856a035bb3d27766969humper@google.com ConfMap::Iter iter(fConfs); 1117af56bee17764a0c118c8856a035bb3d27766969humper@google.com SkTDArray<SkRTConfBase *> *confArray; 1127fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 1137af56bee17764a0c118c8856a035bb3d27766969humper@google.com while (iter.next(&confArray)) { 1147af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (confArray->getAt(0)->isDefault()) { 1157af56bee17764a0c118c8856a035bb3d27766969humper@google.com o->writeText("# "); 1167af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 1177af56bee17764a0c118c8856a035bb3d27766969humper@google.com confArray->getAt(0)->print(o); 1187af56bee17764a0c118c8856a035bb3d27766969humper@google.com o->newline(); 1197af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 1207fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 1217af56bee17764a0c118c8856a035bb3d27766969humper@google.com delete o; 1227af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 1237af56bee17764a0c118c8856a035bb3d27766969humper@google.com 1242d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.combool SkRTConfRegistry::hasNonDefault() const { 1252d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com ConfMap::Iter iter(fConfs); 1262d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com SkTDArray<SkRTConfBase *> *confArray; 1272d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com while (iter.next(&confArray)) { 1282d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com if (!confArray->getAt(0)->isDefault()) { 1292d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com return true; 1302d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com } 1312d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com } 1322d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com return false; 1332d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com} 1342d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com 1357af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConfRegistry::printNonDefault(const char *fname) const { 1367af56bee17764a0c118c8856a035bb3d27766969humper@google.com SkWStream *o; 1377fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 13849f085dddff10473b6ebf832a974288300224e60bsalomon if (fname) { 1397af56bee17764a0c118c8856a035bb3d27766969humper@google.com o = new SkFILEWStream(fname); 1407af56bee17764a0c118c8856a035bb3d27766969humper@google.com } else { 1417af56bee17764a0c118c8856a035bb3d27766969humper@google.com o = new SkDebugWStream(); 1427fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com } 1437af56bee17764a0c118c8856a035bb3d27766969humper@google.com ConfMap::Iter iter(fConfs); 1447af56bee17764a0c118c8856a035bb3d27766969humper@google.com SkTDArray<SkRTConfBase *> *confArray; 1457fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 1467af56bee17764a0c118c8856a035bb3d27766969humper@google.com while (iter.next(&confArray)) { 1477af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (!confArray->getAt(0)->isDefault()) { 1487af56bee17764a0c118c8856a035bb3d27766969humper@google.com confArray->getAt(0)->print(o); 1497af56bee17764a0c118c8856a035bb3d27766969humper@google.com o->newline(); 1507af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 1517af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 1527fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 1537af56bee17764a0c118c8856a035bb3d27766969humper@google.com delete o; 1547af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 1557af56bee17764a0c118c8856a035bb3d27766969humper@google.com 1567af56bee17764a0c118c8856a035bb3d27766969humper@google.com// register a configuration variable after its value has been set by the parser. 1577af56bee17764a0c118c8856a035bb3d27766969humper@google.com// we maintain a vector of these things instead of just a single one because the 1587af56bee17764a0c118c8856a035bb3d27766969humper@google.com// user might set the value after initialization time and we need to have 1597af56bee17764a0c118c8856a035bb3d27766969humper@google.com// all the pointers lying around, not just one. 1607af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConfRegistry::registerConf(SkRTConfBase *conf) { 1617af56bee17764a0c118c8856a035bb3d27766969humper@google.com SkTDArray<SkRTConfBase *> *confArray; 1627af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (fConfs.find(conf->getName(), &confArray)) { 1637af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (!conf->equals(confArray->getAt(0))) { 1647af56bee17764a0c118c8856a035bb3d27766969humper@google.com SkDebugf("WARNING: Skia config \"%s\" was registered more than once in incompatible ways.\n", conf->getName()); 1657af56bee17764a0c118c8856a035bb3d27766969humper@google.com } else { 1667af56bee17764a0c118c8856a035bb3d27766969humper@google.com confArray->append(1, &conf); 1677af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 1687af56bee17764a0c118c8856a035bb3d27766969humper@google.com } else { 1697af56bee17764a0c118c8856a035bb3d27766969humper@google.com confArray = new SkTDArray<SkRTConfBase *>; 1707af56bee17764a0c118c8856a035bb3d27766969humper@google.com confArray->append(1, &conf); 1717af56bee17764a0c118c8856a035bb3d27766969humper@google.com fConfs.set(conf->getName(),confArray); 1727af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 1737af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 1747af56bee17764a0c118c8856a035bb3d27766969humper@google.com 1758563d3089cd18464db181c16ad90271de16ba524sugoi@google.comtemplate <typename T> T doParse(const char *, bool *success ) { 1767af56bee17764a0c118c8856a035bb3d27766969humper@google.com SkDebugf("WARNING: Invoked non-specialized doParse function...\n"); 1777af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (success) { 1787af56bee17764a0c118c8856a035bb3d27766969humper@google.com *success = false; 1797fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com } 1807af56bee17764a0c118c8856a035bb3d27766969humper@google.com return (T) 0; 1817af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 1827af56bee17764a0c118c8856a035bb3d27766969humper@google.com 1837af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> bool doParse<bool>(const char *s, bool *success) { 1847af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (success) { 1857af56bee17764a0c118c8856a035bb3d27766969humper@google.com *success = true; 1867af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 1877af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (!strcmp(s,"1") || !strcmp(s,"true")) { 1887af56bee17764a0c118c8856a035bb3d27766969humper@google.com return true; 1897af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 1907af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (!strcmp(s,"0") || !strcmp(s,"false")) { 1917af56bee17764a0c118c8856a035bb3d27766969humper@google.com return false; 1927af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 1937af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (success) { 1947af56bee17764a0c118c8856a035bb3d27766969humper@google.com *success = false; 1957af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 1967af56bee17764a0c118c8856a035bb3d27766969humper@google.com return false; 1977af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 1987af56bee17764a0c118c8856a035bb3d27766969humper@google.com 1997af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> const char * doParse<const char *>(const char * s, bool *success) { 2007af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (success) { 2017af56bee17764a0c118c8856a035bb3d27766969humper@google.com *success = true; 2027af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 2037af56bee17764a0c118c8856a035bb3d27766969humper@google.com return s; 2047af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 2057af56bee17764a0c118c8856a035bb3d27766969humper@google.com 2067af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> int doParse<int>(const char * s, bool *success) { 2078563d3089cd18464db181c16ad90271de16ba524sugoi@google.com if (success) { 2088563d3089cd18464db181c16ad90271de16ba524sugoi@google.com *success = true; 2098563d3089cd18464db181c16ad90271de16ba524sugoi@google.com } 2107af56bee17764a0c118c8856a035bb3d27766969humper@google.com return atoi(s); 2117af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 2127af56bee17764a0c118c8856a035bb3d27766969humper@google.com 2137af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> unsigned int doParse<unsigned int>(const char * s, bool *success) { 2148563d3089cd18464db181c16ad90271de16ba524sugoi@google.com if (success) { 2158563d3089cd18464db181c16ad90271de16ba524sugoi@google.com *success = true; 2168563d3089cd18464db181c16ad90271de16ba524sugoi@google.com } 2177af56bee17764a0c118c8856a035bb3d27766969humper@google.com return (unsigned int) atoi(s); 2187af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 2197af56bee17764a0c118c8856a035bb3d27766969humper@google.com 2207af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> float doParse<float>(const char * s, bool *success) { 2218563d3089cd18464db181c16ad90271de16ba524sugoi@google.com if (success) { 2228563d3089cd18464db181c16ad90271de16ba524sugoi@google.com *success = true; 2238563d3089cd18464db181c16ad90271de16ba524sugoi@google.com } 2247af56bee17764a0c118c8856a035bb3d27766969humper@google.com return (float) atof(s); 2257af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 2267af56bee17764a0c118c8856a035bb3d27766969humper@google.com 2277af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> double doParse<double>(const char * s, bool *success) { 2288563d3089cd18464db181c16ad90271de16ba524sugoi@google.com if (success) { 2298563d3089cd18464db181c16ad90271de16ba524sugoi@google.com *success = true; 2308563d3089cd18464db181c16ad90271de16ba524sugoi@google.com } 2317af56bee17764a0c118c8856a035bb3d27766969humper@google.com return atof(s); 2327af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 2337af56bee17764a0c118c8856a035bb3d27766969humper@google.com 2347af56bee17764a0c118c8856a035bb3d27766969humper@google.comstatic inline void str_replace(char *s, char search, char replace) { 2357af56bee17764a0c118c8856a035bb3d27766969humper@google.com for (char *ptr = s ; *ptr ; ptr++) { 2367af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (*ptr == search) { 2377af56bee17764a0c118c8856a035bb3d27766969humper@google.com *ptr = replace; 2387af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 2397af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 2407af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 2417af56bee17764a0c118c8856a035bb3d27766969humper@google.com 2427af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<typename T> bool SkRTConfRegistry::parse(const char *name, T* value) { 24396fcdcc219d2a0d3579719b84b28bede76efba64halcanary const char *str = nullptr; 2447af56bee17764a0c118c8856a035bb3d27766969humper@google.com 24591673aafdf227675da15a8b7fabd38dbabdefbb7humper@google.com for (int i = fConfigFileKeys.count() - 1 ; i >= 0; i--) { 2467af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (fConfigFileKeys[i]->equals(name)) { 2477a2269ea7352f0580422f193081b6d7028651138halcanary@google.com str = fConfigFileValues[i]->c_str(); 24891673aafdf227675da15a8b7fabd38dbabdefbb7humper@google.com break; 2497af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 2507af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 2517fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 2527af56bee17764a0c118c8856a035bb3d27766969humper@google.com SkString environment_variable("skia."); 2537af56bee17764a0c118c8856a035bb3d27766969humper@google.com environment_variable.append(name); 2547fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 2557af56bee17764a0c118c8856a035bb3d27766969humper@google.com const char *environment_value = getenv(environment_variable.c_str()); 2567af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (environment_value) { 2577a2269ea7352f0580422f193081b6d7028651138halcanary@google.com str = environment_value; 2587af56bee17764a0c118c8856a035bb3d27766969humper@google.com } else { 2597fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com // apparently my shell doesn't let me have environment variables that 2607af56bee17764a0c118c8856a035bb3d27766969humper@google.com // have periods in them, so also let the user substitute underscores. 2617a2269ea7352f0580422f193081b6d7028651138halcanary@google.com SkAutoTMalloc<char> underscore_name(SkStrDup(environment_variable.c_str())); 2627a2269ea7352f0580422f193081b6d7028651138halcanary@google.com str_replace(underscore_name.get(), '.', '_'); 2637a2269ea7352f0580422f193081b6d7028651138halcanary@google.com environment_value = getenv(underscore_name.get()); 2647af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (environment_value) { 2657a2269ea7352f0580422f193081b6d7028651138halcanary@google.com str = environment_value; 2667af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 2677af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 2687fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 2697af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (!str) { 2707af56bee17764a0c118c8856a035bb3d27766969humper@google.com return false; 2717af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 2727fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 2737af56bee17764a0c118c8856a035bb3d27766969humper@google.com bool success; 2747a2269ea7352f0580422f193081b6d7028651138halcanary@google.com T new_value = doParse<T>(str, &success); 2757af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (success) { 2767af56bee17764a0c118c8856a035bb3d27766969humper@google.com *value = new_value; 2777af56bee17764a0c118c8856a035bb3d27766969humper@google.com } else { 2787a2269ea7352f0580422f193081b6d7028651138halcanary@google.com SkDebugf("WARNING: Couldn't parse value \'%s\' for variable \'%s\'\n", 2797a2269ea7352f0580422f193081b6d7028651138halcanary@google.com str, name); 2807af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 2817af56bee17764a0c118c8856a035bb3d27766969humper@google.com return success; 2827af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 2837af56bee17764a0c118c8856a035bb3d27766969humper@google.com 2847af56bee17764a0c118c8856a035bb3d27766969humper@google.com// need to explicitly instantiate the parsing function for every config type we might have... 2857af56bee17764a0c118c8856a035bb3d27766969humper@google.com 2867af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, bool *value); 2877af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, int *value); 2887af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, unsigned int *value); 2897af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, float *value); 2907af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, double *value); 2917af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, const char **value); 2927af56bee17764a0c118c8856a035bb3d27766969humper@google.com 2931f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate <typename T> void SkRTConfRegistry::set(const char *name, 2941f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com T value, 2951f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com bool warnIfNotFound) { 2967af56bee17764a0c118c8856a035bb3d27766969humper@google.com SkTDArray<SkRTConfBase *> *confArray; 2977af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (!fConfs.find(name, &confArray)) { 2981f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com if (warnIfNotFound) { 2991f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com SkDebugf("WARNING: Attempting to set configuration value \"%s\"," 3001f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com " but I've never heard of that.\n", name); 3011f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com } 3027af56bee17764a0c118c8856a035bb3d27766969humper@google.com return; 3037af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 30496fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(confArray != nullptr); 3057af56bee17764a0c118c8856a035bb3d27766969humper@google.com for (SkRTConfBase **confBase = confArray->begin(); confBase != confArray->end(); confBase++) { 3066d29eda49129893d8f5e385bfbe8473af154b82bhumper@google.com // static_cast here is okay because there's only one kind of child class. 307810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com SkRTConf<T> *concrete = static_cast<SkRTConf<T> *>(*confBase); 3087fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com 3097af56bee17764a0c118c8856a035bb3d27766969humper@google.com if (concrete) { 3107af56bee17764a0c118c8856a035bb3d27766969humper@google.com concrete->set(value); 3117af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 3127af56bee17764a0c118c8856a035bb3d27766969humper@google.com } 3137af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 3147af56bee17764a0c118c8856a035bb3d27766969humper@google.com 3151f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, bool value, bool); 3161f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, int value, bool); 3171f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, unsigned int value, bool); 3181f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, float value, bool); 3191f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, double value, bool); 3201f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, char * value, bool); 3217af56bee17764a0c118c8856a035bb3d27766969humper@google.com 3227af56bee17764a0c118c8856a035bb3d27766969humper@google.comSkRTConfRegistry &skRTConfRegistry() { 3237af56bee17764a0c118c8856a035bb3d27766969humper@google.com static SkRTConfRegistry r; 3247af56bee17764a0c118c8856a035bb3d27766969humper@google.com return r; 3257af56bee17764a0c118c8856a035bb3d27766969humper@google.com} 326