tools/schema/tag.hpp

Go to the documentation of this file.
00001 /* $Id: tag.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2011 - 2012 by Sytyi Nick <nsytyi@gmail.com>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /**
00017  * @file
00018  * This file contains objects "tag" and "key", which are used to store
00019  * information about tags and keys while annotation parsing.
00020  */
00021 
00022 #ifndef TOOLS_SCHEMA_TAG_HPP_INCLUDED
00023 #define TOOLS_SCHEMA_TAG_HPP_INCLUDED
00024 
00025 #include <algorithm>
00026 #include <iostream>
00027 #include <map>
00028 #include <sstream>
00029 #include <string>
00030 
00031 class config;
00032 
00033 namespace schema_validation{
00034 /**
00035   * class_key is used to save the information about one key.
00036   * Key has next info: name, type, default value or key is mandatory.
00037   */
00038 class class_key{
00039 public:
00040     class_key():name_(""),type_(""),default_("\"\""),mandatory_(false)
00041     { }
00042     class_key(const std::string & name,
00043               const std::string &type,
00044               const std::string &def="\"\"")
00045         : name_(name)
00046         , type_(type)
00047         , default_(def)
00048         , mandatory_(def.empty())
00049     {
00050     }
00051     class_key(const config&);
00052 
00053     const std::string &  get_name() const{
00054         return name_ ;
00055     }
00056     const std::string &  get_type() const{
00057         return type_ ;
00058     }
00059     const std::string &  get_default() const{
00060         return default_;
00061     }
00062     bool  is_mandatory () const{
00063         return mandatory_ ;
00064     }
00065 
00066     void  set_name(const std::string& name){
00067         name_ = name;
00068     }
00069     void  set_type(const std::string& type){
00070         type_ = type;
00071     }
00072     void  set_default(const std::string& def){
00073         default_ = def;
00074         if (def.empty()){
00075             mandatory_ = true;
00076         }
00077     }
00078     void  set_mandatory(bool mandatory){
00079         mandatory_ = mandatory;
00080     }
00081     /** is used to print key info
00082      * the format is next
00083      *  [key]
00084      *      name="name"
00085      *      type="type"
00086      *      default="default"
00087      *      mandatory="true/false"
00088      *  [/key]
00089     */
00090     void  print(std::ostream& os,int level) const;
00091 
00092     /**
00093      *Compares keys by name. Used in std::sort, i.e.
00094      */
00095     bool  operator < ( const class_key& k) const{
00096         return (get_name() < k.get_name());
00097     }
00098 private:
00099     /** Name of key*/
00100     std::string name_;
00101     /** Type of key*/
00102     std::string type_;
00103     /** Default value*/
00104     std::string default_;
00105     /** Shows, if key is a mandatory key.*/
00106     bool mandatory_;
00107 };
00108 
00109 /**
00110   * Stores information about tag.
00111   * Each tags is an element of great tag tree. This tree is close to filesystem:
00112   * you can use links and special include directory global/
00113   * Normally root is not mentioned in path.
00114   * Each tag has name, minimum and maximum occasions number,
00115   * and lists of subtags, keys and links.
00116   */
00117 class class_tag{
00118 public:
00119     typedef std::map<std::string,class_tag> tag_map;
00120     typedef std::pair<std::string,class_tag> tag_map_value;
00121 
00122     typedef std::map<std::string,class_key> key_map;
00123     typedef std::pair<std::string,class_key> key_map_value;
00124 
00125     typedef std::map<std::string,std::string> link_map;
00126     typedef std::pair<std::string,std::string> link_map_value;
00127 
00128     typedef key_map::iterator key_iterator;
00129     typedef std::pair<key_iterator,key_iterator> all_key_iterators;
00130 
00131     typedef key_map::const_iterator const_key_iterator;
00132     typedef std::pair<const_key_iterator,const_key_iterator>
00133             all_const_key_iterators;
00134 
00135     typedef tag_map::iterator tag_iterator;
00136     typedef std::pair<tag_iterator,tag_iterator> all_tag_iterators;
00137 
00138     typedef tag_map::const_iterator const_tag_iterator;
00139     typedef std::pair<const_tag_iterator,const_tag_iterator>
00140             all_const_tag_iterators;
00141 
00142     typedef link_map::iterator link_iterator;
00143     typedef std::pair<link_iterator,link_iterator> all_link_iterators;
00144 
00145     typedef link_map::const_iterator const_link_iterator;
00146     typedef std::pair<const_link_iterator,const_link_iterator>
00147             all_const_link_iterators;
00148 
00149     class_tag()
00150         : name_("")
00151         , min_(0)
00152         , max_(0)
00153         , super_("")
00154         , tags_()
00155         , keys_()
00156         , links_()
00157     {
00158     }
00159 
00160     class_tag(const std::string & name,
00161               int min,
00162               int max,
00163               const std::string & super=""
00164               )
00165         : name_(name)
00166         , min_(min)
00167         , max_(max)
00168         , super_(super)
00169         , tags_()
00170         , keys_()
00171         , links_()
00172     {
00173     }
00174     class_tag(const config&);
00175     ~class_tag(){  }
00176 
00177     /** Prints information about tag to outputstream, recursively
00178      * is used to print tag info
00179      * the format is next
00180      *  [tag]
00181      *      subtags
00182      *      keys
00183      *      name="name"
00184      *      min="min"
00185      *      max="max"
00186      *  [/tag]
00187     */
00188     void print(std::ostream& os);
00189 
00190     const std::string & get_name() const{
00191         return name_ ;
00192     }
00193     int get_min() const{
00194         return min_;
00195     }
00196     int get_max() const{
00197         return max_;
00198     }
00199     const std::string & get_super() const{
00200         return super_ ;
00201     }
00202     bool is_extension() const{
00203         return ! super_.empty();
00204     }
00205 
00206     void set_name(const std::string& name){
00207         name_ = name;
00208     }
00209     void set_min(int o){
00210         min_ = o;
00211     }
00212     void set_max(int o){
00213         max_ = o;
00214     }
00215     void set_min( std::string const& s){
00216         std::istringstream i(s);
00217         if (!(i >> min_)){
00218             min_ = 0;
00219         }
00220     }
00221     void set_max( std::string const & s){
00222         std::istringstream i(s);
00223         if (!(i >> max_)){
00224             max_ = 0;
00225         }
00226     }
00227     void set_super(std::string const & s){
00228         super_= s;
00229     }
00230     void add_key(const class_key& new_key){
00231         keys_.insert(key_map_value(new_key.get_name(),new_key));
00232     }
00233     void add_tag(const class_tag& new_tag){
00234         tags_.insert(tag_map_value(new_tag.name_,new_tag));
00235     }
00236     void add_link(const std::string & link);
00237 
00238     /**
00239      * Tags are usually organized in tree.
00240      * This fuction helps to add tag to his exact place in tree
00241      * @param path - path in subtree to exact place of tag
00242      * @param tag  - tag to add
00243      * @param root - root of schema tree - use to support of adding to link.
00244      * Path is getting shotter and shoter with each call.
00245      * Path schould look like tag1/tag2/parent/ Slash at end is mandatory.
00246      */
00247     void add_tag (const std::string & path,const class_tag & tag,
00248                   class_tag &root);
00249 
00250     bool operator < ( const class_tag& t) const{
00251         return name_ < t.name_;
00252     }
00253     bool operator == (const class_tag & other) const {
00254         return name_ == other.name_;
00255     }
00256     /**
00257      * Returns pointer to child key
00258      */
00259     const class_key * find_key(const std::string & name) const;
00260     /**
00261      * Returns pointer to child link
00262      */
00263     const std::string * find_link(const std::string & name) const;
00264 
00265     /**
00266      * Returns pointer to tag using full path to it.
00267      * Also work with links
00268      */
00269     const class_tag * find_tag(const std::string & fullpath,
00270                                const class_tag & root) const;
00271     /**
00272      * Calls the expansion on each child
00273      */
00274     void expand_all(class_tag &root);
00275 
00276     all_const_tag_iterators tags() const{
00277         return all_const_tag_iterators(tags_.begin(),tags_.end());
00278     }
00279     all_const_key_iterators keys() const{
00280         return all_const_key_iterators(keys_.begin(),keys_.end());
00281     }
00282     all_const_link_iterators links() const{
00283         return all_const_link_iterators(links_.begin(),links_.end());
00284     }
00285 
00286     void remove_key_by_name(const std::string &name){
00287         keys_.erase (name);
00288     }
00289     /** Removes all keys with this type. Works recursively */
00290     void remove_keys_by_type(const std::string &type);
00291 
00292 #ifdef _MSC_VER
00293     // MSVC throws an error if this method is private.
00294     // so, define it as public to prevent that. The error is:
00295     // error C2248: 'schema_validation::class_tag::find_tag' : cannot
00296     // access private member declared in class 'schema_validation::class_tag'
00297 
00298     class_tag * find_tag(const std::string & fullpath,
00299                                 class_tag & root) ;
00300 #endif
00301 
00302 //  class_tag & operator= (class_tag const& );
00303 
00304 private:
00305     /** name of tag*/
00306     std::string name_;
00307     /** number of minimum occasions*/
00308     int min_;
00309     /** number of maximum occasions*/
00310     int max_;
00311     /**
00312      * name of tag to extend "super-tag"
00313      * Extension is smth like inheritance and is used in case
00314      * when you need to use another tag with all his
00315      * keys, childs, etc. But you also want to allow extra subtags of that tags,
00316      * so just linking that tag wouldn't help at all.
00317      */
00318     std::string super_;
00319     /** children tags*/
00320     tag_map tags_;
00321     /** keys*/
00322     key_map keys_;
00323     /** links to possible children. */
00324     link_map links_;
00325     /**
00326      * the same as class_tag::print(std::ostream&)
00327      * but indents different levels with step space.
00328      * @param os stream to print
00329      * @param level  current level of indentation
00330      * @param step   step to next indent
00331      */
00332     void printl(std::ostream &os,int level, int step = 4);
00333 
00334 #ifndef _MSC_VER
00335     // this is complementary with the above #ifdef for the MSVC error
00336     class_tag * find_tag(const std::string & fullpath,
00337                                 class_tag & root) ;
00338 #endif
00339 
00340     void add_tags (const tag_map & list){
00341         tags_.insert(list.begin(),list.end());
00342     }
00343     void add_keys (const key_map & list){
00344         keys_.insert(list.begin(),list.end());
00345     }
00346     void add_links (const link_map & list){
00347         links_.insert(list.begin(),list.end());
00348     }
00349     /**
00350      * Copies tags, keys and links of tag to this
00351      */
00352     void append_super(const class_tag & tag,const std::string & super);
00353     /**
00354      * Expands all "super" copying their data to this.
00355      */
00356     void expand(class_tag & root);
00357 };
00358 
00359 }
00360 #endif // TOOLS_SCHEMA_TAG_HPP_INCLUDED
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:13 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs