2013-10-26 09:41:45 +02:00
/******************************************************************************
* Icinga 2 *
2015-01-22 12:00:23 +01:00
* Copyright ( C ) 2012 - 2015 Icinga Development Team ( http : //www.icinga.org) *
2013-10-26 09:41:45 +02:00
* *
* 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 ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU General Public License for more details . *
* *
* You should have received a copy of the GNU General Public License *
* along with this program ; if not , write to the Free Software Foundation *
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-05-25 16:23:35 +02:00
# include "classcompiler.hpp"
2013-10-26 09:41:45 +02:00
# include <iostream>
2014-11-30 23:32:13 +01:00
# include <sstream>
2013-10-26 09:41:45 +02:00
# include <fstream>
# include <stdexcept>
2013-12-13 12:54:14 +01:00
# include <map>
2014-11-30 23:32:13 +01:00
# include <set>
2013-12-13 12:54:14 +01:00
# include <vector>
2014-09-09 13:30:54 +02:00
# include <cstring>
2015-08-04 14:47:44 +02:00
# include <locale>
2014-09-09 16:43:21 +02:00
# ifndef _WIN32
# include <libgen.h>
2014-09-10 15:24:08 +02:00
# else /* _WIN32 */
# include <shlwapi.h>
2014-09-09 16:43:21 +02:00
# endif /* _WIN32 */
2013-10-26 09:41:45 +02:00
using namespace icinga ;
2015-03-28 11:04:42 +01:00
ClassCompiler : : ClassCompiler ( const std : : string & path , std : : istream & input ,
std : : ostream & oimpl , std : : ostream & oheader )
: m_Path ( path ) , m_Input ( input ) , m_Impl ( oimpl ) , m_Header ( oheader )
2013-10-26 09:41:45 +02:00
{
InitializeScanner ( ) ;
}
ClassCompiler : : ~ ClassCompiler ( void )
{
DestroyScanner ( ) ;
}
std : : string ClassCompiler : : GetPath ( void ) const
{
return m_Path ;
}
void * ClassCompiler : : GetScanner ( void )
{
return m_Scanner ;
}
size_t ClassCompiler : : ReadInput ( char * buffer , size_t max_size )
{
2015-03-28 11:04:42 +01:00
m_Input . read ( buffer , max_size ) ;
return static_cast < size_t > ( m_Input . gcount ( ) ) ;
2013-10-26 09:41:45 +02:00
}
2014-05-11 06:30:50 +02:00
void ClassCompiler : : HandleInclude ( const std : : string & path , const ClassDebugInfo & )
2013-10-26 09:41:45 +02:00
{
2015-03-28 11:04:42 +01:00
m_Header < < " #include \" " < < path < < " \" " < < std : : endl < < std : : endl ;
2013-10-26 09:41:45 +02:00
}
2014-05-11 06:30:50 +02:00
void ClassCompiler : : HandleAngleInclude ( const std : : string & path , const ClassDebugInfo & )
2013-10-26 09:41:45 +02:00
{
2015-03-28 11:04:42 +01:00
m_Header < < " #include < " < < path < < " > " < < std : : endl < < std : : endl ;
2013-10-26 09:41:45 +02:00
}
2014-05-11 06:30:50 +02:00
void ClassCompiler : : HandleNamespaceBegin ( const std : : string & name , const ClassDebugInfo & )
2013-10-26 09:41:45 +02:00
{
2015-03-28 11:04:42 +01:00
m_Header < < " namespace " < < name < < std : : endl
< < " { " < < std : : endl < < std : : endl ;
m_Impl < < " namespace " < < name < < std : : endl
< < " { " < < std : : endl < < std : : endl ;
2013-10-26 09:41:45 +02:00
}
2014-05-11 06:30:50 +02:00
void ClassCompiler : : HandleNamespaceEnd ( const ClassDebugInfo & )
2013-10-26 09:41:45 +02:00
{
2014-11-30 23:32:13 +01:00
HandleMissingValidators ( ) ;
2015-03-28 11:04:42 +01:00
m_Header < < " } " < < std : : endl ;
m_Impl < < " } " < < std : : endl ;
2013-10-26 09:41:45 +02:00
}
2014-05-11 06:30:50 +02:00
void ClassCompiler : : HandleCode ( const std : : string & code , const ClassDebugInfo & )
2013-10-26 09:41:45 +02:00
{
2015-03-28 11:04:42 +01:00
m_Header < < code < < std : : endl ;
2013-10-26 09:41:45 +02:00
}
2015-08-04 14:47:44 +02:00
void ClassCompiler : : HandleLibrary ( const std : : string & library , const ClassDebugInfo & locp )
{
m_Library = library ;
}
2013-12-13 12:54:14 +01:00
unsigned long ClassCompiler : : SDBM ( const std : : string & str , size_t len = std : : string : : npos )
{
unsigned long hash = 0 ;
size_t current = 0 ;
std : : string : : const_iterator it ;
for ( it = str . begin ( ) ; it ! = str . end ( ) ; it + + ) {
if ( current > = len )
2014-11-30 23:32:13 +01:00
break ;
2013-12-13 12:54:14 +01:00
char c = * it ;
2014-11-30 23:32:13 +01:00
hash = c + ( hash < < 6 ) + ( hash < < 16 ) - hash ;
2013-12-13 12:54:14 +01:00
2014-11-30 23:32:13 +01:00
current + + ;
}
2013-12-13 12:54:14 +01:00
2014-11-30 23:32:13 +01:00
return hash ;
2013-12-13 12:54:14 +01:00
}
2014-11-07 23:07:02 +01:00
static int TypePreference ( const std : : string & type )
{
if ( type = = " Value " )
return 0 ;
else if ( type = = " String " )
return 1 ;
else if ( type = = " double " )
return 2 ;
else if ( type . find ( " ::Ptr " ) ! = std : : string : : npos )
return 3 ;
else if ( type = = " int " )
return 4 ;
else
return 5 ;
}
static bool FieldLayoutCmp ( const Field & a , const Field & b )
{
2014-11-30 23:32:13 +01:00
return TypePreference ( a . Type . GetRealType ( ) ) < TypePreference ( b . Type . GetRealType ( ) ) ;
2014-11-07 23:07:02 +01:00
}
static bool FieldTypeCmp ( const Field & a , const Field & b )
{
2014-11-30 23:32:13 +01:00
return a . Type . GetRealType ( ) < b . Type . GetRealType ( ) ;
2014-11-07 23:07:02 +01:00
}
void ClassCompiler : : OptimizeStructLayout ( std : : vector < Field > & fields )
{
std : : sort ( fields . begin ( ) , fields . end ( ) , FieldTypeCmp ) ;
std : : stable_sort ( fields . begin ( ) , fields . end ( ) , FieldLayoutCmp ) ;
}
2014-05-11 06:30:50 +02:00
void ClassCompiler : : HandleClass ( const Klass & klass , const ClassDebugInfo & )
2013-10-26 09:41:45 +02:00
{
std : : vector < Field > : : const_iterator it ;
2015-08-04 14:47:44 +02:00
std : : string apiMacro ;
if ( ! m_Library . empty ( ) ) {
std : : string libName = m_Library ;
std : : locale locale ;
for ( std : : string : : size_type i = 0 ; i < libName . size ( ) ; i + + )
libName [ i ] = std : : toupper ( libName [ i ] , locale ) ;
m_Header < < " #ifndef I2_ " < < libName < < " _API " < < std : : endl
< < " # ifdef I2_ " < < libName < < " _BUILD " < < std : : endl
< < " # define I2_ " < < libName < < " _API I2_EXPORT " < < std : : endl
< < " # else /* I2_ " < < libName < < " _BUILD */ " < < std : : endl
< < " # define I2_ " < < libName < < " _API I2_IMPORT " < < std : : endl
< < " # endif /* I2_ " < < libName < < " _BUILD */ " < < std : : endl
< < " #endif /* I2_ " < < libName < < " _API */ " < < std : : endl < < std : : endl ;
apiMacro = " I2_ " + libName + " _API " ;
}
2013-11-04 19:12:34 +01:00
/* forward declaration */
2013-10-26 09:41:45 +02:00
if ( klass . Name . find_first_of ( ' : ' ) = = std : : string : : npos )
2015-03-28 11:04:42 +01:00
m_Header < < " class " < < klass . Name < < " ; " < < std : : endl < < std : : endl ;
2013-10-26 09:41:45 +02:00
2014-11-07 12:32:25 +01:00
/* TypeHelper */
if ( klass . Attributes & TAAbstract ) {
2015-03-28 11:04:42 +01:00
m_Header < < " template<> " < < std : : endl
< < " struct TypeHelper< " < < klass . Name < < " > " < < std : : endl
< < " { " < < std : : endl
< < " \t " < < " static ObjectFactory GetFactory(void) " < < std : : endl
< < " \t " < < " { " < < std : : endl
< < " \t \t " < < " return NULL; " < < std : : endl
< < " \t " < < " } " < < std : : endl
< < " }; " < < std : : endl < < std : : endl ;
2014-11-07 12:32:25 +01:00
}
2013-11-04 23:14:34 +01:00
/* TypeImpl */
2015-03-28 11:04:42 +01:00
m_Header < < " template<> " < < std : : endl
< < " class TypeImpl< " < < klass . Name < < " > "
< < " : public Type " ;
2014-04-05 22:17:20 +02:00
if ( ! klass . TypeBase . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Header < < " , public " + klass . TypeBase ;
2014-04-05 22:17:20 +02:00
2015-03-28 11:04:42 +01:00
m_Header < < std : : endl
< < " { " < < std : : endl
< < " public: " < < std : : endl ;
2013-11-04 19:12:34 +01:00
2015-08-04 14:47:44 +02:00
m_Impl < < " template class TypeImpl< " < < klass . Name < < " >; " < < std : : endl < < std : : endl ;
2013-11-08 11:17:46 +01:00
/* GetName */
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " virtual String GetName(void) const; " < < std : : endl ;
m_Impl < < " String TypeImpl< " < < klass . Name < < " >::GetName(void) const " < < std : : endl
< < " { " < < std : : endl
< < " \t " < < " return \" " < < klass . Name < < " \" ; " < < std : : endl
< < " } " < < std : : endl < < std : : endl ;
2013-11-08 11:17:46 +01:00
2013-12-18 10:18:57 +01:00
/* GetAttributes */
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " virtual int GetAttributes(void) const; " < < std : : endl ;
m_Impl < < " int TypeImpl< " < < klass . Name < < " >::GetAttributes(void) const " < < std : : endl
< < " { " < < std : : endl
< < " \t " < < " return " < < klass . Attributes < < " ; " < < std : : endl
< < " } " < < std : : endl < < std : : endl ;
2013-11-08 11:17:46 +01:00
2013-11-05 08:48:45 +01:00
/* GetBaseType */
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " virtual Type::Ptr GetBaseType(void) const; " < < std : : endl ;
2013-11-05 08:48:45 +01:00
2015-03-28 11:04:42 +01:00
m_Impl < < " Type::Ptr TypeImpl< " < < klass . Name < < " >::GetBaseType(void) const " < < std : : endl
< < " { " < < std : : endl
< < " \t " < < " return " ;
2013-11-05 08:48:45 +01:00
if ( ! klass . Parent . empty ( ) )
2015-08-04 14:47:44 +02:00
m_Impl < < klass . Parent < < " ::TypeInstance " ;
2013-11-05 08:48:45 +01:00
else
2015-08-04 14:47:44 +02:00
m_Impl < < " Object::TypeInstance " ;
2013-11-05 08:48:45 +01:00
2015-03-28 11:04:42 +01:00
m_Impl < < " ; " < < std : : endl
< < " } " < < std : : endl < < std : : endl ;
2013-11-05 08:48:45 +01:00
2013-11-04 19:12:34 +01:00
/* GetFieldId */
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " virtual int GetFieldId(const String& name) const; " < < std : : endl ;
2013-11-04 19:12:34 +01:00
2015-03-28 11:04:42 +01:00
m_Impl < < " int TypeImpl< " < < klass . Name < < " >::GetFieldId(const String& name) const " < < std : : endl
< < " { " < < std : : endl ;
2013-11-04 19:12:34 +01:00
2013-12-17 07:33:39 +01:00
if ( ! klass . Fields . empty ( ) ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " int offset = " ;
2013-12-17 07:33:39 +01:00
if ( ! klass . Parent . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Impl < < klass . Parent < < " ::TypeInstance->GetFieldCount() " ;
2013-12-17 07:33:39 +01:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < " 0 " ;
2013-11-04 19:12:34 +01:00
2015-03-28 11:04:42 +01:00
m_Impl < < " ; " < < std : : endl < < std : : endl ;
2013-12-17 07:33:39 +01:00
}
2013-11-04 19:12:34 +01:00
2013-12-13 12:54:14 +01:00
std : : map < int , std : : vector < std : : pair < int , std : : string > > > jumptable ;
int hlen = 0 , collisions = 0 ;
do {
int num = 0 ;
hlen + + ;
jumptable . clear ( ) ;
collisions = 0 ;
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
int hash = static_cast < int > ( SDBM ( it - > Name , hlen ) ) ;
jumptable [ hash ] . push_back ( std : : make_pair ( num , it - > Name ) ) ;
num + + ;
if ( jumptable [ hash ] . size ( ) > 1 )
collisions + + ;
}
} while ( collisions > = 5 & & hlen < 8 ) ;
if ( ! klass . Fields . empty ( ) ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t switch (static_cast<int>(Utility::SDBM(name, " < < hlen < < " ))) { " < < std : : endl ;
2013-12-13 12:54:14 +01:00
std : : map < int , std : : vector < std : : pair < int , std : : string > > > : : const_iterator itj ;
for ( itj = jumptable . begin ( ) ; itj ! = jumptable . end ( ) ; itj + + ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t case " < < itj - > first < < " : " < < std : : endl ;
2013-12-13 12:54:14 +01:00
std : : vector < std : : pair < int , std : : string > > : : const_iterator itf ;
for ( itf = itj - > second . begin ( ) ; itf ! = itj - > second . end ( ) ; itf + + ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t \t " < < " if (name == \" " < < itf - > second < < " \" ) " < < std : : endl
< < " \t \t \t \t " < < " return offset + " < < itf - > first < < " ; " < < std : : endl ;
2013-12-13 12:54:14 +01:00
}
2015-03-28 11:04:42 +01:00
m_Impl < < std : : endl
< < " \t \t \t \t break; " < < std : : endl ;
2013-12-13 12:54:14 +01:00
}
2015-03-28 11:04:42 +01:00
m_Impl < < " \t } " < < std : : endl ;
2013-11-04 19:12:34 +01:00
}
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < std : : endl
< < " \t " < < " return " ;
2013-10-26 09:41:45 +02:00
2013-11-04 19:12:34 +01:00
if ( ! klass . Parent . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Impl < < klass . Parent < < " ::TypeInstance->GetFieldId(name) " ;
2013-11-04 19:12:34 +01:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < " -1 " ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " ; " < < std : : endl
< < " } " < < std : : endl < < std : : endl ;
2013-10-26 09:41:45 +02:00
2013-11-04 19:12:34 +01:00
/* GetFieldInfo */
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " virtual Field GetFieldInfo(int id) const; " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " Field TypeImpl< " < < klass . Name < < " >::GetFieldInfo(int id) const " < < std : : endl
< < " { " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2013-11-04 19:12:34 +01:00
if ( ! klass . Parent . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " int real_id = id - " < < klass . Parent < < " ::TypeInstance->GetFieldCount(); " < < std : : endl
< < " \t " < < " if (real_id < 0) { return " < < klass . Parent < < " ::TypeInstance->GetFieldInfo(id); } " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2013-11-08 21:45:27 +01:00
if ( klass . Fields . size ( ) > 0 ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " switch ( " ;
2013-10-26 09:41:45 +02:00
2013-11-08 21:45:27 +01:00
if ( ! klass . Parent . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Impl < < " real_id " ;
2013-11-08 21:45:27 +01:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < " id " ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " ) { " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2013-12-13 12:54:14 +01:00
size_t num = 0 ;
2013-11-08 21:45:27 +01:00
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
2014-11-30 23:32:13 +01:00
std : : string ftype = it - > Type . GetRealType ( ) ;
if ( ftype = = " bool " | | ftype = = " int " | | ftype = = " double " )
ftype = " Number " ;
2014-10-31 08:49:14 +01:00
2014-12-10 09:04:49 +01:00
if ( ftype = = " int " | | ftype = = " double " )
2014-12-08 08:36:03 +01:00
ftype = " Number " ;
2014-12-10 09:04:49 +01:00
else if ( ftype = = " bool " )
ftype = " Boolean " ;
2014-12-08 08:36:03 +01:00
2014-11-10 20:06:28 +01:00
if ( ftype . find ( " ::Ptr " ) ! = std : : string : : npos )
2014-10-31 08:49:14 +01:00
ftype = ftype . substr ( 0 , ftype . size ( ) - strlen ( " ::Ptr " ) ) ;
if ( it - > Attributes & FAEnum )
2014-12-08 08:36:03 +01:00
ftype = " Number " ;
2014-10-31 08:49:14 +01:00
2014-11-30 23:32:13 +01:00
std : : string nameref ;
if ( it - > Type . IsName )
nameref = " \" " + it - > Type . TypeName + " \" " ;
else
nameref = " NULL " ;
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " case " < < num < < " : " < < std : : endl
2015-08-04 14:47:44 +02:00
< < " \t \t \t " < < " return Field( " < < num < < " , \" " < < ftype < < " \" , \" " < < it - > Name < < " \" , " < < nameref < < " , " < < it - > Attributes < < " ); " < < std : : endl ;
2013-11-08 21:45:27 +01:00
num + + ;
}
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " default: " < < std : : endl
< < " \t \t " ;
2013-11-04 19:12:34 +01:00
}
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " throw std::runtime_error( \" Invalid field ID. \" ); " < < std : : endl ;
2013-11-08 21:45:27 +01:00
if ( klass . Fields . size ( ) > 0 )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " } " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " } " < < std : : endl < < std : : endl ;
2013-10-26 09:41:45 +02:00
2013-11-04 19:12:34 +01:00
/* GetFieldCount */
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " virtual int GetFieldCount(void) const; " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " int TypeImpl< " < < klass . Name < < " >::GetFieldCount(void) const " < < std : : endl
< < " { " < < std : : endl
< < " \t " < < " return " < < klass . Fields . size ( ) ;
2013-10-26 09:41:45 +02:00
2013-11-04 19:12:34 +01:00
if ( ! klass . Parent . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Impl < < " + " < < klass . Parent < < " ::TypeInstance->GetFieldCount() " ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " ; " < < std : : endl
< < " } " < < std : : endl < < std : : endl ;
2013-10-26 09:41:45 +02:00
2014-11-07 12:32:25 +01:00
/* GetFactory */
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " virtual ObjectFactory GetFactory(void) const; " < < std : : endl ;
m_Impl < < " ObjectFactory TypeImpl< " < < klass . Name < < " >::GetFactory(void) const " < < std : : endl
< < " { " < < std : : endl
< < " \t " < < " return TypeHelper< " < < klass . Name < < " >::GetFactory(); " < < std : : endl
< < " } " < < std : : endl < < std : : endl ;
2014-11-07 12:32:25 +01:00
2015-02-25 12:43:03 +01:00
/* GetLoadDependencies */
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " virtual std::vector<String> GetLoadDependencies(void) const; " < < std : : endl ;
m_Impl < < " std::vector<String> TypeImpl< " < < klass . Name < < " >::GetLoadDependencies(void) const " < < std : : endl
< < " { " < < std : : endl
< < " \t " < < " std::vector<String> deps; " < < std : : endl ;
2015-02-25 12:43:03 +01:00
for ( std : : vector < std : : string > : : const_iterator itd = klass . LoadDependencies . begin ( ) ; itd ! = klass . LoadDependencies . end ( ) ; itd + + )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " deps.push_back( \" " < < * itd < < " \" ); " < < std : : endl ;
2015-02-25 12:43:03 +01:00
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " return deps; " < < std : : endl
2015-08-04 14:47:44 +02:00
< < " } " < < std : : endl < < std : : endl ;
/* RegisterAttributeHandler */
m_Header < < " public: " < < std : : endl
< < " \t " < < " virtual void RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback); " < < std : : endl ;
2015-02-25 12:43:03 +01:00
2015-08-04 14:47:44 +02:00
m_Impl < < " void TypeImpl< " < < klass . Name < < " >::RegisterAttributeHandler(int fieldId, const Type::AttributeHandler& callback) " < < std : : endl
< < " { " < < std : : endl ;
if ( ! klass . Parent . empty ( ) )
m_Impl < < " \t " < < " int real_id = fieldId - " < < klass . Parent < < " ::TypeInstance->GetFieldCount(); " < < std : : endl
< < " \t " < < " if (real_id < 0) { " < < klass . Parent < < " ::TypeInstance->RegisterAttributeHandler(fieldId, callback); return; } " < < std : : endl ;
m_Impl < < " \t " < < " switch ( " ;
if ( ! klass . Parent . empty ( ) )
m_Impl < < " real_id " ;
else
m_Impl < < " fieldId " ;
m_Impl < < " ) { " < < std : : endl ;
int num = 0 ;
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
m_Impl < < " \t \t " < < " case " < < num < < " : " < < std : : endl
< < " \t \t \t " < < " ObjectImpl< " < < klass . Name < < " >::On " < < it - > GetFriendlyName ( ) < < " Changed.connect(callback); " < < std : : endl
< < " \t \t \t " < < " break; " < < std : : endl ;
num + + ;
}
m_Impl < < " \t \t " < < " default: " < < std : : endl
< < " \t \t \t " < < " throw std::runtime_error( \" Invalid field ID. \" ); " < < std : : endl
< < " \t " < < " } " < < std : : endl ;
m_Impl < < " } " < < std : : endl < < std : : endl ;
2015-03-28 11:04:42 +01:00
m_Header < < " }; " < < std : : endl < < std : : endl ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Header < < std : : endl ;
2014-11-30 23:32:13 +01:00
2013-11-04 23:14:34 +01:00
/* ObjectImpl */
2015-03-28 11:04:42 +01:00
m_Header < < " template<> " < < std : : endl
2015-08-04 14:47:44 +02:00
< < " class " < < apiMacro < < " ObjectImpl< " < < klass . Name < < " > "
2015-03-28 11:04:42 +01:00
< < " : public " < < ( klass . Parent . empty ( ) ? " Object " : klass . Parent ) < < std : : endl
< < " { " < < std : : endl
< < " public: " < < std : : endl
< < " \t " < < " DECLARE_PTR_TYPEDEFS(ObjectImpl< " < < klass . Name < < " >); " < < std : : endl < < std : : endl ;
2014-11-30 23:32:13 +01:00
2015-08-04 14:47:44 +02:00
m_Impl < < " template class ObjectImpl< " < < klass . Name < < " >; " < < std : : endl < < std : : endl ;
2014-11-30 23:32:13 +01:00
/* Validate */
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " virtual void Validate(int types, const ValidationUtils& utils); " < < std : : endl ;
m_Impl < < " void ObjectImpl< " < < klass . Name < < " >::Validate(int types, const ValidationUtils& utils) " < < std : : endl
< < " { " < < std : : endl ;
2014-11-30 23:32:13 +01:00
if ( ! klass . Parent . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < klass . Parent < < " ::Validate(types, utils); " < < std : : endl < < std : : endl ;
2014-11-30 23:32:13 +01:00
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " if ( " < < ( it - > Attributes & ( FAEphemeral | FAConfig | FAState ) ) < < " & types) " < < std : : endl
< < " \t \t " < < " Validate " < < it - > GetFriendlyName ( ) < < " (Get " < < it - > GetFriendlyName ( ) < < " (), utils); " < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
2015-03-28 11:04:42 +01:00
m_Impl < < " } " < < std : : endl < < std : : endl ;
2014-11-30 23:32:13 +01:00
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " void SimpleValidate " < < it - > GetFriendlyName ( ) < < " ( " < < it - > Type . GetArgumentType ( ) < < " value, const ValidationUtils& utils); " < < std : : endl ;
m_Impl < < " void ObjectImpl< " < < klass . Name < < " >::SimpleValidate " < < it - > GetFriendlyName ( ) < < " ( " < < it - > Type . GetArgumentType ( ) < < " value, const ValidationUtils& utils) " < < std : : endl
< < " { " < < std : : endl ;
2014-11-30 23:32:13 +01:00
const Field & field = * it ;
if ( ( field . Attributes & ( FARequired ) ) | | field . Type . IsName ) {
if ( field . Attributes & FARequired ) {
if ( field . Type . GetRealType ( ) . find ( " ::Ptr " ) ! = std : : string : : npos )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " if (!value) " < < std : : endl ;
2014-11-30 23:32:13 +01:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " if (value.IsEmpty()) " < < std : : endl ;
2014-11-30 23:32:13 +01:00
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<DynamicObject *>(this), boost::assign::list_of( \" " < < field . Name < < " \" ), \" Attribute must not be empty. \" )); " < < std : : endl < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
if ( field . Type . IsName ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " String ref = value; " < < std : : endl
< < " \t " < < " if (!ref.IsEmpty() && !utils.ValidateName( \" " < < field . Type . TypeName < < " \" , ref)) " < < std : : endl
< < " \t \t " < < " BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<DynamicObject *>(this), boost::assign::list_of( \" " < < field . Name < < " \" ), \" Object ' \" + ref + \" ' of type ' " < < field . Type . TypeName
< < " ' does not exist. \" )); " < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
}
2015-03-28 11:04:42 +01:00
m_Impl < < " } " < < std : : endl < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
2013-11-04 19:12:34 +01:00
if ( ! klass . Fields . empty ( ) ) {
/* constructor */
2015-03-28 11:04:42 +01:00
m_Header < < " public: " < < std : : endl
< < " \t " < < " ObjectImpl< " < < klass . Name < < " >(void); " < < std : : endl ;
m_Impl < < " ObjectImpl< " < < klass . Name < < " >::ObjectImpl(void) " < < std : : endl
< < " { " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2013-11-04 19:12:34 +01:00
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
2015-08-04 14:47:44 +02:00
m_Impl < < " \t " < < " Set " < < it - > GetFriendlyName ( ) < < " ( " < < " GetDefault " < < it - > GetFriendlyName ( ) < < " (), true); " < < std : : endl ;
2013-11-04 19:12:34 +01:00
}
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " } " < < std : : endl < < std : : endl ;
/* destructor */
m_Header < < " public: " < < std : : endl
< < " \t " < < " ~ObjectImpl< " < < klass . Name < < " >(void); " < < std : : endl ;
m_Impl < < " ObjectImpl< " < < klass . Name < < " >::~ObjectImpl(void) " < < std : : endl
< < " { } " < < std : : endl < < std : : endl ;
2013-10-26 09:41:45 +02:00
/* SetField */
2015-03-28 11:04:42 +01:00
m_Header < < " protected: " < < std : : endl
2015-08-04 14:47:44 +02:00
< < " \t " < < " virtual void SetField(int id, const Value& value, bool suppress_events = false, const Value& cookie = Empty); " < < std : : endl ;
2015-03-28 11:04:42 +01:00
2015-08-04 14:47:44 +02:00
m_Impl < < " void ObjectImpl< " < < klass . Name < < " >::SetField(int id, const Value& value, bool suppress_events, const Value& cookie) " < < std : : endl
2015-03-28 11:04:42 +01:00
< < " { " < < std : : endl ;
2013-10-26 09:41:45 +02:00
if ( ! klass . Parent . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " int real_id = id - " < < klass . Parent < < " ::TypeInstance->GetFieldCount(); " < < std : : endl
2015-08-04 14:47:44 +02:00
< < " \t " < < " if (real_id < 0) { " < < klass . Parent < < " ::SetField(id, value, suppress_events, cookie); return; } " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " switch ( " ;
2013-10-26 09:41:45 +02:00
if ( ! klass . Parent . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Impl < < " real_id " ;
2013-10-26 09:41:45 +02:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < " id " ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " ) { " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2013-12-13 12:54:14 +01:00
size_t num = 0 ;
2013-10-26 09:41:45 +02:00
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " case " < < num < < " : " < < std : : endl
< < " \t \t \t " < < " Set " < < it - > GetFriendlyName ( ) < < " ( " ;
2013-10-26 09:41:45 +02:00
if ( it - > Attributes & FAEnum )
2015-03-28 11:04:42 +01:00
m_Impl < < " static_cast< " < < it - > Type . GetRealType ( ) < < " >(static_cast<int>( " ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " value " ;
2013-10-26 09:41:45 +02:00
if ( it - > Attributes & FAEnum )
2015-03-28 11:04:42 +01:00
m_Impl < < " )) " ;
2013-10-26 09:41:45 +02:00
2015-08-04 14:47:44 +02:00
m_Impl < < " , suppress_events, cookie); " < < std : : endl
2015-03-28 11:04:42 +01:00
< < " \t \t \t " < < " break; " < < std : : endl ;
2013-10-26 09:41:45 +02:00
num + + ;
}
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " default: " < < std : : endl
< < " \t \t \t " < < " throw std::runtime_error( \" Invalid field ID. \" ); " < < std : : endl
< < " \t " < < " } " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " } " < < std : : endl < < std : : endl ;
2013-10-26 09:41:45 +02:00
/* GetField */
2015-03-28 11:04:42 +01:00
m_Header < < " protected: " < < std : : endl
< < " \t " < < " virtual Value GetField(int id) const; " < < std : : endl ;
m_Impl < < " Value ObjectImpl< " < < klass . Name < < " >::GetField(int id) const " < < std : : endl
< < " { " < < std : : endl ;
2013-10-26 09:41:45 +02:00
if ( ! klass . Parent . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " int real_id = id - " < < klass . Parent < < " ::TypeInstance->GetFieldCount(); " < < std : : endl
< < " \t " < < " if (real_id < 0) { return " < < klass . Parent < < " ::GetField(id); } " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " switch ( " ;
2013-10-26 09:41:45 +02:00
if ( ! klass . Parent . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Impl < < " real_id " ;
2013-10-26 09:41:45 +02:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < " id " ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " ) { " < < std : : endl ;
2013-10-26 09:41:45 +02:00
num = 0 ;
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " case " < < num < < " : " < < std : : endl
< < " \t \t \t " < < " return Get " < < it - > GetFriendlyName ( ) < < " (); " < < std : : endl ;
2013-10-26 09:41:45 +02:00
num + + ;
}
2015-08-04 14:47:44 +02:00
m_Impl < < " \t \t " < < " default: " < < std : : endl
< < " \t \t \t " < < " throw std::runtime_error( \" Invalid field ID. \" ); " < < std : : endl
< < " \t " < < " } " < < std : : endl ;
m_Impl < < " } " < < std : : endl < < std : : endl ;
2015-08-13 08:52:00 +02:00
/* ValidateField */
m_Header < < " protected: " < < std : : endl
< < " \t " < < " virtual void ValidateField(int id, const Value& value, const ValidationUtils& utils); " < < std : : endl ;
m_Impl < < " void ObjectImpl< " < < klass . Name < < " >::ValidateField(int id, const Value& value, const ValidationUtils& utils) " < < std : : endl
< < " { " < < std : : endl ;
if ( ! klass . Parent . empty ( ) )
m_Impl < < " \t " < < " int real_id = id - " < < klass . Parent < < " ::TypeInstance->GetFieldCount(); " < < std : : endl
< < " \t " < < " if (real_id < 0) { " < < klass . Parent < < " ::ValidateField(id, value, utils); return; } " < < std : : endl ;
m_Impl < < " \t " < < " switch ( " ;
if ( ! klass . Parent . empty ( ) )
m_Impl < < " real_id " ;
else
m_Impl < < " id " ;
m_Impl < < " ) { " < < std : : endl ;
num = 0 ;
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
m_Impl < < " \t \t " < < " case " < < num < < " : " < < std : : endl
< < " \t \t \t " < < " Validate " < < it - > GetFriendlyName ( ) < < " ( " ;
if ( it - > Attributes & FAEnum )
m_Impl < < " static_cast< " < < it - > Type . GetRealType ( ) < < " >(static_cast<int>( " ;
m_Impl < < " value " ;
if ( it - > Attributes & FAEnum )
m_Impl < < " )) " ;
m_Impl < < " , utils); " < < std : : endl
< < " \t \t \t " < < " break; " < < std : : endl ;
num + + ;
}
m_Impl < < " \t \t " < < " default: " < < std : : endl
< < " \t \t \t " < < " throw std::runtime_error( \" Invalid field ID. \" ); " < < std : : endl
< < " \t " < < " } " < < std : : endl ;
m_Impl < < " } " < < std : : endl < < std : : endl ;
2015-08-04 14:47:44 +02:00
/* NotifyField */
m_Header < < " protected: " < < std : : endl
< < " \t " < < " virtual void NotifyField(int id, const Value& cookie = Empty); " < < std : : endl ;
m_Impl < < " void ObjectImpl< " < < klass . Name < < " >::NotifyField(int id, const Value& cookie) " < < std : : endl
< < " { " < < std : : endl ;
if ( ! klass . Parent . empty ( ) )
m_Impl < < " \t " < < " int real_id = id - " < < klass . Parent < < " ::TypeInstance->GetFieldCount(); " < < std : : endl
< < " \t " < < " if (real_id < 0) { " < < klass . Parent < < " ::NotifyField(id, cookie); return; } " < < std : : endl ;
m_Impl < < " \t " < < " switch ( " ;
if ( ! klass . Parent . empty ( ) )
m_Impl < < " real_id " ;
else
m_Impl < < " id " ;
m_Impl < < " ) { " < < std : : endl ;
num = 0 ;
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
m_Impl < < " \t \t " < < " case " < < num < < " : " < < std : : endl
< < " \t \t \t " < < " Notify " < < it - > GetFriendlyName ( ) < < " (cookie); " < < std : : endl
< < " \t \t \t " < < " break; " < < std : : endl ;
num + + ;
}
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " default: " < < std : : endl
< < " \t \t \t " < < " throw std::runtime_error( \" Invalid field ID. \" ); " < < std : : endl
< < " \t " < < " } " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " } " < < std : : endl < < std : : endl ;
2013-10-26 09:41:45 +02:00
/* getters */
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
std : : string prot ;
if ( it - > Attributes & FAGetProtected )
prot = " protected " ;
else
prot = " public " ;
2015-03-28 11:04:42 +01:00
m_Header < < prot < < " : " < < std : : endl
< < " \t " < < " virtual " < < it - > Type . GetRealType ( ) < < " Get " < < it - > GetFriendlyName ( ) < < " (void) const " ;
2015-02-09 08:50:17 +01:00
if ( it - > PureGetAccessor ) {
2015-03-28 11:04:42 +01:00
m_Header < < " = 0; " < < std : : endl ;
2015-02-09 08:50:17 +01:00
} else {
2015-03-28 11:04:42 +01:00
m_Header < < " ; " < < std : : endl ;
m_Impl < < it - > Type . GetRealType ( ) < < " ObjectImpl< " < < klass . Name < < " >::Get " < < it - > GetFriendlyName ( ) < < " (void) const " < < std : : endl
< < " { " < < std : : endl ;
2013-10-26 09:41:45 +02:00
2015-02-09 08:50:17 +01:00
if ( it - > GetAccessor . empty ( ) & & ! ( it - > Attributes & FANoStorage ) )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " return m_ " < < it - > GetFriendlyName ( ) < < " ; " < < std : : endl ;
2015-02-09 08:50:17 +01:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < it - > GetAccessor < < std : : endl ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " } " < < std : : endl < < std : : endl ;
2015-02-09 08:50:17 +01:00
}
2013-10-26 09:41:45 +02:00
}
/* setters */
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
std : : string prot ;
if ( it - > Attributes & FASetProtected )
prot = " protected " ;
else
prot = " public " ;
2015-03-28 11:04:42 +01:00
m_Header < < prot < < " : " < < std : : endl
2015-08-04 14:47:44 +02:00
< < " \t " < < " virtual void Set " < < it - > GetFriendlyName ( ) < < " ( " < < it - > Type . GetArgumentType ( ) < < " value, bool suppress_events = false, const Value& cookie = Empty) " ;
2013-10-26 09:41:45 +02:00
2015-02-09 08:50:17 +01:00
if ( it - > PureSetAccessor ) {
2015-03-28 11:04:42 +01:00
m_Header < < " = 0; " < < std : : endl ;
2015-02-09 08:50:17 +01:00
} else {
2015-03-28 11:04:42 +01:00
m_Header < < " ; " < < std : : endl ;
2015-08-04 14:47:44 +02:00
m_Impl < < " void ObjectImpl< " < < klass . Name < < " >::Set " < < it - > GetFriendlyName ( ) < < " ( " < < it - > Type . GetArgumentType ( ) < < " value, bool suppress_events, const Value& cookie) " < < std : : endl
2015-03-28 11:04:42 +01:00
< < " { " < < std : : endl ;
2015-02-09 08:50:17 +01:00
if ( it - > SetAccessor . empty ( ) & & ! ( it - > Attributes & FANoStorage ) )
2015-08-04 14:47:44 +02:00
m_Impl < < " \t " < < " m_ " < < it - > GetFriendlyName ( ) < < " = value; " < < std : : endl ;
2015-02-09 08:50:17 +01:00
else
2015-08-04 14:47:44 +02:00
m_Impl < < it - > SetAccessor < < std : : endl < < std : : endl ;
m_Impl < < " \t " < < " if (!suppress_events) " < < std : : endl
< < " \t \t " < < " Notify " < < it - > GetFriendlyName ( ) < < " (cookie); " < < std : : endl
< < " } " < < std : : endl < < std : : endl ;
2015-02-09 08:50:17 +01:00
}
2013-10-26 09:41:45 +02:00
}
2015-08-04 14:47:44 +02:00
/* notify */
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
std : : string prot ;
if ( it - > Attributes & FASetProtected )
prot = " protected " ;
else
prot = " public " ;
m_Header < < prot < < " : " < < std : : endl
< < " \t " < < " virtual void Notify " < < it - > GetFriendlyName ( ) < < " (const Value& cookie = Empty); " < < std : : endl ;
m_Impl < < " void ObjectImpl< " < < klass . Name < < " >::Notify " < < it - > GetFriendlyName ( ) < < " (const Value& cookie) " < < std : : endl
< < " { " < < std : : endl
< < " \t " < < " DynamicObject *dobj = dynamic_cast<DynamicObject *>(this); " < < std : : endl ;
if ( it - > Name ! = " active " ) {
m_Impl < < " \t " < < " if (!dobj || dobj->IsActive()) " < < std : : endl
< < " \t " ;
}
m_Impl < < " On " < < it - > GetFriendlyName ( ) < < " Changed(static_cast< " < < klass . Name < < " *>(this), cookie); " < < std : : endl
< < " } " < < std : : endl < < std : : endl ;
}
2013-10-26 09:41:45 +02:00
/* default */
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
2014-11-30 23:32:13 +01:00
std : : string realType = it - > Type . GetRealType ( ) ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Header < < " private: " < < std : : endl
2015-03-28 16:13:44 +01:00
< < " \t " < < " inline " < < realType < < " GetDefault " < < it - > GetFriendlyName ( ) < < " (void) const; " < < std : : endl ;
2015-03-28 11:04:42 +01:00
m_Impl < < realType < < " ObjectImpl< " < < klass . Name < < " >::GetDefault " < < it - > GetFriendlyName ( ) < < " (void) const " < < std : : endl
< < " { " < < std : : endl ;
2013-10-26 09:41:45 +02:00
if ( it - > DefaultAccessor . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " return " < < realType < < " (); " < < std : : endl ;
2013-10-26 09:41:45 +02:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < it - > DefaultAccessor < < std : : endl ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
m_Impl < < " } " < < std : : endl ;
2013-10-26 09:41:45 +02:00
}
2014-11-30 23:32:13 +01:00
/* validators */
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
2015-03-28 11:04:42 +01:00
m_Header < < " protected: " < < std : : endl
< < " \t " < < " virtual void Validate " < < it - > GetFriendlyName ( ) < < " ( " < < it - > Type . GetArgumentType ( ) < < " value, const ValidationUtils& utils); " < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
2013-10-26 09:41:45 +02:00
/* instance variables */
2015-03-28 11:04:42 +01:00
m_Header < < " private: " < < std : : endl ;
2013-10-26 09:41:45 +02:00
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
2015-02-09 14:09:43 +01:00
if ( ! ( it - > Attributes & FANoStorage ) )
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < it - > Type . GetRealType ( ) < < " m_ " < < it - > GetFriendlyName ( ) < < " ; " < < std : : endl ;
2013-10-26 09:41:45 +02:00
}
2015-08-04 14:47:44 +02:00
/* signal */
m_Header < < " public: " < < std : : endl ;
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
m_Header < < " \t " < < " static boost::signals2::signal<void (const intrusive_ptr< " < < klass . Name < < " >&, const Value&)> On " < < it - > GetFriendlyName ( ) < < " Changed; " < < std : : endl ;
m_Impl < < std : : endl < < " boost::signals2::signal<void (const intrusive_ptr< " < < klass . Name < < " >&, const Value&)> ObjectImpl< " < < klass . Name < < " >::On " < < it - > GetFriendlyName ( ) < < " Changed; " < < std : : endl < < std : : endl ;
}
2013-10-26 09:41:45 +02:00
}
2014-11-06 19:35:47 +01:00
if ( klass . Name = = " DynamicObject " )
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " friend class ConfigItem; " < < std : : endl ;
2014-11-06 19:35:47 +01:00
if ( ! klass . TypeBase . empty ( ) )
2015-03-28 11:04:42 +01:00
m_Header < < " \t " < < " friend class " < < klass . TypeBase < < " ; " < < std : : endl ;
2014-11-06 19:35:47 +01:00
2015-03-28 11:04:42 +01:00
m_Header < < " }; " < < std : : endl < < std : : endl ;
2014-11-30 23:32:13 +01:00
for ( it = klass . Fields . begin ( ) ; it ! = klass . Fields . end ( ) ; it + + ) {
m_MissingValidators [ std : : make_pair ( klass . Name , it - > GetFriendlyName ( ) ) ] = * it ;
}
}
2015-03-28 11:04:42 +01:00
void ClassCompiler : : CodeGenValidator ( const std : : string & name , const std : : string & klass , const std : : vector < Rule > & rules , const std : : string & field , const FieldType & fieldType , ValidatorType validatorType )
2014-11-30 23:32:13 +01:00
{
2015-03-28 23:38:05 +01:00
m_Impl < < " static void TIValidate " < < name < < " (const intrusive_ptr<ObjectImpl< " < < klass < < " > >& object, " ;
2014-11-30 23:32:13 +01:00
2015-03-28 23:38:05 +01:00
if ( validatorType ! = ValidatorField )
2015-03-28 11:04:42 +01:00
m_Impl < < " const String& key, " ;
2014-11-30 23:32:13 +01:00
2015-03-28 11:04:42 +01:00
m_Impl < < fieldType . GetArgumentType ( ) < < " value, std::vector<String>& location, const ValidationUtils& utils) " < < std : : endl
< < " { " < < std : : endl ;
2014-11-30 23:32:13 +01:00
if ( validatorType = = ValidatorField ) {
bool required = false ;
for ( std : : vector < Rule > : : size_type i = 0 ; i < rules . size ( ) ; i + + ) {
const Rule & rule = rules [ i ] ;
if ( ( rule . Attributes & RARequired ) & & rule . Pattern = = field ) {
required = true ;
break ;
}
}
if ( fieldType . GetRealType ( ) ! = " int " & & fieldType . GetRealType ( ) ! = " double " ) {
if ( fieldType . GetRealType ( ) = = " Value " | | fieldType . GetRealType ( ) = = " String " )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " if (value.IsEmpty()) " < < std : : endl ;
2014-11-30 23:32:13 +01:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " if (!value) " < < std : : endl ;
2014-11-30 23:32:13 +01:00
if ( required )
2015-03-28 11:04:42 +01:00
m_Impl < < " BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<DynamicObject *>(this), location, \" This attribute must not be empty. \" )); " < < std : : endl ;
2014-11-30 23:32:13 +01:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " return; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
2015-03-28 11:04:42 +01:00
m_Impl < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
}
2015-04-20 14:16:19 +02:00
if ( validatorType ! = ValidatorField )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " bool known_attribute = false; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
bool type_check = false ;
for ( std : : vector < Rule > : : size_type i = 0 ; i < rules . size ( ) ; i + + ) {
const Rule & rule = rules [ i ] ;
if ( rule . Attributes & RARequired )
continue ;
if ( validatorType = = ValidatorField & & rule . Pattern ! = field )
continue ;
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " do { " < < std : : endl ;
2014-11-30 23:32:13 +01:00
if ( validatorType ! = ValidatorField ) {
if ( rule . Pattern ! = " * " ) {
if ( rule . Pattern . find_first_of ( " *? " ) ! = std : : string : : npos )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " if (!Utility::Match( \" " < < rule . Pattern < < " \" , key)) " < < std : : endl ;
2014-11-30 23:32:13 +01:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " if (key != \" " < < rule . Pattern < < " \" ) " < < std : : endl ;
2014-11-30 23:32:13 +01:00
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t \t " < < " break; " < < std : : endl ;
2015-04-20 14:16:19 +02:00
}
2014-11-30 23:32:13 +01:00
2015-04-20 14:16:19 +02:00
m_Impl < < " \t \t " < < " known_attribute = true; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
if ( rule . IsName ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " if (value.IsScalar()) { " < < std : : endl
< < " \t \t \t " < < " if (utils.ValidateName( \" " < < rule . Type < < " \" , value)) " < < std : : endl
< < " \t \t \t \t " < < " return; " < < std : : endl
< < " \t \t \t " < < " else " < < std : : endl
< < " \t \t \t \t " < < " BOOST_THROW_EXCEPTION(ValidationError(dynamic_pointer_cast<DynamicObject>(object), location, \" Object ' \" + value + \" ' of type ' " < < rule . Type < < " ' does not exist. \" )); " < < std : : endl
< < " \t \t " < < " } " < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
if ( fieldType . GetRealType ( ) = = " Value " ) {
if ( rule . Type = = " String " )
2015-03-30 14:55:41 +02:00
m_Impl < < " \t \t " < < " if (value.IsEmpty() || value.IsScalar()) " < < std : : endl
2015-03-28 11:04:42 +01:00
< < " \t \t \t " < < " return; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
else if ( rule . Type = = " Number " ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " try { " < < std : : endl
< < " \t \t \t " < < " Convert::ToDouble(value); " < < std : : endl
< < " \t \t \t " < < " return; " < < std : : endl
< < " \t \t " < < " } catch (...) { } " < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
}
if ( rule . Type = = " Dictionary " | | rule . Type = = " Array " | | rule . Type = = " Function " ) {
if ( fieldType . GetRealType ( ) = = " Value " ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " if (value.IsObjectType< " < < rule . Type < < " >()) { " < < std : : endl ;
2014-11-30 23:32:13 +01:00
type_check = true ;
} else if ( fieldType . GetRealType ( ) ! = rule . Type + " ::Ptr " ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " if (dynamic_pointer_cast< " < < rule . Type < < " >(value)) { " < < std : : endl ;
2014-11-30 23:32:13 +01:00
type_check = true ;
}
if ( ! rule . Rules . empty ( ) ) {
bool indent = false ;
if ( rule . Type = = " Dictionary " ) {
if ( type_check )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t \t " < < " Dictionary::Ptr dict = value; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " const Dictionary::Ptr& dict = value; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
2015-03-28 11:04:42 +01:00
m_Impl < < ( type_check ? " \t " : " " ) < < " \t \t " < < " ObjectLock olock(dict); " < < std : : endl
< < ( type_check ? " \t " : " " ) < < " \t \t " < < " BOOST_FOREACH(const Dictionary::Pair& kv, dict) { " < < std : : endl
< < ( type_check ? " \t " : " " ) < < " \t \t \t " < < " const String& akey = kv.first; " < < std : : endl
< < ( type_check ? " \t " : " " ) < < " \t \t \t " < < " const Value& avalue = kv.second; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
indent = true ;
} else if ( rule . Type = = " Array " ) {
if ( type_check )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t \t " < < " Array::Ptr arr = value; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
else
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " const Array::Ptr& arr = value; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
2015-03-28 11:04:42 +01:00
m_Impl < < ( type_check ? " \t " : " " ) < < " \t \t " < < " Array::SizeType anum = 0; " < < std : : endl
< < ( type_check ? " \t " : " " ) < < " \t \t " < < " ObjectLock olock(arr); " < < std : : endl
< < ( type_check ? " \t " : " " ) < < " \t \t " < < " BOOST_FOREACH(const Value& avalue, arr) { " < < std : : endl
< < ( type_check ? " \t " : " " ) < < " \t \t \t " < < " String akey = Convert::ToString(anum); " < < std : : endl ;
2014-11-30 23:32:13 +01:00
indent = true ;
} else {
2015-03-28 11:04:42 +01:00
m_Impl < < ( type_check ? " \t " : " " ) < < " \t \t " < < " String akey = \" \" ; " < < std : : endl
< < ( type_check ? " \t " : " " ) < < " \t \t " < < " const Value& avalue = value; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
std : : string subvalidator_prefix ;
if ( validatorType = = ValidatorField )
subvalidator_prefix = klass ;
else
subvalidator_prefix = name ;
2015-03-28 11:04:42 +01:00
m_Impl < < ( type_check ? " \t " : " " ) < < ( indent ? " \t " : " " ) < < " \t \t " < < " location.push_back(akey); " < < std : : endl
< < ( type_check ? " \t " : " " ) < < ( indent ? " \t " : " " ) < < " \t \t " < < " TIValidate " < < subvalidator_prefix < < " _ " < < i < < " (object, akey, avalue, location, utils); " < < std : : endl ;
2014-11-30 23:32:13 +01:00
if ( rule . Type = = " Array " )
2015-03-28 11:04:42 +01:00
m_Impl < < ( type_check ? " \t " : " " ) < < " \t \t \t " < < " anum++; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
if ( rule . Type = = " Dictionary " | | rule . Type = = " Array " )
2015-03-28 11:04:42 +01:00
m_Impl < < ( type_check ? " \t " : " " ) < < " \t \t " < < " } " < < std : : endl ;
2014-11-30 23:32:13 +01:00
for ( std : : vector < Rule > : : size_type i = 0 ; i < rule . Rules . size ( ) ; i + + ) {
const Rule & srule = rule . Rules [ i ] ;
if ( ( srule . Attributes & RARequired ) = = 0 )
continue ;
if ( rule . Type = = " Dictionary " ) {
2015-03-28 11:04:42 +01:00
m_Impl < < ( type_check ? " \t " : " " ) < < " \t \t " < < " if (dict.Get( \" " < < srule . Pattern < < " \" ).IsEmpty()) " < < std : : endl
< < ( type_check ? " \t " : " " ) < < " \t \t \t " < < " BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<DynamicObject *>(this), location, \" Required dictionary item ' " < < srule . Pattern < < " ' is not set. \" )); " < < std : : endl ;
2014-11-30 23:32:13 +01:00
} else if ( rule . Type = = " Array " ) {
int index = - 1 ;
std : : stringstream idxbuf ;
idxbuf < < srule . Pattern ;
idxbuf > > index ;
if ( index = = - 1 ) {
std : : cerr < < " Invalid index for 'required' keyword: " < < srule . Pattern ;
std : : exit ( 1 ) ;
}
2015-03-28 11:04:42 +01:00
m_Impl < < ( type_check ? " \t " : " " ) < < " \t \t " < < " if (arr.GetLength() < " < < ( index + 1 ) < < " ) " < < std : : endl
< < ( type_check ? " \t " : " " ) < < " \t \t \t " < < " BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<DynamicObject *>(this), location, \" Required index ' " < < index < < " ' is not set. \" )); " < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
}
2015-03-28 11:04:42 +01:00
m_Impl < < ( type_check ? " \t " : " " ) < < ( indent ? " \t " : " " ) < < " \t \t " < < " location.pop_back(); " < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
2015-03-28 11:04:42 +01:00
m_Impl < < ( type_check ? " \t " : " " ) < < " \t \t " < < " return; " < < std : : endl ;
2014-11-30 23:32:13 +01:00
if ( fieldType . GetRealType ( ) = = " Value " | | fieldType . GetRealType ( ) ! = rule . Type + " ::Ptr " )
2015-03-28 11:04:42 +01:00
m_Impl < < " \t \t " < < " } " < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " } while (0); " < < std : : endl < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
if ( type_check | | validatorType ! = ValidatorField ) {
2015-04-20 14:16:19 +02:00
if ( validatorType ! = ValidatorField ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " \t " < < " if (!known_attribute) " < < std : : endl
< < " \t \t " < < " BOOST_THROW_EXCEPTION(ValidationError(dynamic_pointer_cast<DynamicObject>(object), location, \" Invalid attribute: \" + key)); " < < std : : endl
< < " \t " < < " else " < < std : : endl ;
2015-04-20 14:16:19 +02:00
}
2014-11-30 23:32:13 +01:00
2015-04-20 14:16:19 +02:00
m_Impl < < ( validatorType ! = ValidatorField ? " \t " : " " ) < < " \t " < < " BOOST_THROW_EXCEPTION(ValidationError(dynamic_pointer_cast<DynamicObject>(object), location, \" Invalid type. \" )); " < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
2015-03-28 11:04:42 +01:00
m_Impl < < " } " < < std : : endl < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
2015-03-28 11:04:42 +01:00
void ClassCompiler : : CodeGenValidatorSubrules ( const std : : string & name , const std : : string & klass , const std : : vector < Rule > & rules )
2014-11-30 23:32:13 +01:00
{
for ( std : : vector < Rule > : : size_type i = 0 ; i < rules . size ( ) ; i + + ) {
const Rule & rule = rules [ i ] ;
if ( rule . Attributes & RARequired )
continue ;
if ( ! rule . Rules . empty ( ) ) {
ValidatorType subtype ;
if ( rule . Type = = " Array " )
subtype = ValidatorArray ;
else if ( rule . Type = = " Dictionary " )
subtype = ValidatorDictionary ;
else {
std : : cerr < < " Invalid sub-validator type: " < < rule . Type < < std : : endl ;
std : : exit ( EXIT_FAILURE ) ;
}
std : : ostringstream namebuf ;
namebuf < < name < < " _ " < < i ;
CodeGenValidatorSubrules ( namebuf . str ( ) , klass , rule . Rules ) ;
FieldType ftype ;
ftype . IsName = false ;
ftype . TypeName = " Value " ;
CodeGenValidator ( namebuf . str ( ) , klass , rule . Rules , rule . Pattern , ftype , subtype ) ;
}
}
}
void ClassCompiler : : HandleValidator ( const Validator & validator , const ClassDebugInfo & )
{
CodeGenValidatorSubrules ( validator . Name , validator . Name , validator . Rules ) ;
for ( std : : map < std : : pair < std : : string , std : : string > , Field > : : const_iterator it = m_MissingValidators . begin ( ) ; it ! = m_MissingValidators . end ( ) ; it + + )
CodeGenValidator ( it - > first . first + it - > first . second , it - > first . first , validator . Rules , it - > second . Name , it - > second . Type , ValidatorField ) ;
for ( std : : map < std : : pair < std : : string , std : : string > , Field > : : const_iterator it = m_MissingValidators . begin ( ) ; it ! = m_MissingValidators . end ( ) ; it + + ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " void ObjectImpl< " < < it - > first . first < < " >::Validate " < < it - > first . second < < " ( " < < it - > second . Type . GetArgumentType ( ) < < " value, const ValidationUtils& utils) " < < std : : endl
< < " { " < < std : : endl
< < " \t " < < " SimpleValidate " < < it - > first . second < < " (value, utils); " < < std : : endl
< < " \t " < < " std::vector<String> location; " < < std : : endl
< < " \t " < < " location.push_back( \" " < < it - > second . Name < < " \" ); " < < std : : endl
< < " \t " < < " TIValidate " < < it - > first . first < < it - > first . second < < " (this, value, location, utils); " < < std : : endl
< < " } " < < std : : endl < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
m_MissingValidators . clear ( ) ;
}
void ClassCompiler : : HandleMissingValidators ( void )
{
for ( std : : map < std : : pair < std : : string , std : : string > , Field > : : const_iterator it = m_MissingValidators . begin ( ) ; it ! = m_MissingValidators . end ( ) ; it + + ) {
2015-03-28 11:04:42 +01:00
m_Impl < < " void ObjectImpl< " < < it - > first . first < < " >::Validate " < < it - > first . second < < " ( " < < it - > second . Type . GetArgumentType ( ) < < " value, const ValidationUtils& utils) " < < std : : endl
< < " { " < < std : : endl
< < " \t " < < " SimpleValidate " < < it - > first . second < < " (value, utils); " < < std : : endl
< < " } " < < std : : endl < < std : : endl ;
2014-11-30 23:32:13 +01:00
}
m_MissingValidators . clear ( ) ;
2013-10-26 09:41:45 +02:00
}
2015-03-28 11:04:42 +01:00
void ClassCompiler : : CompileFile ( const std : : string & inputpath ,
const std : : string & implpath , const std : : string & headerpath )
2013-10-26 09:41:45 +02:00
{
2015-03-28 11:04:42 +01:00
std : : ifstream input ;
input . open ( inputpath . c_str ( ) , std : : ifstream : : in ) ;
if ( ! input ) {
std : : cerr < < " Could not open input file: " < < inputpath < < std : : endl ;
std : : exit ( EXIT_FAILURE ) ;
}
std : : string tmpheaderpath = headerpath + " .tmp " ;
std : : ofstream oheader ;
oheader . open ( tmpheaderpath . c_str ( ) , std : : ofstream : : out ) ;
if ( ! oheader ) {
std : : cerr < < " Could not open header file: " < < tmpheaderpath < < std : : endl ;
std : : exit ( EXIT_FAILURE ) ;
}
std : : string tmpimplpath = implpath + " .tmp " ;
std : : ofstream oimpl ;
oimpl . open ( tmpimplpath . c_str ( ) , std : : ofstream : : out ) ;
if ( ! oimpl ) {
std : : cerr < < " Could not open implementation file: " < < tmpimplpath < < std : : endl ;
std : : exit ( EXIT_FAILURE ) ;
}
CompileStream ( inputpath , input , oimpl , oheader ) ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
input . close ( ) ;
oimpl . close ( ) ;
oheader . close ( ) ;
2013-10-26 09:41:45 +02:00
2015-03-28 11:04:42 +01:00
# ifdef _WIN32
_unlink ( headerpath . c_str ( ) ) ;
# endif /* _WIN32 */
if ( rename ( tmpheaderpath . c_str ( ) , headerpath . c_str ( ) ) < 0 ) {
std : : cerr < < " Could not rename header file: " < < tmpheaderpath < < " -> " < < headerpath < < std : : endl ;
std : : exit ( EXIT_FAILURE ) ;
}
# ifdef _WIN32
_unlink ( implpath . c_str ( ) ) ;
# endif /* _WIN32 */
if ( rename ( tmpimplpath . c_str ( ) , implpath . c_str ( ) ) < 0 ) {
std : : cerr < < " Could not rename implementation file: " < < tmpimplpath < < " -> " < < implpath < < std : : endl ;
std : : exit ( EXIT_FAILURE ) ;
}
2013-10-26 09:41:45 +02:00
}
2014-11-30 23:32:13 +01:00
std : : string ClassCompiler : : BaseName ( const std : : string & path )
2014-09-09 13:30:54 +02:00
{
char * dir = strdup ( path . c_str ( ) ) ;
std : : string result ;
if ( dir = = NULL )
throw std : : bad_alloc ( ) ;
# ifndef _WIN32
result = basename ( dir ) ;
# else /* _WIN32 */
result = PathFindFileName ( dir ) ;
# endif /* _WIN32 */
free ( dir ) ;
return result ;
}
std : : string ClassCompiler : : FileNameToGuardName ( const std : : string & fname )
{
std : : string result = fname ;
2015-03-28 11:04:42 +01:00
for ( std : : string : : size_type i = 0 ; i < result . size ( ) ; i + + ) {
2014-09-09 13:30:54 +02:00
result [ i ] = toupper ( result [ i ] ) ;
if ( result [ i ] = = ' . ' )
result [ i ] = ' _ ' ;
}
return result ;
}
2015-03-28 11:04:42 +01:00
void ClassCompiler : : CompileStream ( const std : : string & path , std : : istream & input ,
std : : ostream & oimpl , std : : ostream & oheader )
2013-10-26 09:41:45 +02:00
{
2015-03-28 11:04:42 +01:00
input . exceptions ( std : : istream : : badbit ) ;
2013-10-26 09:41:45 +02:00
2014-09-09 13:30:54 +02:00
std : : string guard_name = FileNameToGuardName ( BaseName ( path ) ) ;
2015-03-28 11:04:42 +01:00
oheader < < " #ifndef " < < guard_name < < std : : endl
< < " #define " < < guard_name < < std : : endl < < std : : endl ;
oheader < < " #include \" base/object.hpp \" " < < std : : endl
< < " #include \" base/type.hpp \" " < < std : : endl
< < " #include \" base/value.hpp \" " < < std : : endl
< < " #include \" base/array.hpp \" " < < std : : endl
2015-08-04 14:47:44 +02:00
< < " #include \" base/dictionary.hpp \" " < < std : : endl
< < " #include <boost/signals2.hpp> " < < std : : endl < < std : : endl ;
2015-03-28 11:04:42 +01:00
oimpl < < " #include \" base/exception.hpp \" " < < std : : endl
< < " #include \" base/objectlock.hpp \" " < < std : : endl
< < " #include \" base/utility.hpp \" " < < std : : endl
< < " #include \" base/convert.hpp \" " < < std : : endl
< < " #include <boost/foreach.hpp> " < < std : : endl
< < " #include <boost/assign/list_of.hpp> " < < std : : endl
< < " #ifdef _MSC_VER " < < std : : endl
< < " #pragma warning( push ) " < < std : : endl
< < " #pragma warning( disable : 4244 ) " < < std : : endl
< < " #pragma warning( disable : 4800 ) " < < std : : endl
< < " #endif /* _MSC_VER */ " < < std : : endl < < std : : endl ;
ClassCompiler ctx ( path , input , oimpl , oheader ) ;
2013-10-26 09:41:45 +02:00
ctx . Compile ( ) ;
2015-03-28 11:04:42 +01:00
oheader < < " #endif /* " < < guard_name < < " */ " < < std : : endl ;
2014-09-09 13:30:54 +02:00
2015-03-28 11:04:42 +01:00
oimpl < < " #ifdef _MSC_VER " < < std : : endl
< < " #pragma warning ( pop ) " < < std : : endl
< < " #endif /* _MSC_VER */ " < < std : : endl ;
2013-10-26 09:41:45 +02:00
}