cgv
Loading...
Searching...
No Matches
variables.cxx
1#include "variables.h"
2#include <map>
3#include <iostream>
4#include <stdlib.h>
6
7#ifdef WIN32
8#pragma warning (disable:4503)
9#else
10extern char **environ;
11#endif
12
13
14namespace cgv {
15 namespace ppp {
16
17 namespace_info::namespace_info(bool _is_function_call_ns, variant::map_type* _ns, namespace_info* _environment_ns, namespace_info* _parent_ns) :
18 is_function_call_ns(_is_function_call_ns), ns(_ns), ns_allocated(_ns == 0), environment_ns(_environment_ns), parent_ns(_parent_ns)
19 {
20 child_ns = 0;
21 if (ns_allocated)
22 ns = new variant::map_type();
23 }
24
25 namespace_info::~namespace_info()
26 {
27 if (ns_allocated) {
28 delete ns;
29 ns = 0;
30 }
31 }
32
33
34 namespace_info*& ref_current_namespace()
35 {
36 static namespace_info* current_namespace = 0;
37 if (!current_namespace) {
38 current_namespace = new namespace_info(false);
39 ref_variable("UNDEF") = variant();
40 ref_variable("BOOL") = variant(true);
41 ref_variable("TRUE") = variant(true);
42 ref_variable("FALSE") = variant(false);
43 ref_variable("INT") = variant(7);
44 ref_variable("STRING") = variant(std::string());
45 ref_variable("LIST") = variant(std::vector<variant>());
46 ref_variable("MAP") = variant(variant::map_type());
47 ref_variable("FUNC") = variant(func_type(-1, -2));
48#ifdef WIN32
49 ref_variable("SYSTEM") = variant(std::string("windows"));
50#else
51 ref_variable("SYSTEM") = variant(std::string("linux"));
52#endif
53 }
54 return current_namespace;
55 }
56
57 namespace_info* get_current_namespace()
58 {
59 return ref_current_namespace();
60 }
61
63 void set_current_namespace(namespace_info* _cns)
64 {
65 ref_current_namespace() = _cns;
66 }
67
68
69 variant* find_variable(const std::string& var_name, bool only_current)
70 {
71 namespace_info* cns = ref_current_namespace();
72 while (cns) {
73 variant::map_type::iterator iter = cns->ns->find(var_name);
74 if (iter != cns->ns->end())
75 return &iter->second;
76 if (only_current)
77 return 0;
78 cns = cns->environment_ns;
79 }
80 return 0;
81 }
82
83 variant& ref_variable(const std::string& var_name, bool only_current)
84 {
85 variant* var = find_variable(var_name, only_current);
86 if (var)
87 return *var;
88 return (*ref_current_namespace()->ns)[var_name];
89 }
90
91 void remove_namespace(namespace_info* ns)
92 {
93 if (ns->child_ns) {
94 ns->child_ns->parent_ns = 0;
95 remove_namespace(ns->child_ns);
96 }
97 namespace_info* pns = ns->parent_ns;
98 delete ns;
99 if (pns) {
100 pns->child_ns = 0;
101 remove_namespace(pns);
102 }
103 }
104
106 void clear_variables()
107 {
108 remove_namespace(ref_current_namespace());
109 ref_current_namespace() = 0;
110 }
111
112
113 void push_namespace(variant* ns_var, namespace_info* environment_ns)
114 {
115 namespace_info *ns, *cns = ref_current_namespace();
116 if (environment_ns)
117 ns = new namespace_info(true, 0, environment_ns, cns);
118 else {
119 if (cns->is_function_call_ns)
120 ns = new namespace_info(false, &ns_var->ref_map(), cns, cns);
121 else
122 ns = new namespace_info(false, &ns_var->ref_map(), cns->get_environment(), cns);
123 }
124 ns->child_ns = cns->child_ns;
125 if (ns->child_ns)
126 ns->child_ns->parent_ns = ns;
127 cns->child_ns = ns;
128 ref_current_namespace() = ns;
129 }
130
131 void pop_namespace()
132 {
133 namespace_info* cns = ref_current_namespace();
134 if (!cns->parent_ns) {
135 std::cerr << "pop_namespace called without a pushed namespace available" << std::endl;
136 return;
137 }
138 cns->parent_ns->child_ns = cns->child_ns;
139 if (cns->child_ns)
140 cns->child_ns->parent_ns = cns->parent_ns;
141 ref_current_namespace() = cns->parent_ns;
142 delete cns;
143 }
144
146 bool has_child_namespace()
147 {
148 return ref_current_namespace()->child_ns != 0;
149 }
150
152 void goto_child_namespace()
153 {
154 namespace_info* cns = ref_current_namespace();
155 if (cns->child_ns)
156 ref_current_namespace() = cns->child_ns;
157 else
158 std::cerr << "goto_child_namespace called without a child namespace available" << std::endl;
159 }
160
162 bool has_parent_namespace()
163 {
164 return ref_current_namespace()->parent_ns != 0;
165 }
166
168 void goto_parent_namespace()
169 {
170 namespace_info* cns = ref_current_namespace();
171 if (cns->parent_ns)
172 ref_current_namespace() = cns->parent_ns;
173 else
174 std::cerr << "goto_parent_namespace called without a parent namespace available" << std::endl;
175 }
176
177
178 void init_environment(int argc, char** argv)
179 {
180 variant& env = ref_variable("env");
181 env = variant(variant::map_type());
182 variant::map_type& env_map = env.ref_map();
183 char** glob_vars = environ;
184 while (*glob_vars != NULL) {
185 std::string def(*glob_vars), var_name, value;
186 size_t pos = def.find_first_of("=");
187 if (pos == std::string::npos)
188 var_name = def;
189 else {
190 var_name = def.substr(0, pos);
191 value = def.substr(pos + 1);
192 }
193 env_map[var_name] = variant(value);
194 ++glob_vars;
195 }
196 variant& opt = ref_variable("cgv_options");
197 opt.set_map();
198 auto iter = env_map.find("CGV_OPTIONS");
199 if (iter != env_map.end()) {
200 std::vector<cgv::utils::token> tokens;
201 cgv::utils::split_to_tokens(iter->second.get_str(), tokens, ";", false);
202 for (unsigned i = 0; i < tokens.size(); i += 2) {
203 opt.ref_map()[cgv::utils::to_string(tokens[i])].set_int(1);
204 }
205 }
206 variant::list_type& arg_list = (env_map["ARGS"] = variant(variant::list_type())).ref_list();
207 for (int i = 0; i < argc; ++i)
208 arg_list.push_back(variant(std::string(argv[i])));
209 }
210
211 }
212}
More advanced text processing for splitting text into lines or tokens.
void split_to_tokens(const char *begin, const char *end, std::vector< token > &tokens, const std::string &separators, bool merge_separators, const std::string &open_parenthesis, const std::string &close_parenthesis, const std::string &whitespaces, unsigned int max_nr_tokens)
this function splits a text range into tokens.
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
the cgv namespace
Definition print.h:11