@@ -45,6 +45,10 @@ class bin_expr_t {
|
||||
|
||||
bin_expr_t() : arg1_(NULL), arg2_(NULL) {}
|
||||
bin_expr_t(const bin_expr_t* arg1, const bin_expr_t* arg2) : arg1_(arg1), arg2_(arg2) {}
|
||||
virtual ~bin_expr_t() {
|
||||
if (arg1_) delete arg1_;
|
||||
if (arg2_) delete arg2_;
|
||||
}
|
||||
|
||||
virtual args_t Eval(const args_cache_t& args) const = 0;
|
||||
virtual std::string Symbol() const = 0;
|
||||
@@ -66,7 +70,8 @@ class bin_expr_t {
|
||||
class Expr {
|
||||
public:
|
||||
explicit Expr(const std::string& expr, const expr_cache_t* cache)
|
||||
: expr_(expr), pos_(0), sub_count_(0), cache_(cache) {
|
||||
: expr_(expr), pos_(0), sub_count_(0), cache_(cache), is_sub_expr_(false)
|
||||
{
|
||||
sub_vec_ = new std::vector<const Expr*>;
|
||||
var_vec_ = new std::vector<std::string>;
|
||||
tree_ = ParseExpr();
|
||||
@@ -78,17 +83,22 @@ class Expr {
|
||||
sub_count_(0),
|
||||
cache_(obj->cache_),
|
||||
sub_vec_(obj->sub_vec_),
|
||||
var_vec_(obj->var_vec_) {
|
||||
var_vec_(obj->var_vec_),
|
||||
is_sub_expr_(true)
|
||||
{
|
||||
sub_vec_->push_back(this);
|
||||
tree_ = ParseExpr();
|
||||
if (!SubCheck()) throw exception_t("expr '" + expr_ + "', bad parenthesis count");
|
||||
}
|
||||
|
||||
~Expr() {
|
||||
delete cache_;
|
||||
for (auto it : *sub_vec_) delete it;
|
||||
delete sub_vec_;
|
||||
delete var_vec_;
|
||||
if (!is_sub_expr_) {
|
||||
delete cache_;
|
||||
for (auto it : *sub_vec_) delete it;
|
||||
delete sub_vec_;
|
||||
delete var_vec_;
|
||||
delete tree_;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetStr() const { return expr_; }
|
||||
@@ -204,6 +214,8 @@ class Expr {
|
||||
return str;
|
||||
}
|
||||
|
||||
static const bool div_zero_exc_on = false;
|
||||
|
||||
const std::string expr_;
|
||||
unsigned pos_;
|
||||
unsigned sub_count_;
|
||||
@@ -211,7 +223,7 @@ class Expr {
|
||||
const expr_cache_t* const cache_;
|
||||
std::vector<const Expr*>* sub_vec_;
|
||||
std::vector<std::string>* var_vec_;
|
||||
static const bool div_zero_exc_on = false;
|
||||
const bool is_sub_expr_;
|
||||
};
|
||||
|
||||
class add_expr_t : public bin_expr_t {
|
||||
|
||||
@@ -33,7 +33,7 @@ class Xml {
|
||||
enum { DECL_STATE, BODY_STATE };
|
||||
|
||||
static Xml* Create(const std::string& file_name, const Xml* obj = NULL) {
|
||||
Xml* xml = new Xml(file_name.c_str(), obj);
|
||||
Xml* xml = new Xml(file_name, obj);
|
||||
if (xml != NULL) {
|
||||
if (xml->Init() == false) {
|
||||
delete xml;
|
||||
@@ -91,23 +91,45 @@ class Xml {
|
||||
|
||||
nodes_t GetNodes(std::string global_tag) { return (*map_)[global_tag]; }
|
||||
|
||||
void Print() const {
|
||||
std::cout << "XML file '" << file_name_ << "':" << std::endl;
|
||||
for (auto& elem : *map_) {
|
||||
for (auto node : elem.second) {
|
||||
if (node->opts.size()) {
|
||||
std::cout << elem.first << ":" << std::endl;
|
||||
for (auto& opt : node->opts) {
|
||||
std::cout << " " << opt.first << " = " << opt.second << std::endl;
|
||||
}
|
||||
}
|
||||
template <class F>
|
||||
F ForEach(const F& f_i) {
|
||||
F f = f_i;
|
||||
for (auto& entry : *map_) {
|
||||
for (auto node : entry.second) {
|
||||
if (f.fun(entry.first, node) == false) break;
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
template <class F>
|
||||
F ForEach(const F& f_i) const {
|
||||
F f = f_i;
|
||||
for (auto& entry : *map_) {
|
||||
for (auto node : entry.second) {
|
||||
if (f.fun(entry.first, node) == false) break;
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
struct print_func {
|
||||
bool fun(const std::string& global_tag, level_t* node) {
|
||||
for (auto& opt : node->opts) {
|
||||
std::cout << global_tag << "." << opt.first << " = " << opt.second << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void Print() const {
|
||||
std::cout << "XML file '" << file_name_ << "':" << std::endl;
|
||||
ForEach(print_func());
|
||||
}
|
||||
|
||||
private:
|
||||
Xml(const char* file_name, const Xml* obj)
|
||||
: file_name_(strdup(file_name)),
|
||||
Xml(const std::string& file_name, const Xml* obj)
|
||||
: file_name_(file_name),
|
||||
file_line_(0),
|
||||
data_size_(0),
|
||||
index_(0),
|
||||
@@ -124,12 +146,22 @@ class Xml {
|
||||
}
|
||||
}
|
||||
|
||||
struct delete_func {
|
||||
bool fun(const std::string&, level_t* node) {
|
||||
delete node;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
~Xml() {
|
||||
if (included_ == false) delete map_;
|
||||
if (included_ == false) {
|
||||
ForEach(delete_func());
|
||||
delete map_;
|
||||
}
|
||||
}
|
||||
|
||||
bool Init() {
|
||||
fd_ = open(file_name_, O_RDONLY);
|
||||
fd_ = open(file_name_.c_str(), O_RDONLY);
|
||||
if (fd_ == -1) {
|
||||
perror((std::string("open XML file ") + file_name_).c_str());
|
||||
return false;
|
||||
@@ -228,11 +260,11 @@ class Xml {
|
||||
} else
|
||||
token[i] = '\0';
|
||||
|
||||
const char* tag = strdup(&token[ind]);
|
||||
const char* tag = &token[ind];
|
||||
if (node_begin) {
|
||||
AddLevel(tag);
|
||||
} else {
|
||||
if (strncmp(CurrentLevel().c_str(), tag, strlen(tag))) {
|
||||
if (strncmp(CurrentLevel().c_str(), tag, strlen(tag)) != 0) {
|
||||
token.back() = '>';
|
||||
BadFormat(token);
|
||||
}
|
||||
@@ -373,7 +405,7 @@ class Xml {
|
||||
|
||||
void AddOption(const std::string& key, const std::string& value) { level_->opts[key] = value; }
|
||||
|
||||
const char* file_name_;
|
||||
const std::string file_name_;
|
||||
unsigned file_line_;
|
||||
int fd_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user