From a12aa85b519bbc7c685bc80052acfae61a70598b Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Tue, 1 Jan 2019 14:44:23 -0800 Subject: [PATCH] Allow env OPENIMAGEIO_OPTIONS to set global OIIO::attribute() Akin to how we have `OPENIMAGEIO_IMAGECACHE_OPTIONS` and `OPENIMAGEIO_TEXTURE_OPTIONS`. `OPENIMAGEIO_TEXTURE_OPTIONS` is a comma-separated list of name=val pairs that upon startup will seed the global options that are usually set by the OIIO::attribute() call. Along the way, I beefed up the OptParser to be able to handle both single and double quotes equally well. That lets you set an option that is a string, that itself contains quotes. Also document all of these options -- I realized the PDF docs don't talk about even the existing env variables. --- src/doc/imageioapi.tex | 28 ++++++++++++++++++++++++++++ src/include/OpenImageIO/optparser.h | 19 ++++++++++++------- src/libOpenImageIO/imageio.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/doc/imageioapi.tex b/src/doc/imageioapi.tex index 59aeb0e866..3b05721b01 100644 --- a/src/doc/imageioapi.tex +++ b/src/doc/imageioapi.tex @@ -1115,6 +1115,19 @@ \section{Miscellaneous Utilities} \noindent The following are the recognized attributes: +\apiitem{string options} +\vspace{10pt} +This catch-all is simply a comma-separated list of {\cf name=value} +settings of named options, which will be parsed and individually set. +For example, +\begin{code} + OIIO::attribute ("options", "threads=4,log_times=1"); +\end{code} +Note that if an option takes a string value that must itself contain a +comma, it is permissible to enclose the value in either single ({\cf ' '}) +or double ({\cf " "}) quotes. +\apiend + \apiitem{int threads} \vspace{10pt} \index{threads} \label{sec:attribute:threads} @@ -1349,6 +1362,21 @@ \section{Environment variables} \product at times that it is not convenient to set options individually from inside the source code. +\apiitem{OPENIMAGEIO_OPTIONS} +\NEW % 2.0 +Allows you to seed the global \product-wide options. + +The value of the environment variable should be a comma-separated list of +\emph{name=value} settings. If a value is a string that itself needs to +contain commas, it may be enclosed in single or double quotes. + +Upon startup, the contents of this environment variable will be passed +to a call to: +\begin{code} + OIIO::attribute ("options", value); +\end{code} +\apiend + \apiitem{OPENIMAGEIO_IMAGECACHE_OPTIONS} Allows you to seed the options for any \ImageCache created. diff --git a/src/include/OpenImageIO/optparser.h b/src/include/OpenImageIO/optparser.h index f198689848..00496f531e 100644 --- a/src/include/OpenImageIO/optparser.h +++ b/src/include/OpenImageIO/optparser.h @@ -74,11 +74,11 @@ optparse1(C& system, const std::string& opt) // otherwise treat it as a string // trim surrounding double quotes - if (value.size() >= 2 && value[0] == '\"' - && value[value.size() - 1] == '\"') + if (value.size() >= 2 && (value[0] == '\"' || value[0] == '\'') + && value[value.size() - 1] == value[0]) value = std::string(value, 1, value.size() - 2); - return system.attribute(name.c_str(), value.c_str()); + return system.attribute(name, value); } @@ -98,12 +98,17 @@ optparser(C& system, const std::string& optstring) size_t pos = 0; while (pos < len) { std::string opt; - bool inquote = false; + char inquote = 0; while (pos < len) { unsigned char c = optstring[pos]; - if (c == '\"') { - // Hit a double quote -- toggle "inquote" and add the quote - inquote = !inquote; + if (c == inquote) { + // Ending a quote + inquote = 0; + opt += c; + ++pos; + } else if (c == '\"' || c == '\'') { + // Found a quote + inquote = c; opt += c; ++pos; } else if (c == ',' && !inquote) { diff --git a/src/libOpenImageIO/imageio.cpp b/src/libOpenImageIO/imageio.cpp index 03532bd831..19139591f1 100644 --- a/src/libOpenImageIO/imageio.cpp +++ b/src/libOpenImageIO/imageio.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -143,6 +144,27 @@ class TimingLog { }; static TimingLog timing_log; + + +// Pipe-fitting class to set global options, for the sake of optparser. +struct GlobalOptSetter { +public: + template bool attribute(string_view name, T val) const + { + return OIIO::attribute(name, val); + } +}; + + +// Trick to force get the "OPENIMAGEIO_OPTIONS" env var on startup. +bool force_global_opts = []() { + auto options = Sysutil::getenv("OPENIMAGEIO_OPTIONS"); + // std::cout << "OPTIONS: '" << options << "'\n"; + if (!options.empty()) + attribute("options", options); + return true; +}(); + } // namespace @@ -283,6 +305,10 @@ pvt::log_time(string_view key, const Timer& timer) bool attribute(string_view name, TypeDesc type, const void* val) { + if (name == "options" && type == TypeDesc::STRING) { + GlobalOptSetter gos; + return optparser(gos, *(const char**)val); + } if (name == "threads" && type == TypeInt) { int ot = Imath::clamp(*(const int*)val, 0, maxthreads); if (ot == 0)