Add initial validator structure.
Applies a slightly modified patch #2815.
This commit is contained in:
parent
351a3d803d
commit
01169bbd31
4 changed files with 134 additions and 18 deletions
|
@ -31,6 +31,7 @@
|
|||
#include "serialization/preprocessor.hpp"
|
||||
#include "serialization/tokenizer.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
#include "serialization/validator.hpp"
|
||||
#include "foreach.hpp"
|
||||
|
||||
#include <stack>
|
||||
|
@ -48,14 +49,14 @@ static lg::log_domain log_config("config");
|
|||
static const size_t max_recursion_levels = 1000;
|
||||
|
||||
namespace {
|
||||
|
||||
class parser
|
||||
{
|
||||
parser();
|
||||
parser(const parser&);
|
||||
parser& operator=(const parser&);
|
||||
public:
|
||||
parser(config& cfg, std::istream& in);
|
||||
parser(config& cfg, std::istream& in,
|
||||
abstract_validator * validator = NULL);
|
||||
~parser();
|
||||
void operator()();
|
||||
|
||||
|
@ -68,6 +69,7 @@ private:
|
|||
|
||||
config& cfg_;
|
||||
tokenizer *tok_;
|
||||
abstract_validator *validator_;
|
||||
|
||||
struct element {
|
||||
element(config *cfg, std::string const &name,
|
||||
|
@ -84,10 +86,11 @@ private:
|
|||
std::stack<element> elements;
|
||||
};
|
||||
|
||||
parser::parser(config &cfg, std::istream &in) :
|
||||
cfg_(cfg),
|
||||
tok_(new tokenizer(in)),
|
||||
elements()
|
||||
parser::parser(config &cfg, std::istream &in, abstract_validator * validator)
|
||||
:cfg_(cfg),
|
||||
tok_(new tokenizer(in)),
|
||||
validator_(validator),
|
||||
elements()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -148,13 +151,15 @@ void parser::parse_element()
|
|||
tok_->next_token();
|
||||
std::string elname;
|
||||
config* current_element = NULL;
|
||||
|
||||
switch(tok_->current_token().type) {
|
||||
case token::STRING: // [element]
|
||||
elname = tok_->current_token().value;
|
||||
if (tok_->next_token().type != ']')
|
||||
error(_("Unterminated [element] tag"));
|
||||
|
||||
if (validator_){
|
||||
validator_->open_tag(elname,tok_->get_start_line(),
|
||||
tok_->get_file());
|
||||
}
|
||||
// Add the element
|
||||
current_element = &(elements.top().cfg->add_child(elname));
|
||||
elements.push(element(current_element, elname, tok_->get_start_line(), tok_->get_file()));
|
||||
|
@ -174,6 +179,10 @@ void parser::parse_element()
|
|||
} else {
|
||||
current_element = &elements.top().cfg->add_child(elname);
|
||||
}
|
||||
if (validator_){
|
||||
validator_->open_tag(elname,tok_->get_start_line(),
|
||||
tok_->get_file());
|
||||
}
|
||||
elements.push(element(current_element, elname, tok_->get_start_line(), tok_->get_file()));
|
||||
break;
|
||||
|
||||
|
@ -194,7 +203,11 @@ void parser::parse_element()
|
|||
error(lineno_string(i18n_symbols, ss.str(),
|
||||
N_("Found invalid closing tag $tag2 for tag $tag1 (opened at $pos)")));
|
||||
}
|
||||
|
||||
if(validator_){
|
||||
element & el= elements.top();
|
||||
validator_->validate(*el.cfg,el.name,el.start_line,el.file);
|
||||
validator_->close_tag();
|
||||
}
|
||||
elements.pop();
|
||||
break;
|
||||
default:
|
||||
|
@ -342,18 +355,18 @@ void parser::error(const std::string& error_type)
|
|||
|
||||
} // end anon namespace
|
||||
|
||||
void read(config &cfg, std::istream &in)
|
||||
void read(config &cfg, std::istream &in, abstract_validator * validator)
|
||||
{
|
||||
parser(cfg, in)();
|
||||
parser(cfg, in, validator)();
|
||||
}
|
||||
|
||||
void read(config &cfg, std::string &in)
|
||||
void read(config &cfg, std::string &in, abstract_validator * validator)
|
||||
{
|
||||
std::istringstream ss(in);
|
||||
parser(cfg, ss)();
|
||||
parser(cfg, ss, validator)();
|
||||
}
|
||||
|
||||
void read_gz(config &cfg, std::istream &file)
|
||||
void read_gz(config &cfg, std::istream &file, abstract_validator * validator)
|
||||
{
|
||||
//an empty gzip file seems to confuse boost on msvc
|
||||
//so return early if this is the case
|
||||
|
@ -364,7 +377,7 @@ void read_gz(config &cfg, std::istream &file)
|
|||
filter.push(boost::iostreams::gzip_decompressor());
|
||||
filter.push(file);
|
||||
|
||||
parser(cfg, filter)();
|
||||
parser(cfg, filter,validator)();
|
||||
}
|
||||
|
||||
static std::string escaped_string(const std::string &value)
|
||||
|
|
|
@ -22,10 +22,15 @@
|
|||
#include "global.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
|
||||
class abstract_validator;
|
||||
// Read data in, clobbering existing data.
|
||||
void read(config &cfg, std::istream &in); // Throws config::error
|
||||
void read(config &cfg, std::string &in); // Throws config::error
|
||||
void read_gz(config &cfg, std::istream &in);
|
||||
void read(config &cfg, std::istream &in,
|
||||
abstract_validator * validator = NULL); // Throws config::error
|
||||
void read(config &cfg, std::string &in,
|
||||
abstract_validator * validator = NULL); // Throws config::error
|
||||
void read_gz(config &cfg, std::istream &in,
|
||||
abstract_validator * validator = NULL);
|
||||
|
||||
void write(std::ostream &out, config const &cfg, unsigned int level=0);
|
||||
void write_gz(std::ostream &out, config const &cfg);
|
||||
|
|
19
src/serialization/validator.cpp
Normal file
19
src/serialization/validator.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2011 - 2011 by Sytyi Nick <nsytyi@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
/**
|
||||
* @file validator.cpp
|
||||
*/
|
||||
#include "serialization/validator.hpp"
|
||||
|
79
src/serialization/validator.hpp
Normal file
79
src/serialization/validator.hpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2011 - 2011 by Sytyi Nick <nsytyi@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
/**
|
||||
* @file validator.hpp
|
||||
* This file contains information about validation abstract level interface.
|
||||
*/
|
||||
|
||||
#ifndef SERIALIZATION_VALIDATOR_HPP_INCLUDED
|
||||
#define SERIALIZATION_VALIDATOR_HPP_INCLUDED
|
||||
|
||||
#include "game_errors.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
class config;
|
||||
|
||||
/**
|
||||
* @class abstract_validator
|
||||
* Used in parsing config file. @ref parser.cpp
|
||||
* Contains virtual methods, which are called by parser
|
||||
* and take information about config to be validated
|
||||
*/
|
||||
|
||||
class abstract_validator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor of validator can throw validator::error
|
||||
* @throws abstract_validator::error
|
||||
*/
|
||||
abstract_validator(){}
|
||||
|
||||
virtual ~abstract_validator(){}
|
||||
/**
|
||||
* Is called when parser opens tag.
|
||||
* @param name Name of tag
|
||||
* @param start_line Line in file
|
||||
* @param file Name of file
|
||||
*/
|
||||
virtual void open_tag(const std::string & name,int start_line,
|
||||
const std::string &file) = 0;
|
||||
/**
|
||||
* As far as parser is built on stack, some realizations can store stack
|
||||
* too. So they need to know if tag was closed.
|
||||
*/
|
||||
virtual void close_tag() = 0;
|
||||
/**
|
||||
* Validates config
|
||||
* What exactly is validated depends on validator realization
|
||||
* @param cfg Config to be validated.
|
||||
* @param name Name of tag
|
||||
* @param start_line Line in file
|
||||
* @param file Name of file
|
||||
*/
|
||||
virtual bool validate(const config & cfg, const std::string & name,
|
||||
int start_line,
|
||||
const std::string &file) = 0;
|
||||
/**
|
||||
* @struct error
|
||||
* Used to manage with not initialized validators
|
||||
* Supposed to be thrown from the constructor
|
||||
*/
|
||||
struct error : public game::error {
|
||||
error(const std::string& message) : game::error(message) {}
|
||||
};
|
||||
};
|
||||
#endif // SERIALIZATION_VALIDATOR_HPP_INCLUDED
|
Loading…
Add table
Reference in a new issue