On 9 Mar 2011, at 16:25, Tapio Rantala wrote:

> Hi,
> I have made the following changes to libiodata in project Trunk:Testing. 
> Please review and accept ASAP.
> 
> Thank You,
> Tapio Rantala
> 
> [This message was auto-generated]
> 
> ---
> 
> Request #14622:
> 
>  submit:   devel:systemsw/libiodata(r4) -> Trunk:Testing/libiodata
> 
> 
> Message:
>    * Fri Mar 04 2011 Tapio Rantala <[email protected]> 0.17-1
> - New upstream version (FEA#5513)
> 
> State:   new          2011-03-09T00:25:17 tapioran
> Comment: None
> 
> 
> 
> changes files:
> --------------
> --- libiodata.changes
> +++ libiodata.changes
> @@ -0,0 +1,3 @@
> +* Fri Mar 04 2011 Tapio Rantala <[email protected]> 0.17-1
> +- New upstream version (FEA#5513)
> +
> 
> old:
> ----
>  iodata-0.0.16.tar.bz2
> 
> new:
> ----
>  iodata-0.17.tar.bz2
> 
> spec files:
> -----------
> --- libiodata.spec
> +++ libiodata.spec
> @@ -1,6 +1,6 @@
> %define _name iodata
> Name:     libiodata
> -Version:  0.0.16
> +Version:  0.17

Shouldn't it be 0.0.17??

Anas


> Release:  1
> Summary:  Library for input/ouput data
> Group:    System/System Control
> @@ -37,6 +37,7 @@
> %setup -q -n %{_name}-%{version}
> 
> %build
> +export IODATA_VERSION=`head -n1 debian/changelog | sed 
> "s/.*(\([^)+]*\).*/\1/"`
> %qmake
> make
> 
> @@ -57,6 +58,7 @@
> %files devel
> %defattr(-,root,root,-)
> %doc COPYING
> +%{_bindir}/iodata-type-to-c++
> %{_includedir}/iodata/*
> %{_libdir}/%{name}.so
> %{_datadir}/qt4/mkspecs/features/iodata.prf
> 
> other changes:
> --------------
> 
> ++++++ iodata-0.0.16.tar.bz2 -> iodata-0.17.tar.bz2
> --- debian/changelog
> +++ debian/changelog
> @@ -1,3 +1,11 @@
> +iodata (0.17) unstable; urgency=low
> +
> +  * using qt4 qmake
> +  * taking version number from changelog
> +  * iodata-type-to-c++ compiler
> +
> + -- Ilya Dogolazky <[email protected]>  Thu, 17 Feb 2011 11:34:16 
> +0200
> +
> iodata (0.0.16) unstable; urgency=low
> 
>   * export read_file_to_string()
> --- debian/libiodata-dev.install
> +++ debian/libiodata-dev.install
> @@ -2,3 +2,5 @@
> usr/lib/libiodata.so
> 
> usr/share/qt4/mkspecs/features/iodata.prf
> +
> +usr/bin/iodata-type-to-c++
> --- debian/rules
> +++ debian/rules
> @@ -2,6 +2,7 @@
> # -*- makefile -*-
> 
> export DH_VERBOSE=1
> +export IODATA_VERSION=$(shell head -n1 debian/changelog | sed 
> "s/.*(\([^)+]*\).*/\1/")
> 
> configure: configure-stamp
> configure-stamp:
> @@ -12,7 +13,7 @@
> build: build-stamp
> build-stamp: configure-stamp
>       dh_testdir
> -     qmake && make
> +     qmake-qt4 && make
>       touch build-stamp
> 
> clean:
> --- iodata.prf
> +++ iodata.prf
> @@ -1 +1,15 @@
> LIBS += -liodata
> +
> +QMAKE_EXTRA_COMPILERS += iodata_type_to_cxx iodata_type_to_h
> +
> +iodata_type_to_cxx.input = IODATA_TYPES
> +iodata_type_to_cxx.output = iodata_${QMAKE_FILE_IN_BASE}.cpp
> +iodata_type_to_cxx.variable_out = SOURCES
> +iodata_type_to_cxx.commands = iodata-type-to-c++ ${QMAKE_FILE_IN} -o 
> iodata_${QMAKE_FILE_IN_BASE}.cpp -d ${QMAKE_FILE_IN}.h
> +
> +iodata_type_to_h.input = IODATA_TYPES
> +iodata_type_to_h.output = ${QMAKE_FILE_IN}.h
> +iodata_type_to_h.variable_out = HEADERS
> +iodata_type_to_h.commands = iodata-type-to-c++ ${QMAKE_FILE_IN} -o 
> iodata_${QMAKE_FILE_IN_BASE}.cpp -d ${QMAKE_FILE_IN}.h
> +
> +# iodata-type-to-c++ ${QMAKE_FILE_IN} -d ${QMAKE_FILE_OUT}
> --- root.pro
> +++ root.pro
> @@ -1,6 +1,6 @@
> TEMPLATE = subdirs
> 
> -SUBDIRS = src tests
> +SUBDIRS = src tests type-to-cxx
> 
> prf.files = iodata.prf
> prf.path = /usr/share/qt4/mkspecs/features
> --- src/iodata.cpp
> +++ src/iodata.cpp
> @@ -25,6 +25,13 @@
> 
> namespace iodata
> {
> +  bitmask::bitmask(bitmask_t literal, const char **symbolics)
> +  {
> +    xl = literal ;
> +    for (const char **p=symbolics; *p; ++p)
> +      xs.insert(*p) ;
> +  }
> +
>   void bitmask::assign(bitmask_t value, const bit_codec *codec)
>   {
>     xl = codec ? codec->encode(value, xs) : value ;
> --- src/iodata.h
> +++ src/iodata.h
> @@ -103,10 +103,12 @@
>     bitmask() { xl=0 ; }
>     bitmask(const bitmask &y) : xl(y.xl), xs(y.xs) { }
>     bitmask(bitmask_t value, const bit_codec *codec) { assign(value,codec) ; }
> +    bitmask(bitmask_t literal, const char *symbolics[]) ;
>     virtual ~bitmask() { }
>     bitmask_t value(const bit_codec *codec) const ;
>     void add(bitmask_t bits) { xl|=bits ; }
>     void add(string name) { xs.insert(name) ; }
> +    bool bit_present(const string &name) const { return xs.count(name)>0 ; }
>     void assign(bitmask_t value, const bit_codec *codec) ;
>     void plain_output(ostream &os, const string &prefix) const ;
>     bool is_leaf() { return true ; }
> @@ -249,7 +251,7 @@
>   {
>     if(const T *p_cast = dynamic_cast<const T*> (p))
>       return p_cast ;
> -    throw exception((string)T::static_class_name()+ "expected, but 
> "+p->class_name()+" found") ;
> +    throw exception((string)T::static_class_name()+ " expected, but 
> "+p->class_name()+" found") ;
>   }
> 
>   inline  const record *item::rec() const { return 
> cast_and_check_const<record>(this) ; }
> --- src/src.pro
> +++ src/src.pro
> @@ -1,4 +1,4 @@
> -VERSION = 0.0.16
> +VERSION = 0.$$(IODATA_VERSION)
> TEMPLATE=lib
> QT -= gui
> 
> --- src/storage.cpp
> +++ src/storage.cpp
> @@ -199,7 +199,7 @@
> 
>   if(no_data_on_disk || no_secondary || data_in_secondary)
>   {
> -    int res = write_string_to_file(0, new_data) ;
> +    int res = write_string(0, new_data) ;
>     if(res<0)
>     {
>       log_critical("can't write data to '%s': %m", path_0) ;
> @@ -234,7 +234,7 @@
> 
>   const char *path_i = index==0 ? path_0 : path_1 ;
> 
> -  int res = write_string_to_file(index, new_data) ;
> +  int res = write_string(index, new_data) ;
> 
>   if(res<0)
>   {
> @@ -298,7 +298,7 @@
> 
>   // now just write the cached data to primary
> 
> -  if(write_string_to_file(0, data_cached)<0)
> +  if(write_string(0, data_cached)<0)
>     return false ;
> 
>   data_source = 0 ;
> @@ -331,10 +331,14 @@
>   return rename(path_from, path_to) ;
> }
> 
> -int storage::write_string_to_file(int index, const string &data)
> +int storage::write_string(int index, const string &data)
> {
>   const char *file = path[index].c_str() ;
> +  return write_string_to_file(file, data) ;
> +}
> 
> +int storage::write_string_to_file(const char *file, const string &data)
> +{
>   int fd = open(file, O_WRONLY|O_CREAT|O_TRUNC, 0666) ;
> 
>   if(fd < 0)
> --- src/storage.h
> +++ src/storage.h
> @@ -64,9 +64,10 @@
>   bool fix_files(bool force) ;
> 
>   static int read_file_to_string(const char *file, string &input) ;
> +  static int write_string_to_file(const char *file, const string &data) ;
> private:
>   int move_files(int index_from, int index_to) ;
> -  int write_string_to_file(int index, const string &data) ;
> +  int write_string(int index, const string &data) ;
> 
>   record *parse_string_to_tree(std::string &message) ;
> } ;
> --- src/validator.cpp
> +++ src/validator.cpp
> @@ -32,23 +32,34 @@
> 
> iodata::validator::validator()
> {
> +  is_static = false ;
> +#if 0
>   static bool first = true ;
>   if(first)
>     init_type_codec(), first=false ;
> +#endif
> }
> iodata::validator::~validator()
> {
> +  if (is_static)
> +    return ;
>   log_debug("deleting validator::types") ;
>   for(map<string,record_type*>::iterator it=types.begin(); it!=types.end(); 
> ++it)
>     delete it->second ;
> }
> 
> +void iodata::validator::set_static()
> +{
> +  is_static = true ;
> +}
> +
> void iodata::validator::check_record(record *p, const record_type *r, bool 
> write)
> {
>   item *items[r->nodes.size()+1] ; // '+1' is used just for the case N=0
>   unsigned N=0, not_present=0 ;
> -  for(vector<node>::const_iterator n=r->nodes.begin(); n!=r->nodes.end(); 
> ++n)
> +  for(vector<node*>::const_iterator pn=r->nodes.begin(); pn!=r->nodes.end(); 
> ++pn)
>   {
> +    node *n = *pn ;
>     map<string,item*>::iterator it = p->x.find(n->name) ;
>     items[N++] = (it==p->x.end()) ? ++not_present, (item*)NULL : it->second ;
>   }
> @@ -70,8 +81,8 @@
>   for(map<string,item*>::iterator p_it=p->x.begin(); p_it!=p->x.end(); ++p_it)
>   {
>     bool found = false ;
> -    for(vector<node>::const_iterator r_it=r->nodes.begin(); !found && 
> r_it!=r->nodes.end(); ++r_it)
> -      found = r_it->name == p_it->first ;
> +    for(vector<node*>::const_iterator r_it=r->nodes.begin(); !found && 
> r_it!=r->nodes.end(); ++r_it)
> +      found = (*r_it)->name == p_it->first ;
>     if(found)
>       continue ;
>     if(counter++)
> @@ -88,10 +99,10 @@
> 
>   for(unsigned i=0; i<N; ++i)
>   {
> -    const node *n = &r->nodes[i] ;
> +    const node *n = r->nodes[i] ;
>     if(items[i]==NULL) // field is not present
>     {
> -      if(n->flag & MANDATORY) // but it's mandatory!
> +      if(n->is_mandatory) // but it's mandatory!
>       {
>         if(missed_fields)
>           *missed_fields += ", ", *missed_fields += n->name ;
> @@ -101,14 +112,27 @@
>       }
>       else if(add_defaults) // use the default value
>       {
> +        if (not n->is_array)
> +        {
> +#if 0
> #define _append(bit, type) if((n->flag&(bit|ARRAY))==bit) items[i] = 
> p->x[n->name] = new type(n->type##_value) ;
> -        _append(BITMASK, bitmask) ;
> -        _append(INTEGER, integer) ;
> -        _append(BYTES, bytes) ;
> +#else
> +#define _append(bit, type) if(n->is_##type() and not n->is_array) items[i] = 
> p->x[n->name] = new type(dynamic_cast<const node_##type*>(n)->value) ;
> +#endif
> +          _append(BITMASK, bitmask) ;
> +          _append(INTEGER, integer) ;
> +          _append(BYTES, bytes) ;
> #undef _append
> +#if 0
> #define _append_empty(bit, type) if((n->flag&(bit|ARRAY))==bit) items[i] = 
> p->x[n->name] = new type  ;
> -        _append_empty(ARRAY, array) ;
> -        _append_empty(RECORD, record) ;
> +#else
> +#define _append_empty(bit, type) items[i] = p->x[n->name] = new type ;
> +#endif
> +          if (n->is_record())
> +            _append_empty(RECORD, record) ;
> +        }
> +        else
> +          _append_empty(ARRAY, array) ;
> #undef _append_empty
> 
>       }
> @@ -117,7 +141,11 @@
>     {
>       try
>       {
> +#if 0
> #define _check(bit, type) if((n->flag&(bit|ARRAY))==bit) 
> cast_and_check<type>(items[i])
> +#else
> +#define _check(bit, type) if(n->is_##type() and not n->is_array) 
> cast_and_check<type>(items[i]) ;
> +#endif
>         _check(BITMASK, bitmask) ;
>         _check(INTEGER, integer) ;
>         _check(BYTES, bytes);
> @@ -137,40 +165,52 @@
>   }
> }
> 
> -void iodata::validator::check_children(record *p, const record_type *r, bool 
> write, item *items[], unsigned N)
> +void iodata::validator::check_children(record * /*p*/, const record_type *r, 
> bool write, item *items[], unsigned N)
> {
>   for(unsigned i=0; i<N; ++i)
>   {
>     if(items[i]==NULL)
>       continue ;
> -    int f = r->nodes[i].flag ;
> -    if((f&(ARRAY|RECORD))==0)
> +    // int f = r->nodes[i]->flag ;
> +    const node *n = r->nodes[i] ;
> +    if (not n->is_array and not n->is_record())
>       continue ;
> -    int element_type = f & (RECORD|INTEGER|BITMASK|BYTES) ;
> -    if(f&ARRAY)
> +    // int element_type = f & (RECORD|INTEGER|BITMASK|BYTES) ;
> +    if (n->is_array)
>     {
>       array *pa = cast_and_check<array> (items[i]) ;
>       for(unsigned j=0; j<pa->x.size(); ++j)
>       {
>         try
>         {
> +#if 0
>           switch(element_type)
>           {
>             default: throw exception((string)"internal error 
> in"+__PRETTY_FUNCTION__) ;
>             case BITMASK: cast_and_check<bitmask> (pa->x[j]) ; break ;
>             case INTEGER: cast_and_check<integer> (pa->x[j]) ; break ;
>             case BYTES:   cast_and_check<bytes> (pa->x[j]) ; break ;
> -            case RECORD:  check_record(cast_and_check<record>(pa->x[j]), 
> r->nodes[i].type, write) ;
> +            case RECORD:  check_record(cast_and_check<record>(pa->x[j]), 
> r->nodes[i]->type, write) ;
>           }
> +#else
> +          if (n->is_integer())
> +            cast_and_check<integer> (pa->x[j]) ;
> +          if (n->is_bytes())
> +            cast_and_check<bytes> (pa->x[j]) ;
> +          if (n->is_bitmask())
> +            cast_and_check<bitmask> (pa->x[j]) ;
> +          if (n->is_record())
> +            check_record(cast_and_check<record>(pa->x[j]), 
> dynamic_cast<const node_record*>(n)->type, write) ;
> +#endif
>         }
>         catch(exception &e)
>         {
> -          throw e.prepend_index(j).prepend_path(r->nodes[i].name) ;
> +          throw e.prepend_index(j).prepend_path(r->nodes[i]->name) ;
>         }
>       }
>     }
>     else // it's a record, because it's not an array
> -      check_record(cast_and_check<record>(items[i]), r->nodes[i].type, 
> write) ;
> +      check_record(cast_and_check<record>(items[i]), dynamic_cast<const 
> node_record*>(n)->type, write) ;
>   }
> }
> 
> @@ -180,9 +220,11 @@
>   {
>     if(items[i]==NULL)
>       continue ;
> -    int f = r->nodes[i].flag ;
> -    if(f & MANDATORY)
> +    // int f = r->nodes[i]->flag ;
> +    const node *n = r->nodes[i] ;
> +    if (n->is_mandatory)
>       continue ;
> +#if 0
>     if(f & ARRAY)
>       f = ARRAY ;
>     bool flag = false ;
> @@ -191,15 +233,30 @@
>       default: throw exception((string)"internal error 
> in"+__PRETTY_FUNCTION__) ;
>       case ARRAY: flag = cast_and_check<array>(items[i])->x.size()==0 ; break 
> ;
>       case RECORD: flag = cast_and_check<record>(items[i])->x.size()==0 ; 
> break ;
> -      case INTEGER: flag = 
> cast_and_check<integer>(items[i])->x==r->nodes[i].integer_value ; break ;
> -      case BYTES: flag = 
> cast_and_check<bytes>(items[i])->x==r->nodes[i].bytes_value ; break ;
> -      case BITMASK: flag = 
> *cast_and_check<bitmask>(items[i])==r->nodes[i].bitmask_value ; break ;
> +      case INTEGER: flag = 
> cast_and_check<integer>(items[i])->x==r->nodes[i]->integer_value ; break ;
> +      case BYTES: flag = 
> cast_and_check<bytes>(items[i])->x==r->nodes[i]->bytes_value ; break ;
> +      case BITMASK: flag = 
> *cast_and_check<bitmask>(items[i])==r->nodes[i]->bitmask_value ; break ;
>     }
> +#else
> +    bool flag = false ;
> +    if (n->is_array)
> +      flag = cast_and_check<array>(items[i])->x.size()==0 ;
> +    else if (n->is_record())
> +      flag = cast_and_check<record>(items[i])->x.size() == 0 ;
> +    else if (n->is_integer())
> +      flag = cast_and_check<integer>(items[i])->x == dynamic_cast<const 
> node_integer *> (n)->value ;
> +    else if (n->is_bytes())
> +      flag = cast_and_check<bytes>(items[i])->x == dynamic_cast<const 
> node_bytes *> (n)->value ;
> +    else if (n->is_bitmask())
> +      flag = *cast_and_check<bitmask>(items[i]) == dynamic_cast<const 
> node_bitmask *> (n)->value ;
> +    else
> +      throw exception((string)"internal error in"+__PRETTY_FUNCTION__) ;
> +#endif
>     if(flag)
>     {
>       delete items[i] ;
>       items[i] = NULL ;
> -      p->x.erase(r->nodes[i].name) ;
> +      p->x.erase(r->nodes[i]->name) ;
>     }
>   }
> }
> @@ -209,9 +266,26 @@
>   typedef map<string, item*>::const_iterator iterator ;
>   for(iterator it=lang->x.begin(); it!=lang->x.end(); ++it)
>   {
> +    if (it->first=="_function")
> +    {
> +      v_function = dynamic_cast<const bytes*> (it->second) -> x ;
> +      continue ;
> +    }
> +
>     const array *ap = dynamic_cast<const array*> (it->second) ;
>     unsigned N = ap->x.size() ;
>     // assert(N>0) ; // WHY >0 ? Empty type is okey?
> +
> +    if (it->first=="_namespace")
> +    {
> +      for(unsigned i=0; i<N; ++i)
> +      {
> +        string word = dynamic_cast<const bytes *> (ap->x[i]) -> x ;
> +        v_namespace.push_back(word) ;
> +      }
> +      continue ;
> +    }
> +
>     assert(types.find(it->first)==types.end()) ;
>     record_type *t = types[it->first] = new record_type ;
>     t->name = it->first ;
> @@ -219,29 +293,29 @@
>     for(unsigned i=0; i<N; ++i)
>     {
>       const record *r = dynamic_cast<const record *> (ap->x[i]) ;
> -      node &n = t->nodes[i] ;
> -      const bytes *item_name = dynamic_cast<const bytes*> 
> (r->x.find("name")->second) ;
>       const bitmask *item_type = dynamic_cast<const bitmask*> 
> (r->x.find("type")->second) ;
> -      n.flag = (validator_flag) (unsigned) item_type->value(&type_codec) ;
> -      n.name = item_name->x ;
> -      n.type = NULL ;
> -      if(n.flag & RECORD)
> -        n.type_name = dynamic_cast<const bytes*> 
> (r->x.find("record")->second)->x ;
> -      map<string,item*>::const_iterator value_it = r->x.find("value") ;
> -      if(value_it!=r->x.end())
> -      {
> -        const item *value_item = value_it->second ;
> -        if(n.flag & INTEGER)
> -          n.integer_value = dynamic_cast<const integer *> (value_item) -> x ;
> -        if(n.flag & BYTES)
> -          n.bytes_value = dynamic_cast<const bytes *> (value_item) -> x ;
> -        if(n.flag & BITMASK)
> -          n.bitmask_value = * dynamic_cast<const bitmask *> (value_item) ;
> -      }
> +      bool item_is_mandatory = item_type->bit_present("mandatory") ;
> +      bool item_is_array = item_type->bit_present("array") ;
> +      map<string,item*>::const_iterator value_iterator = r->x.find("value") ;
> +      const item *value_item = value_iterator==r->x.end() ? NULL : 
> value_iterator->second ;
> +      string item_name = dynamic_cast<const bytes*> 
> (r->x.find("name")->second) -> x ;
> +
> +      node *n = NULL ;
> +      if (item_type->bit_present("integer"))
> +        n = new node_integer(item_name, item_is_array, item_is_mandatory, 
> value_item ? dynamic_cast<const integer *> (value_item) -> x : 0) ;
> +      if (item_type->bit_present("bytes"))
> +        n = new node_bytes(item_name, item_is_array, item_is_mandatory, 
> value_item ? dynamic_cast<const bytes *> (value_item) -> x : "") ;
> +      if (item_type->bit_present("bitmask"))
> +        n = new node_bitmask(item_name, item_is_array, item_is_mandatory, 
> value_item ? * dynamic_cast<const bitmask *> (value_item) : bitmask()) ;
> +      if (item_type->bit_present("record"))
> +        n = new node_record(item_name, item_is_array, item_is_mandatory, 
> dynamic_cast<const bytes*> (r->x.find("record")->second)->x) ;
> +      log_assert(n) ;
> +      t->nodes[i] = n ;
>     }
>   }
> }
> 
> +#if 0
> iodata::bit_codec iodata::validator::type_codec ;
> 
> void iodata::validator::init_type_codec()
> @@ -253,21 +327,26 @@
>   type_codec.register_name(BYTES, "bytes") ;
>   type_codec.register_name(MANDATORY, "mandatory") ;
> }
> +#endif
> 
> void iodata::validator::link()
> {
>   for(map<string,record_type*>::iterator t=types.begin(); t!=types.end(); ++t)
>   {
>     assert(t->first==t->second->name) ;
> -    for(vector<node>::iterator n=t->second->nodes.begin(); 
> n!=t->second->nodes.end(); ++n)
> -      if(n->flag & RECORD)
> +    for(vector<node*>::iterator nn=t->second->nodes.begin(); 
> nn!=t->second->nodes.end(); ++nn)
> +    {
> +      node *n = *nn ;
> +      if (node_record *nr = dynamic_cast<node_record*> (n))
>       {
> -        if(n->type)
> +        assert(n->is_record()) ; // paranoia
> +        if (nr->type)
>           continue ;
> -        map<string,record_type*>::iterator res = types.find(n->type_name) ;
> +        map<string,record_type*>::iterator res = types.find(nr->type_name) ;
>         assert(res!=types.end()) ;
> -        n->type = res->second ;
> +        nr->type = res->second ;
>       }
> +    }
>   }
> }
> 
> --- src/validator.h
> +++ src/validator.h
> @@ -50,6 +50,7 @@
>   } ;
> 
>   struct record_type ;
> +#if 0
>   struct node ;
> 
>   struct node
> @@ -62,11 +63,68 @@
>     record_type *type ;
>     string type_name ;
>   } ;
> +#else
> +  struct node ;
> +  struct node_integer ;
> +  struct node_bytes ;
> +  struct node_bitmask ;
> +  struct node_record ;
> +
> +  struct node
> +  {
> +    string name ;
> +    bool is_array, is_mandatory ;
> +    node(const string &n, bool a, bool m) : name(n), is_array(a), 
> is_mandatory(m) { }
> +    virtual ~node() { }
> +    virtual bool is_integer() const { return false ; }
> +    virtual bool is_bytes() const { return false ; }
> +    virtual bool is_bitmask() const { return false ; }
> +    virtual bool is_record() const { return false ; }
> +    virtual const char *node_name() const = 0 ;
> +  } ;
> +
> +  struct node_integer : public node
> +  {
> +    int32_t value ;
> +    node_integer(const string &n, bool a, bool m, int32_t v) : node(n,a,m), 
> value(v) { }
> +   ~node_integer() { }
> +    bool is_integer() const { return true ; }
> +    const char *node_name() const { return "node_integer" ; }
> +  } ;
> +
> +  struct node_bytes : public node
> +  {
> +    string value ;
> +    node_bytes(const string &n, bool a, bool m, const string &v) : 
> node(n,a,m), value(v) { }
> +   ~node_bytes() { }
> +    bool is_bytes() const { return true ; }
> +    const char *node_name() const { return "node_bytes" ; }
> +  } ;
> +
> +  struct node_bitmask : public node
> +  {
> +    bitmask value ;
> +    node_bitmask(const string &n, bool a, bool m, const bitmask &v) : 
> node(n,a,m), value(v) { }
> +   ~node_bitmask() { }
> +    bool is_bitmask() const { return true ; }
> +    const char *node_name() const { return "node_bitmask" ; }
> +  } ;
> +
> +  struct node_record : public node
> +  {
> +    string type_name ;
> +    record_type *type ;
> +    node_record(const string &n, bool a, bool m, const string &tn, 
> record_type *t=NULL) : node(n,a,m), type_name(tn) { type = t ; }
> +   ~node_record() { }
> +    bool is_record() const { return true ; }
> +    const char *node_name() const { return "node_record" ; }
> +  } ;
> +#endif
> 
>   struct record_type
>   {
>     string name ;
> -    vector<node> nodes ;
> +    vector<node*> nodes ;
>   } ;
> 
> 
> @@ -75,11 +133,14 @@
>   {
>     if(T *p_cast = dynamic_cast<T*> (p))
>       return p_cast ;
> -    throw exception((string)T::static_class_name()+ "expected, but 
> "+p->class_name()+" found") ;
> +    throw exception((string)T::static_class_name()+ " expected, but 
> "+p->class_name()+" found") ;
>   }
> 
>   struct validator
>   {
> +    vector<string> v_namespace ;
> +    string v_function ;
> +
>     struct exception : public iodata::exception
>     {
>       string node_path ;
> @@ -90,8 +151,10 @@
>      ~exception() throw() { }
>     } ;
> 
> +#if 0
>     static bit_codec type_codec ;
>     static void init_type_codec() ;
> +#endif
>     static validator* from_file(const char *path) ;
>     iodata::record *record_from_file(const char *path, const char 
> *record_type, string &message) ;
>     bool record_to_file(const char *path, const char *record_type, 
> iodata::record *data, string &serialized) ;
> @@ -109,8 +172,10 @@
>     }
> #endif
>     map<string, record_type*> types ;
> +    bool is_static ; // flag used by structures generated by 
> iodata-type-to-c++ compiler
>     void load(const record *lang) ;
>     void link() ;
> +    void set_static() ;
> 
> #if 0
>     bool read_run(record *data) ;
> --- tests/tests.pro
> +++ tests/tests.pro
> @@ -1,3 +1,4 @@
> +VERSION = $$(IODATA_VERSION)
> TEMPLATE = app
> QT -= Gui
> TARGET = iodata-test
> --- type-to-cxx
> +++ type-to-cxx
> +(directory)
> --- type-to-cxx/type-to-cxx.cpp
> +++ type-to-cxx/type-to-cxx.cpp
> +#include <iostream>
> +using namespace std ;
> +
> +#include <argp.h>
> +
> +#include <qmlog>
> +
> +#include <iodata/iodata>
> +#include <iodata/validator>
> +#include <iodata/storage>
> +
> +void dump_h(ostringstream &h, iodata::validator *v)
> +{
> +  h << "#include <iodata/validator>" << endl ;
> +  for (vector<string>::const_iterator it=v->v_namespace.begin(); 
> it!=v->v_namespace.end(); ++it)
> +    h << "namespace " << *it << " {" << endl ;
> +  string foo = v->v_function ;
> +  if (foo.empty())
> +    foo = "foo" ;
> +  h << "iodata::validator * " << foo << "() ;" << endl ;
> +  for (unsigned i=0; i<v->v_namespace.size(); ++i)
> +    h << "}" ;
> +  if (not v->v_namespace.empty())
> +    h << endl ;
> +}
> +
> +void dump_cpp(ostringstream &cpp, iodata::validator *v)
> +{
> +  using iodata::/*validator::*/record_type ;
> +  using iodata::/*validator::*/node ;
> +  using iodata::/*validator::*/node_integer ;
> +  using iodata::/*validator::*/node_bytes ;
> +  using iodata::/*validator::*/node_bitmask ;
> +  using iodata::/*validator::*/node_record ;
> +
> +  string foo = v->v_function.empty() ? (string)"foo" : v->v_function ;
> +  for (vector<string>::const_reverse_iterator it=v->v_namespace.rbegin(); 
> it!=v->v_namespace.rend(); ++it)
> +    foo = *it + "::" + foo ;
> +
> +  cpp << "iodata::validator * " << foo << "()" << "{" << endl ;
> +  cpp << "static bool init_done = false ;" << endl ;
> +  cpp << "static iodata::validator A ;" << endl ;
> +  map<record_type*, int> record_type_to_num ;
> +  int rec_no = 0 ;
> +  for (map<string,record_type*>::iterator it = v->types.begin(); it != 
> v->types.end() and ++rec_no; ++it)
> +  {
> +    record_type *rt = it->second ;
> +    record_type_to_num[rt] = rec_no ;
> +    cpp << "static iodata::/*validator::*/record_type record_type" << rec_no 
> << " = { " ;
> +    cpp << '"' << it->first << '"' << ", " ;
> +    cpp << "vector<iodata::/*validator::*/node*>(" << rt->nodes.size() << ") 
> } ;" << endl ;
> +  }
> +  map<node*, int> node_to_num ;
> +  int node_no = 0 ;
> +  int bitmask_no = 0 ;
> +  for (map<string,record_type*>::iterator it = v->types.begin(); it != 
> v->types.end() and ++rec_no; ++it)
> +  {
> +    record_type *rt = it->second ;
> +    for (vector<node*>::iterator nit = rt->nodes.begin(); nit 
> !=rt->nodes.end(); ++nit)
> +    {
> +      node *no = *nit ;
> +      node_to_num[no] = ++node_no ;
> +      if (node_bitmask *nn = dynamic_cast<node_bitmask*> (no))
> +      {
> +        cpp << "static const char *bitmask_list" << ++bitmask_no << "[] = { 
> " ;
> +        for(set<string>::const_iterator it=nn->value.xs.begin(); 
> it!=nn->value.xs.end(); ++it)
> +          cpp << '"' << *it << '"' << ", " ;
> +        cpp << "NULL } ;" << endl ;
> +      }
> +      cpp << "static iodata::/*validator::*/" << no->node_name() << " node" 
> << node_no ;
> +      cpp << "(" << '"' << no->name << '"' << ", " ;
> +      cpp << no->is_array << ", " << no->is_mandatory << ", " ;
> +      if (node_integer *nn = dynamic_cast<node_integer*> (no))
> +        cpp << nn->value ;
> +      else if (node_bytes *nn = dynamic_cast<node_bytes*> (no))
> +        cpp << '"' << nn->value << '"' ;
> +      else if (node_record *nn = dynamic_cast<node_record*> (no))
> +      {
> +        cpp << '"' << nn->type_name << '"' ;
> +        int x = record_type_to_num[nn->type] ;
> +        log_assert(x>0, "unknown record index for name '%s'", 
> nn->type_name.c_str()) ;
> +        cpp << ", " << "&record_type" << x ;
> +      }
> +      else if (node_bitmask *nn = dynamic_cast<node_bitmask*> (no))
> +        cpp << "iodata::bitmask(" << nn->value.xl << ", bitmask_list" << 
> bitmask_no << ")" ;
> +      cpp << ") ;" << endl ;
> +    }
> +  }
> +  cpp << "if (not init_done) { init_done = true ;" << endl ;
> +  cpp << "A.set_static() ;" << endl ;
> +  for (map<string,record_type*>::iterator it = v->types.begin(); it != 
> v->types.end(); ++it)
> +  {
> +    record_type *r = it->second ;
> +    int x = record_type_to_num[r] ;
> +    log_assert(x>0, "unknown record index for name '%s'", r->name.c_str()) ;
> +    for (unsigned i=0; i<r->nodes.size(); ++i)
> +    {
> +      int j = node_to_num[r->nodes[i]] ;
> +      log_assert(j>0, "node index not found for type '%s' node #%d", 
> it->first.c_str(), i) ;
> +      cpp << "record_type" << x << ".nodes[" << i << "] = &node" << j << " 
> ;" << endl ;
> +    }
> +    cpp << "A.types[" << '"' << it->first << '"' << "] = &record_type" << x 
> << " ;" << endl ;
> +  }
> +  cpp << "}" << endl << "return &A ;" << endl << "}" << endl << endl ;
> +}
> +
> +int main_try(int ac, char **av)
> +{
> +  qmlog::enable() ;
> +  string c_output, h_output ;
> +  vector<string> input ;
> +
> +  const char *usage = "iodata-type-to-c++ -o output.c++ -d output.h 
> [input.type]..." ;
> +  for (int c; (c=getopt(ac, av, "ho:d:")) != -1; )
> +  {
> +    if (c=='h')
> +    {
> +      log_notice("usage: %s", usage) ;
> +      return 0 ;
> +    }
> +    else if(c=='o')
> +    {
> +      if (not c_output.empty())
> +      {
> +        log_error("only a single '-o' option allowed") ;
> +        return 1 ;
> +      }
> +      c_output = optarg ;
> +    }
> +    else if(c=='d')
> +    {
> +      if (not h_output.empty())
> +      {
> +        log_error("only a single '-d' option allowed") ;
> +        return 1 ;
> +      }
> +      h_output = optarg ;
> +    }
> +    else
> +    {
> +      log_error("usage: %s", usage) ;
> +      return 1 ;
> +    }
> +  }
> +  for (int i=optind; i < ac; ++i)
> +    input.push_back(av[i]) ;
> +
> +  if (input.size()==0)
> +  {
> +    log_error("no input files. usage: %s", usage) ;
> +    return 1 ;
> +  }
> +
> +  if (input.size()>1 and c_output.empty() and h_output.empty())
> +  {
> +    log_error("output file(s) must be specified if multiple input") ;
> +    return 1 ;
> +  }
> +
> +  if (c_output.empty() and input.size()==1)
> +    c_output = input[0] + ".c++" ;
> +
> +  if (h_output.empty() and input.size()==1)
> +    h_output = input[0] + ".h" ;
> +
> +  ostringstream cpp, h ;
> +  for (unsigned i=0; i<input.size(); ++i)
> +  {
> +    // log_notice("processing input file: '%s'", input[i].c_str()) ;
> +    iodata::validator *v = iodata::validator::from_file(input[i].c_str()) ;
> +    dump_cpp(cpp, v) ;
> +    dump_h(h, v) ;
> +  }
> +
> +  bool failure = false ;
> +
> +  if (not h_output.empty())
> +  {
> +    string header = h.str() ;
> +
> +    ostringstream sum ;
> +    sum << "iodata_type_to_cxx_" ;
> +    string salt = "$5$salt$" ;
> +    if (const char *enc = crypt(header.c_str(), salt.c_str()))
> +      for (const char *p=enc; *p; ++p)
> +        sum << (unsigned int)(unsigned char) *p ;
> +    else
> +      sum << header.length() ;
> +
> +    header = "#ifndef "+sum.str()+"\n" + "#define "+sum.str()+ "\n" + header 
> + "#endif\n" ;
> +
> +    if (iodata::storage::write_string_to_file(h_output.c_str(), 
> header.c_str()) < 0)
> +    {
> +      log_error("can't write header file to '%s': %m", h_output.c_str()) ;
> +      failure = true ;
> +    }
> +  }
> +
> +  if (not c_output.empty())
> +  {
> +    string include = "#include <iodata/validator>\n" ;
> +
> +    if (not h_output.empty())
> +      include += "#include \"" + h_output + "\"\n" ;
> +
> +    string program = include + cpp.str() ;
> +
> +    if (iodata::storage::write_string_to_file(c_output.c_str(), 
> program.c_str()) < 0)
> +    {
> +      log_error("can't write c++ output to '%s': %m", c_output.c_str()) ;
> +      failure = true ;
> +    }
> +  }
> +
> +  return failure ? 1 : 0 ;
> +}
> +
> +int main(int ac, char **av)
> +{
> +  try
> +  {
> +    return main_try(ac, av) ;
> +  }
> +  catch(const std::exception &e)
> +  {
> +    log_error("exception: %s", e.what()) ;
> +    return 1 ;
> +  }
> +}
> --- type-to-cxx/type-to-cxx.pro
> +++ type-to-cxx/type-to-cxx.pro
> +VERSION = $$(IODATA_VERSION)
> +TEMPLATE = app
> +QT -= gui
> +TARGET = iodata-type-to-c++
> +
> +CONFIG += qmlog
> +
> +INSTALLS = target
> +
> +LIBS += -liodata -lcrypt
> +QMAKE_LIBDIR_FLAGS += -L../src
> +INCLUDEPATH += ../H
> +
> +SOURCES = type-to-cxx.cpp
> +
> +target.path = /usr/bin
> 
> _______________________________________________
> MeeGo-commits mailing list
> [email protected]
> http://lists.meego.com/listinfo/meego-commits

_______________________________________________
MeeGo-packaging mailing list
[email protected]
http://lists.meego.com/listinfo/meego-packaging

Reply via email to