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
117af56bee17764a0c118c8856a035bb3d27766969humper@google.comSkRTConfRegistry::SkRTConfRegistry(): fConfs(100) {
127fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
137af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkFILE *fp = sk_fopen(configFileLocation(), kRead_SkFILE_Flag);
147af56bee17764a0c118c8856a035bb3d27766969humper@google.com
157af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (!fp) {
167af56bee17764a0c118c8856a035bb3d27766969humper@google.com        return;
177af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
187fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
1918a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com    char line[1024];
207fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
217af56bee17764a0c118c8856a035bb3d27766969humper@google.com    while (!sk_feof(fp)) {
227fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
2318a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com        if (!sk_fgets(line, sizeof(line), fp)) {
2418a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com            break;
2518a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com        }
267fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
277af56bee17764a0c118c8856a035bb3d27766969humper@google.com        char *commentptr = strchr(line, '#');
287af56bee17764a0c118c8856a035bb3d27766969humper@google.com        if (commentptr == line) {
297af56bee17764a0c118c8856a035bb3d27766969humper@google.com            continue;
307af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
3149f085dddff10473b6ebf832a974288300224e60bsalomon        if (commentptr) {
3218a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com            *commentptr = '\0';
337af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
347fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
3518a48c3c1c1aa183a1b1ab033be34329685199f6humper@google.com        char sep[] = " \t\r\n";
367fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
377af56bee17764a0c118c8856a035bb3d27766969humper@google.com        char *keyptr = strtok(line, sep);
387af56bee17764a0c118c8856a035bb3d27766969humper@google.com        if (!keyptr) {
397af56bee17764a0c118c8856a035bb3d27766969humper@google.com            continue;
407af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
417af56bee17764a0c118c8856a035bb3d27766969humper@google.com
427af56bee17764a0c118c8856a035bb3d27766969humper@google.com        char *valptr = strtok(NULL, sep);
437af56bee17764a0c118c8856a035bb3d27766969humper@google.com        if (!valptr) {
447af56bee17764a0c118c8856a035bb3d27766969humper@google.com            continue;
457af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
467fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
47bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org        SkString* key = SkNEW_ARGS(SkString,(keyptr));
48bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org        SkString* val = SkNEW_ARGS(SkString,(valptr));
497af56bee17764a0c118c8856a035bb3d27766969humper@google.com
507af56bee17764a0c118c8856a035bb3d27766969humper@google.com        fConfigFileKeys.append(1, &key);
517af56bee17764a0c118c8856a035bb3d27766969humper@google.com        fConfigFileValues.append(1, &val);
527af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
537af56bee17764a0c118c8856a035bb3d27766969humper@google.com    sk_fclose(fp);
547af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
557af56bee17764a0c118c8856a035bb3d27766969humper@google.com
56bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.orgSkRTConfRegistry::~SkRTConfRegistry() {
57bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org    ConfMap::Iter iter(fConfs);
58bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org    SkTDArray<SkRTConfBase *> *confArray;
59bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org
60bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org    while (iter.next(&confArray)) {
61bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org        delete confArray;
62bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org    }
63bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org
64bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org    for (int i = 0 ; i < fConfigFileKeys.count() ; i++) {
65bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org        SkDELETE(fConfigFileKeys[i]);
66bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org        SkDELETE(fConfigFileValues[i]);
67bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org    }
68bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org}
69bf6a6d45043393f8cd9c942d7f03b789fe2c94b3commit-bot@chromium.org
707af56bee17764a0c118c8856a035bb3d27766969humper@google.comconst char *SkRTConfRegistry::configFileLocation() const {
717af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return "skia.conf"; // for now -- should probably do something fancier like home directories or whatever.
727af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
737af56bee17764a0c118c8856a035bb3d27766969humper@google.com
747af56bee17764a0c118c8856a035bb3d27766969humper@google.com// dump all known runtime config options to the file with their default values.
757af56bee17764a0c118c8856a035bb3d27766969humper@google.com// to trigger this, make a config file of zero size.
767af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConfRegistry::possiblyDumpFile() const {
777af56bee17764a0c118c8856a035bb3d27766969humper@google.com    const char *path = configFileLocation();
787af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkFILE *fp = sk_fopen(path, kRead_SkFILE_Flag);
797af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (!fp) {
807af56bee17764a0c118c8856a035bb3d27766969humper@google.com        return;
817af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
827af56bee17764a0c118c8856a035bb3d27766969humper@google.com    size_t configFileSize = sk_fgetsize(fp);
837af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (configFileSize == 0) {
847af56bee17764a0c118c8856a035bb3d27766969humper@google.com        printAll(path);
857af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
867af56bee17764a0c118c8856a035bb3d27766969humper@google.com    sk_fclose(fp);
877af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
887af56bee17764a0c118c8856a035bb3d27766969humper@google.com
897af56bee17764a0c118c8856a035bb3d27766969humper@google.com// Run through every provided configuration option and print a warning if the user hasn't
907af56bee17764a0c118c8856a035bb3d27766969humper@google.com// declared a correponding configuration object somewhere.
917af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConfRegistry::validate() const {
927af56bee17764a0c118c8856a035bb3d27766969humper@google.com    for (int i = 0 ; i < fConfigFileKeys.count() ; i++) {
932b71c439afaf2912f6eba211d0631ef07beaec1bhumper@google.com        if (!fConfs.find(fConfigFileKeys[i]->c_str())) {
947af56bee17764a0c118c8856a035bb3d27766969humper@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());
957af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
967af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
977af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
987af56bee17764a0c118c8856a035bb3d27766969humper@google.com
997af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConfRegistry::printAll(const char *fname) const {
1007af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkWStream *o;
1017fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
10249f085dddff10473b6ebf832a974288300224e60bsalomon    if (fname) {
1037af56bee17764a0c118c8856a035bb3d27766969humper@google.com        o = new SkFILEWStream(fname);
1047af56bee17764a0c118c8856a035bb3d27766969humper@google.com    } else {
1057af56bee17764a0c118c8856a035bb3d27766969humper@google.com        o = new SkDebugWStream();
1067af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
1077fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
1087af56bee17764a0c118c8856a035bb3d27766969humper@google.com    ConfMap::Iter iter(fConfs);
1097af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkTDArray<SkRTConfBase *> *confArray;
1107fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
1117af56bee17764a0c118c8856a035bb3d27766969humper@google.com    while (iter.next(&confArray)) {
1127af56bee17764a0c118c8856a035bb3d27766969humper@google.com        if (confArray->getAt(0)->isDefault()) {
1137af56bee17764a0c118c8856a035bb3d27766969humper@google.com            o->writeText("# ");
1147af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
1157af56bee17764a0c118c8856a035bb3d27766969humper@google.com        confArray->getAt(0)->print(o);
1167af56bee17764a0c118c8856a035bb3d27766969humper@google.com        o->newline();
1177af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
1187fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
1197af56bee17764a0c118c8856a035bb3d27766969humper@google.com    delete o;
1207af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
1217af56bee17764a0c118c8856a035bb3d27766969humper@google.com
1222d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.combool SkRTConfRegistry::hasNonDefault() const {
1232d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com    ConfMap::Iter iter(fConfs);
1242d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com    SkTDArray<SkRTConfBase *> *confArray;
1252d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com    while (iter.next(&confArray)) {
1262d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com        if (!confArray->getAt(0)->isDefault()) {
1272d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com            return true;
1282d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com        }
1292d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com    }
1302d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com    return false;
1312d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com}
1322d1adf2322b026ec746dbdd931ca6aac7bb5d4cbhalcanary@google.com
1337af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConfRegistry::printNonDefault(const char *fname) const {
1347af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkWStream *o;
1357fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
13649f085dddff10473b6ebf832a974288300224e60bsalomon    if (fname) {
1377af56bee17764a0c118c8856a035bb3d27766969humper@google.com        o = new SkFILEWStream(fname);
1387af56bee17764a0c118c8856a035bb3d27766969humper@google.com    } else {
1397af56bee17764a0c118c8856a035bb3d27766969humper@google.com        o = new SkDebugWStream();
1407fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com    }
1417af56bee17764a0c118c8856a035bb3d27766969humper@google.com    ConfMap::Iter iter(fConfs);
1427af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkTDArray<SkRTConfBase *> *confArray;
1437fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
1447af56bee17764a0c118c8856a035bb3d27766969humper@google.com    while (iter.next(&confArray)) {
1457af56bee17764a0c118c8856a035bb3d27766969humper@google.com        if (!confArray->getAt(0)->isDefault()) {
1467af56bee17764a0c118c8856a035bb3d27766969humper@google.com            confArray->getAt(0)->print(o);
1477af56bee17764a0c118c8856a035bb3d27766969humper@google.com            o->newline();
1487af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
1497af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
1507fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
1517af56bee17764a0c118c8856a035bb3d27766969humper@google.com    delete o;
1527af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
1537af56bee17764a0c118c8856a035bb3d27766969humper@google.com
1547af56bee17764a0c118c8856a035bb3d27766969humper@google.com// register a configuration variable after its value has been set by the parser.
1557af56bee17764a0c118c8856a035bb3d27766969humper@google.com// we maintain a vector of these things instead of just a single one because the
1567af56bee17764a0c118c8856a035bb3d27766969humper@google.com// user might set the value after initialization time and we need to have
1577af56bee17764a0c118c8856a035bb3d27766969humper@google.com// all the pointers lying around, not just one.
1587af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConfRegistry::registerConf(SkRTConfBase *conf) {
1597af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkTDArray<SkRTConfBase *> *confArray;
1607af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (fConfs.find(conf->getName(), &confArray)) {
1617af56bee17764a0c118c8856a035bb3d27766969humper@google.com        if (!conf->equals(confArray->getAt(0))) {
1627af56bee17764a0c118c8856a035bb3d27766969humper@google.com            SkDebugf("WARNING: Skia config \"%s\" was registered more than once in incompatible ways.\n", conf->getName());
1637af56bee17764a0c118c8856a035bb3d27766969humper@google.com        } else {
1647af56bee17764a0c118c8856a035bb3d27766969humper@google.com            confArray->append(1, &conf);
1657af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
1667af56bee17764a0c118c8856a035bb3d27766969humper@google.com    } else {
1677af56bee17764a0c118c8856a035bb3d27766969humper@google.com        confArray = new SkTDArray<SkRTConfBase *>;
1687af56bee17764a0c118c8856a035bb3d27766969humper@google.com        confArray->append(1, &conf);
1697af56bee17764a0c118c8856a035bb3d27766969humper@google.com        fConfs.set(conf->getName(),confArray);
1707af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
1717af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
1727af56bee17764a0c118c8856a035bb3d27766969humper@google.com
1738563d3089cd18464db181c16ad90271de16ba524sugoi@google.comtemplate <typename T> T doParse(const char *, bool *success ) {
1747af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkDebugf("WARNING: Invoked non-specialized doParse function...\n");
1757af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (success) {
1767af56bee17764a0c118c8856a035bb3d27766969humper@google.com        *success = false;
1777fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com    }
1787af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return (T) 0;
1797af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
1807af56bee17764a0c118c8856a035bb3d27766969humper@google.com
1817af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> bool doParse<bool>(const char *s, bool *success) {
1827af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (success) {
1837af56bee17764a0c118c8856a035bb3d27766969humper@google.com        *success = true;
1847af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
1857af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (!strcmp(s,"1") || !strcmp(s,"true")) {
1867af56bee17764a0c118c8856a035bb3d27766969humper@google.com        return true;
1877af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
1887af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (!strcmp(s,"0") || !strcmp(s,"false")) {
1897af56bee17764a0c118c8856a035bb3d27766969humper@google.com        return false;
1907af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
1917af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (success) {
1927af56bee17764a0c118c8856a035bb3d27766969humper@google.com        *success = false;
1937af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
1947af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return false;
1957af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
1967af56bee17764a0c118c8856a035bb3d27766969humper@google.com
1977af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> const char * doParse<const char *>(const char * s, bool *success) {
1987af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (success) {
1997af56bee17764a0c118c8856a035bb3d27766969humper@google.com        *success = true;
2007af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
2017af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return s;
2027af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
2037af56bee17764a0c118c8856a035bb3d27766969humper@google.com
2047af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> int doParse<int>(const char * s, bool *success) {
2058563d3089cd18464db181c16ad90271de16ba524sugoi@google.com    if (success) {
2068563d3089cd18464db181c16ad90271de16ba524sugoi@google.com        *success = true;
2078563d3089cd18464db181c16ad90271de16ba524sugoi@google.com    }
2087af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return atoi(s);
2097af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
2107af56bee17764a0c118c8856a035bb3d27766969humper@google.com
2117af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> unsigned int doParse<unsigned int>(const char * s, bool *success) {
2128563d3089cd18464db181c16ad90271de16ba524sugoi@google.com    if (success) {
2138563d3089cd18464db181c16ad90271de16ba524sugoi@google.com        *success = true;
2148563d3089cd18464db181c16ad90271de16ba524sugoi@google.com    }
2157af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return (unsigned int) atoi(s);
2167af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
2177af56bee17764a0c118c8856a035bb3d27766969humper@google.com
2187af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> float doParse<float>(const char * s, bool *success) {
2198563d3089cd18464db181c16ad90271de16ba524sugoi@google.com    if (success) {
2208563d3089cd18464db181c16ad90271de16ba524sugoi@google.com        *success = true;
2218563d3089cd18464db181c16ad90271de16ba524sugoi@google.com    }
2227af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return (float) atof(s);
2237af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
2247af56bee17764a0c118c8856a035bb3d27766969humper@google.com
2257af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<> double doParse<double>(const char * s, bool *success) {
2268563d3089cd18464db181c16ad90271de16ba524sugoi@google.com    if (success) {
2278563d3089cd18464db181c16ad90271de16ba524sugoi@google.com        *success = true;
2288563d3089cd18464db181c16ad90271de16ba524sugoi@google.com    }
2297af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return atof(s);
2307af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
2317af56bee17764a0c118c8856a035bb3d27766969humper@google.com
2327af56bee17764a0c118c8856a035bb3d27766969humper@google.comstatic inline void str_replace(char *s, char search, char replace) {
2337af56bee17764a0c118c8856a035bb3d27766969humper@google.com    for (char *ptr = s ; *ptr ; ptr++) {
2347af56bee17764a0c118c8856a035bb3d27766969humper@google.com        if (*ptr == search) {
2357af56bee17764a0c118c8856a035bb3d27766969humper@google.com            *ptr = replace;
2367af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
2377af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
2387af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
2397af56bee17764a0c118c8856a035bb3d27766969humper@google.com
2407af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<typename T> bool SkRTConfRegistry::parse(const char *name, T* value) {
2417a2269ea7352f0580422f193081b6d7028651138halcanary@google.com    const char *str = NULL;
2427af56bee17764a0c118c8856a035bb3d27766969humper@google.com
24391673aafdf227675da15a8b7fabd38dbabdefbb7humper@google.com    for (int i = fConfigFileKeys.count() - 1 ; i >= 0; i--) {
2447af56bee17764a0c118c8856a035bb3d27766969humper@google.com        if (fConfigFileKeys[i]->equals(name)) {
2457a2269ea7352f0580422f193081b6d7028651138halcanary@google.com            str = fConfigFileValues[i]->c_str();
24691673aafdf227675da15a8b7fabd38dbabdefbb7humper@google.com            break;
2477af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
2487af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
2497fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
2507af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkString environment_variable("skia.");
2517af56bee17764a0c118c8856a035bb3d27766969humper@google.com    environment_variable.append(name);
2527fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
2537af56bee17764a0c118c8856a035bb3d27766969humper@google.com    const char *environment_value = getenv(environment_variable.c_str());
2547af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (environment_value) {
2557a2269ea7352f0580422f193081b6d7028651138halcanary@google.com        str = environment_value;
2567af56bee17764a0c118c8856a035bb3d27766969humper@google.com    } else {
2577fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com        // apparently my shell doesn't let me have environment variables that
2587af56bee17764a0c118c8856a035bb3d27766969humper@google.com        // have periods in them, so also let the user substitute underscores.
2597a2269ea7352f0580422f193081b6d7028651138halcanary@google.com        SkAutoTMalloc<char> underscore_name(SkStrDup(environment_variable.c_str()));
2607a2269ea7352f0580422f193081b6d7028651138halcanary@google.com        str_replace(underscore_name.get(), '.', '_');
2617a2269ea7352f0580422f193081b6d7028651138halcanary@google.com        environment_value = getenv(underscore_name.get());
2627af56bee17764a0c118c8856a035bb3d27766969humper@google.com        if (environment_value) {
2637a2269ea7352f0580422f193081b6d7028651138halcanary@google.com            str = environment_value;
2647af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
2657af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
2667fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
2677af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (!str) {
2687af56bee17764a0c118c8856a035bb3d27766969humper@google.com        return false;
2697af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
2707fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
2717af56bee17764a0c118c8856a035bb3d27766969humper@google.com    bool success;
2727a2269ea7352f0580422f193081b6d7028651138halcanary@google.com    T new_value = doParse<T>(str, &success);
2737af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (success) {
2747af56bee17764a0c118c8856a035bb3d27766969humper@google.com        *value = new_value;
2757af56bee17764a0c118c8856a035bb3d27766969humper@google.com    } else {
2767a2269ea7352f0580422f193081b6d7028651138halcanary@google.com        SkDebugf("WARNING: Couldn't parse value \'%s\' for variable \'%s\'\n",
2777a2269ea7352f0580422f193081b6d7028651138halcanary@google.com                 str, name);
2787af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
2797af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return success;
2807af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
2817af56bee17764a0c118c8856a035bb3d27766969humper@google.com
2827af56bee17764a0c118c8856a035bb3d27766969humper@google.com// need to explicitly instantiate the parsing function for every config type we might have...
2837af56bee17764a0c118c8856a035bb3d27766969humper@google.com
2847af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, bool *value);
2857af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, int *value);
2867af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, unsigned int *value);
2877af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, float *value);
2887af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, double *value);
2897af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate bool SkRTConfRegistry::parse(const char *name, const char **value);
2907af56bee17764a0c118c8856a035bb3d27766969humper@google.com
2911f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate <typename T> void SkRTConfRegistry::set(const char *name,
2921f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com                                                 T value,
2931f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com                                                 bool warnIfNotFound) {
2947af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkTDArray<SkRTConfBase *> *confArray;
2957af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (!fConfs.find(name, &confArray)) {
2961f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com        if (warnIfNotFound) {
2971f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com            SkDebugf("WARNING: Attempting to set configuration value \"%s\","
2981f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com                     " but I've never heard of that.\n", name);
2991f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com        }
3007af56bee17764a0c118c8856a035bb3d27766969humper@google.com        return;
3017af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
3021f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.com    SkASSERT(confArray != NULL);
3037af56bee17764a0c118c8856a035bb3d27766969humper@google.com    for (SkRTConfBase **confBase = confArray->begin(); confBase != confArray->end(); confBase++) {
3046d29eda49129893d8f5e385bfbe8473af154b82bhumper@google.com        // static_cast here is okay because there's only one kind of child class.
305810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com        SkRTConf<T> *concrete = static_cast<SkRTConf<T> *>(*confBase);
3067fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
3077af56bee17764a0c118c8856a035bb3d27766969humper@google.com        if (concrete) {
3087af56bee17764a0c118c8856a035bb3d27766969humper@google.com            concrete->set(value);
3097af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
3107af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
3117af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
3127af56bee17764a0c118c8856a035bb3d27766969humper@google.com
3131f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, bool value, bool);
3141f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, int value, bool);
3151f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, unsigned int value, bool);
3161f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, float value, bool);
3171f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, double value, bool);
3181f0121af495e5a70ecff2521729b7749c81a20b2halcanary@google.comtemplate void SkRTConfRegistry::set(const char *name, char * value, bool);
3197af56bee17764a0c118c8856a035bb3d27766969humper@google.com
3207af56bee17764a0c118c8856a035bb3d27766969humper@google.comSkRTConfRegistry &skRTConfRegistry() {
3217af56bee17764a0c118c8856a035bb3d27766969humper@google.com    static SkRTConfRegistry r;
3227af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return r;
3237af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
324