Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Unified Diff: src/utils/SkRTConf.cpp

Issue 2215433003: Revert of SkRTConf: reduce functionality to what we use, increase simplicity (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/opts/opts_check_x86.cpp ('k') | tests/PathOpsExtendedTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/utils/SkRTConf.cpp
diff --git a/src/utils/SkRTConf.cpp b/src/utils/SkRTConf.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2dfa47efc71015c12864d3ae585dd681dd027075
--- /dev/null
+++ b/src/utils/SkRTConf.cpp
@@ -0,0 +1,325 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkRTConf.h"
+#include "SkOSFile.h"
+
+#include <stdlib.h>
+
+SkRTConfRegistry::SkRTConfRegistry(): fConfs(100) {
+
+ FILE *fp = sk_fopen(configFileLocation(), kRead_SkFILE_Flag);
+
+ if (!fp) {
+ return;
+ }
+
+ char line[1024];
+
+ while (!sk_feof(fp)) {
+
+ if (!sk_fgets(line, sizeof(line), fp)) {
+ break;
+ }
+
+ char *commentptr = strchr(line, '#');
+ if (commentptr == line) {
+ continue;
+ }
+ if (commentptr) {
+ *commentptr = '\0';
+ }
+
+ char sep[] = " \t\r\n";
+
+ char *keyptr = strtok(line, sep);
+ if (!keyptr) {
+ continue;
+ }
+
+ char *valptr = strtok(nullptr, sep);
+ if (!valptr) {
+ continue;
+ }
+
+ SkString *key = new SkString(keyptr);
+ SkString *val = new SkString(valptr);
+
+ fConfigFileKeys.append(1, &key);
+ fConfigFileValues.append(1, &val);
+ }
+ sk_fclose(fp);
+}
+
+SkRTConfRegistry::~SkRTConfRegistry() {
+ ConfMap::Iter iter(fConfs);
+ SkTDArray<SkRTConfBase *> *confArray;
+
+ while (iter.next(&confArray)) {
+ delete confArray;
+ }
+
+ for (int i = 0 ; i < fConfigFileKeys.count() ; i++) {
+ delete fConfigFileKeys[i];
+ delete fConfigFileValues[i];
+ }
+}
+
+const char *SkRTConfRegistry::configFileLocation() const {
+ return "skia.conf"; // for now -- should probably do something fancier like home directories or whatever.
+}
+
+// dump all known runtime config options to the file with their default values.
+// to trigger this, make a config file of zero size.
+void SkRTConfRegistry::possiblyDumpFile() const {
+ const char *path = configFileLocation();
+ FILE *fp = sk_fopen(path, kRead_SkFILE_Flag);
+ if (!fp) {
+ return;
+ }
+ size_t configFileSize = sk_fgetsize(fp);
+ if (configFileSize == 0) {
+ printAll(path);
+ }
+ sk_fclose(fp);
+}
+
+// Run through every provided configuration option and print a warning if the user hasn't
+// declared a correponding configuration object somewhere.
+void SkRTConfRegistry::validate() const {
+ for (int i = 0 ; i < fConfigFileKeys.count() ; i++) {
+ if (!fConfs.find(fConfigFileKeys[i]->c_str())) {
+ SkDebugf("WARNING: You have config value %s in your configuration file, but I've never heard of that.\n", fConfigFileKeys[i]->c_str());
+ }
+ }
+}
+
+void SkRTConfRegistry::printAll(const char *fname) const {
+ SkWStream *o;
+
+ if (fname) {
+ o = new SkFILEWStream(fname);
+ } else {
+ o = new SkDebugWStream();
+ }
+
+ ConfMap::Iter iter(fConfs);
+ SkTDArray<SkRTConfBase *> *confArray;
+
+ while (iter.next(&confArray)) {
+ if (confArray->getAt(0)->isDefault()) {
+ o->writeText("# ");
+ }
+ confArray->getAt(0)->print(o);
+ o->newline();
+ }
+
+ delete o;
+}
+
+bool SkRTConfRegistry::hasNonDefault() const {
+ ConfMap::Iter iter(fConfs);
+ SkTDArray<SkRTConfBase *> *confArray;
+ while (iter.next(&confArray)) {
+ if (!confArray->getAt(0)->isDefault()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void SkRTConfRegistry::printNonDefault(const char *fname) const {
+ SkWStream *o;
+
+ if (fname) {
+ o = new SkFILEWStream(fname);
+ } else {
+ o = new SkDebugWStream();
+ }
+ ConfMap::Iter iter(fConfs);
+ SkTDArray<SkRTConfBase *> *confArray;
+
+ while (iter.next(&confArray)) {
+ if (!confArray->getAt(0)->isDefault()) {
+ confArray->getAt(0)->print(o);
+ o->newline();
+ }
+ }
+
+ delete o;
+}
+
+// register a configuration variable after its value has been set by the parser.
+// we maintain a vector of these things instead of just a single one because the
+// user might set the value after initialization time and we need to have
+// all the pointers lying around, not just one.
+void SkRTConfRegistry::registerConf(SkRTConfBase *conf) {
+ SkTDArray<SkRTConfBase *> *confArray;
+ if (fConfs.find(conf->getName(), &confArray)) {
+ if (!conf->equals(confArray->getAt(0))) {
+ SkDebugf("WARNING: Skia config \"%s\" was registered more than once in incompatible ways.\n", conf->getName());
+ } else {
+ confArray->append(1, &conf);
+ }
+ } else {
+ confArray = new SkTDArray<SkRTConfBase *>;
+ confArray->append(1, &conf);
+ fConfs.set(conf->getName(),confArray);
+ }
+}
+
+template <typename T> T doParse(const char *, bool *success ) {
+ SkDebugf("WARNING: Invoked non-specialized doParse function...\n");
+ if (success) {
+ *success = false;
+ }
+ return (T) 0;
+}
+
+template<> bool doParse<bool>(const char *s, bool *success) {
+ if (success) {
+ *success = true;
+ }
+ if (!strcmp(s,"1") || !strcmp(s,"true")) {
+ return true;
+ }
+ if (!strcmp(s,"0") || !strcmp(s,"false")) {
+ return false;
+ }
+ if (success) {
+ *success = false;
+ }
+ return false;
+}
+
+template<> const char * doParse<const char *>(const char * s, bool *success) {
+ if (success) {
+ *success = true;
+ }
+ return s;
+}
+
+template<> int doParse<int>(const char * s, bool *success) {
+ if (success) {
+ *success = true;
+ }
+ return atoi(s);
+}
+
+template<> unsigned int doParse<unsigned int>(const char * s, bool *success) {
+ if (success) {
+ *success = true;
+ }
+ return (unsigned int) atoi(s);
+}
+
+template<> float doParse<float>(const char * s, bool *success) {
+ if (success) {
+ *success = true;
+ }
+ return (float) atof(s);
+}
+
+template<> double doParse<double>(const char * s, bool *success) {
+ if (success) {
+ *success = true;
+ }
+ return atof(s);
+}
+
+static inline void str_replace(char *s, char search, char replace) {
+ for (char *ptr = s ; *ptr ; ptr++) {
+ if (*ptr == search) {
+ *ptr = replace;
+ }
+ }
+}
+
+template<typename T> bool SkRTConfRegistry::parse(const char *name, T* value) {
+ const char *str = nullptr;
+
+ for (int i = fConfigFileKeys.count() - 1 ; i >= 0; i--) {
+ if (fConfigFileKeys[i]->equals(name)) {
+ str = fConfigFileValues[i]->c_str();
+ break;
+ }
+ }
+
+ SkString environment_variable("skia.");
+ environment_variable.append(name);
+
+ const char *environment_value = getenv(environment_variable.c_str());
+ if (environment_value) {
+ str = environment_value;
+ } else {
+ // apparently my shell doesn't let me have environment variables that
+ // have periods in them, so also let the user substitute underscores.
+ SkAutoTMalloc<char> underscore_name(SkStrDup(environment_variable.c_str()));
+ str_replace(underscore_name.get(), '.', '_');
+ environment_value = getenv(underscore_name.get());
+ if (environment_value) {
+ str = environment_value;
+ }
+ }
+
+ if (!str) {
+ return false;
+ }
+
+ bool success;
+ T new_value = doParse<T>(str, &success);
+ if (success) {
+ *value = new_value;
+ } else {
+ SkDebugf("WARNING: Couldn't parse value \'%s\' for variable \'%s\'\n",
+ str, name);
+ }
+ return success;
+}
+
+// need to explicitly instantiate the parsing function for every config type we might have...
+
+template bool SkRTConfRegistry::parse(const char *name, bool *value);
+template bool SkRTConfRegistry::parse(const char *name, int *value);
+template bool SkRTConfRegistry::parse(const char *name, unsigned int *value);
+template bool SkRTConfRegistry::parse(const char *name, float *value);
+template bool SkRTConfRegistry::parse(const char *name, double *value);
+template bool SkRTConfRegistry::parse(const char *name, const char **value);
+
+template <typename T> void SkRTConfRegistry::set(const char *name,
+ T value,
+ bool warnIfNotFound) {
+ SkTDArray<SkRTConfBase *> *confArray;
+ if (!fConfs.find(name, &confArray)) {
+ if (warnIfNotFound) {
+ SkDebugf("WARNING: Attempting to set configuration value \"%s\","
+ " but I've never heard of that.\n", name);
+ }
+ return;
+ }
+ SkASSERT(confArray != nullptr);
+ for (SkRTConfBase **confBase = confArray->begin(); confBase != confArray->end(); confBase++) {
+ // static_cast here is okay because there's only one kind of child class.
+ SkRTConf<T> *concrete = static_cast<SkRTConf<T> *>(*confBase);
+
+ if (concrete) {
+ concrete->set(value);
+ }
+ }
+}
+
+template void SkRTConfRegistry::set(const char *name, bool value, bool);
+template void SkRTConfRegistry::set(const char *name, int value, bool);
+template void SkRTConfRegistry::set(const char *name, unsigned int value, bool);
+template void SkRTConfRegistry::set(const char *name, float value, bool);
+template void SkRTConfRegistry::set(const char *name, double value, bool);
+template void SkRTConfRegistry::set(const char *name, char * value, bool);
+
+SkRTConfRegistry &skRTConfRegistry() {
+ static SkRTConfRegistry r;
+ return r;
+}
« no previous file with comments | « src/opts/opts_check_x86.cpp ('k') | tests/PathOpsExtendedTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698