Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "vars.h"
00029
00030 #include <iostream>
00031 #include <fstream>
00032 #include <sstream>
00033 #include <boost/algorithm/string.hpp>
00034 #include <boost/algorithm/string/replace.hpp>
00035
00036 using namespace std;
00037 using namespace boost;
00038
00039 namespace pangolin
00040 {
00041
00042 boost::ptr_unordered_map<string,_Var> vars;
00043 vector<NewVarCallback> new_var_callbacks;
00044 vector<GuiVarChangedCallback> gui_var_changed_callbacks;
00045
00046 void RegisterNewVarCallback(NewVarCallbackFn callback, void* data, const std::string& filter)
00047 {
00048 new_var_callbacks.push_back(NewVarCallback(filter,callback,data));
00049 }
00050
00051 void RegisterGuiVarChangedCallback(GuiVarChangedCallbackFn callback, void* data, const std::string& filter)
00052 {
00053 gui_var_changed_callbacks.push_back(GuiVarChangedCallback(filter,callback,data));
00054 }
00055
00056
00057 const char* FirstOpenBrace(const char* str)
00058 {
00059 bool symbol = false;
00060
00061 for(; *str != '\0'; ++str )
00062 {
00063 if( *str == '$')
00064 {
00065 symbol = true;
00066 }
00067 else
00068 {
00069 if( symbol )
00070 {
00071 if( *str == '{' )
00072 {
00073 return str;
00074 }
00075 else
00076 {
00077 symbol = false;
00078 }
00079 }
00080 }
00081 }
00082 return 0;
00083 }
00084
00085
00086 const char* MatchingEndBrace(const char* str)
00087 {
00088 int b = 0;
00089 for(; *str != '\0'; ++str )
00090 {
00091 if( *str == '{' )
00092 {
00093 ++b;
00094 }
00095 else if( *str == '}' )
00096 {
00097 --b;
00098 if( b == 0 )
00099 {
00100 return str;
00101 }
00102 }
00103 }
00104 return 0;
00105 }
00106
00107
00108 string ProcessVal(const string& val )
00109 {
00110 string expanded = val;
00111
00112 while(true)
00113 {
00114 const char* brace = FirstOpenBrace(expanded.c_str());
00115 if(brace)
00116 {
00117 const char* endbrace = MatchingEndBrace(brace);
00118 if( endbrace )
00119 {
00120 iterator_range<const char*> out(brace-1,endbrace+1);
00121 iterator_range<const char*> in(brace+1,endbrace);
00122 string inexpand = ProcessVal(copy_range<string>(in));
00123 Var<string> var(inexpand,"#");
00124 if( !((const string)var).compare("#"))
00125 {
00126 std::cerr << "Unabled to expand: [" << inexpand << "].\nMake sure it is defined and terminated with a semi-colon." << endl << endl;
00127 }
00128 ostringstream oss;
00129 oss << copy_range<string>(iterator_range<const char*>(expanded.c_str(), brace-1));
00130 oss << (const string)var;
00131 oss << copy_range<string>(iterator_range<const char*>(endbrace+1, expanded.c_str() + expanded.length() ));
00132 expanded = oss.str();
00133
00134
00135 continue;
00136 }
00137 }
00138 break;
00139 }
00140
00141 return expanded;
00142 }
00143
00144 void AddVar(const string& name, const string& val )
00145 {
00146 boost::ptr_unordered_map<std::string,_Var>::iterator vi = vars.find(name);
00147 const bool exists_already = vi != vars.end();
00148
00149 string full = ProcessVal(val);
00150 Var<string> var(name);
00151 var = full;
00152
00153
00154 if(!exists_already)
00155 {
00156 var.var->generic = true;
00157 }
00158 }
00159
00160 #ifdef ALIAS
00161 void AddAlias(const string& alias, const string& name)
00162 {
00163 boost::ptr_unordered_map<std::string,_Var>::iterator vi = vars.find(name);
00164
00165 if( vi != vars.end() )
00166 {
00167
00168 _Var * v = vi->second;
00169 vars[alias].create(v->val,v->val_default,v->type_name);
00170 vars[alias].meta_friendly = alias;
00171 v->generic = false;
00172 vars[alias].generic = false;
00173 }
00174 else
00175 {
00176 cout << "Variable " << name << " does not exist to alias." << endl;
00177 }
00178 }
00179 #endif
00180
00181 void ParseVarsFile(const string& filename)
00182 {
00183 ifstream f(filename.c_str());
00184
00185 if( f.is_open() )
00186 {
00187 while( !f.bad() && !f.eof())
00188 {
00189 const int c = f.peek();
00190
00191 if( isspace(c) )
00192 {
00193
00194 f.get();
00195 }
00196 else
00197 {
00198 if( c == '#' || c == '%' )
00199 {
00200
00201 string comment;
00202 getline(f,comment);
00203 }
00204 else
00205 {
00206
00207 string name;
00208 string val;
00209 getline(f,name,'=');
00210 getline(f,val,';');
00211 boost::trim_if(name, boost::is_any_of(" \t\n\r"));
00212 boost::trim_if(val, boost::is_any_of(" \t\n\r"));
00213
00214 if( name.size() >0 && val.size() > 0 )
00215 {
00216 if( !val.substr(0,1).compare("@") )
00217 {
00218 #ifdef ALIAS
00219 AddAlias(name,val.substr(1));
00220 #endif
00221 }
00222 else
00223 {
00224 AddVar(name,val);
00225 }
00226 }
00227 }
00228 }
00229 }
00230 f.close();
00231 }
00232 else
00233 {
00234 cerr << "Unable to open '" << filename << "' for configuration data" << endl;
00235 }
00236 }
00237
00238 }