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