require 'ftools' MAX_ARGS = 15 # ====================================================================== # TODO: This doesn't properly handle escaped %'s def fill_template(template_str, args) result = template_str.dup args_not_found = args.dup result.gsub!(/%\(-(\w+)\)/) do |match| args_not_found.delete($1.intern) '' end result.gsub!(/%\((\w+)\)/) do |match| value = args[$1.intern] raise ArgumentError, "#{match} not found in argument hash" if value.nil? args_not_found.delete($1.intern) value end if args_not_found.size != 0 then args_not_found.each do |name, value| raise "#{name} not found in template" end end return result end GENERATED_FILE_WARNING = < macro_name }) end out.puts head if head namespace_wrapper = namespace ? method(:wrap_namespace) : method(:null_wrap) docstring_wrapper = docstring ? method(:wrap_docstring) : method(:null_wrap) namespace_wrapper.call(out, namespace) do docstring_wrapper.call(out, docstring) do yield out end end out.puts tail if tail out.puts "#include \"#{File.basename(filename, '.hpp')}.ipp\"" if include_ipp if header_bottom then out.puts fill_template(header_bottom, { :macro_name => macro_name }) end end end def null_wrap(*args) yield(*args) end def wrap_docstring(out, docstring) out.puts "#ifdef DOXYGEN" out.puts docstring out.puts "#else" out.puts "" yield out out.puts "#endif // DOXYGEN" end def wrap_namespace(out, namespace) namespaces = namespace.split('::') namespaces.each do |namespace| out.print "namespace #{namespace}\n{\n\n" end yield out namespaces.reverse.each do |namespace| out.print "\n} // namespace #{namespace}\n" end out.print "\n" end if __FILE__ == $0 then # ====================================================================== # TODO: Can I make protect accept a function or functor that # doesn't return a VALUE? docstring = < class Ruby_Function_%(j) { public: Ruby_Function_%(j)(Fun f%(member_args)); inline VALUE operator()(); static inline VALUE call(Ruby_Function_%(j) * f); private: Fun f_; %(member_decls) }; template inline Ruby_Function_%(j):: Ruby_Function_%(j)(Fun f%(member_args)) : f_(f)%(initializers) { } template inline VALUE Ruby_Function_%(j):: operator()() { return f_(%(member_params)); } template inline VALUE Ruby_Function_%(j):: call(Ruby_Function_%(j) * f) { return (*f)(); } } // namespace detail template inline VALUE protect(Fun fun%(args)) { typedef detail::Ruby_Function_%(j) RF; RF f(fun%(params)); return detail::protect( RUBY_VALUE_FUNC(RF::call), reinterpret_cast(&f)); } // --------------------------------------------------------------------- END hpp_template = < VALUE protect(Fun fun%(args)); END ipp_head = <::Type const t#{x}_; " } t_array.map { |x| "T#{x} const & t#{x}_; " } add_comma = (j == 0) ? '' : ', ' typename_list = (j == 0) ? '' : t_array.map { |x| "typename T#{x}" }.join(', ') member_arg_list = # t_array.map { |x| "typename detail::Copy_Type::Type t#{x}" }.join(', ') t_array.map { |x| "T#{x} const & t#{x}" }.join(', ') ipp.puts fill_template(ipp_template, { :j => j, :typenames => add_comma + typename_list, :args => add_comma + arg_list, :member_args => add_comma + member_arg_list, :initializers => add_comma + init_list, :member_params => member_param_list, :member_decls => member_decl_list, :types => add_comma + type_list, :params => add_comma + param_list }) ipp.puts '' hpp.puts fill_template(hpp_template, { :typenames => add_comma + typename_list, :args => add_comma + arg_list, }) hpp.puts '' end end end # ====================================================================== docstring = <. The return value will automatically be * converted to type Retval_T with from_ruby<>. * * E.g.: * \\code * float y = x.call("foo", z, 42); * \\endcode */ template Retval_T call(Identifier id, T1 arg1, T2 arg2, ...) const; //! Version of call which defaults to Object return type. Object call(Identifier id, T1 arg1, T2 arg2, ...) const; END ipp_template = <' convert_list = t_array.map { |x| "to_ruby(arg#{x})" }.join(', ') end ipp.puts fill_template(ipp_template, { :args => arg_list, :convert_list => convert_list, :j => j, :template => template, }) ipp.puts hpp.puts fill_template(hpp_template, { :args => arg_list, :template => template, }) hpp.puts end end end # ====================================================================== docstring = < Auto_Function_Wrapper:: Auto_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments) : Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args) , func_(func) , handler_(handler) , handler_guard_(&handler_) { if(arguments == 0) { arguments_ = new Arguments(); } else { arguments_ = arguments; } } template VALUE Auto_Function_Wrapper:: call(int argc, VALUE *argv, VALUE self) { Auto_Function_Wrapper * wrapper = 0; try { Data_Object data(detail::method_data()); wrapper = (Auto_Function_Wrapper *)data.get(); Arguments* args = wrapper->arguments_; bool hasSelf = (self && self != Qnil); if(args->count() >= 0) { hasSelf = hasSelf && args->count() == Num_Args - 1; } else { hasSelf = hasSelf && argc == Num_Args -1; } VALUE %(scan_def_list); if(hasSelf) { rb_scan_args(argc, argv, args->formatString(Num_Args - 1) %(scan_args_list)); Arg0_T arg0 = from_ruby(self); %(self_arg_convert_list) return to_ruby(wrapper->func_(%(arg_list))); } else { rb_scan_args(argc, argv, args->formatString(Num_Args) %(scan_args_list)); %(arg_convert_list) return to_ruby(wrapper->func_(%(arg_list))); } } catch(...) { RUBY_TRY { if(wrapper) { return wrapper->handler_->handle_exception(); } else { throw; } } RUBY_CATCH } } template Auto_Function_Wrapper:: Auto_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments) : Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args) , func_(func) , handler_(handler) , handler_guard_(&handler_) { if(arguments == 0) { arguments_ = new Arguments(); } else { arguments_ = arguments; } } template VALUE Auto_Function_Wrapper:: call(int argc, VALUE* argv, VALUE self) { Auto_Function_Wrapper * wrapper = 0; try { Data_Object data(detail::method_data()); wrapper = (Auto_Function_Wrapper *)data.get(); Arguments* args = wrapper->arguments_; bool hasSelf = (self && self != Qnil); if(args->count() >= 0) { hasSelf = hasSelf && args->count() == Num_Args - 1; } else { hasSelf = hasSelf && argc == Num_Args -1; } VALUE %(scan_def_list); if(hasSelf) { rb_scan_args(argc, argv, args->formatString(Num_Args - 1) %(scan_args_list)); Arg0_T arg0 = from_ruby(self); %(self_arg_convert_list) wrapper->func_(%(arg_list)); return Qnil; } else { rb_scan_args(argc, argv, args->formatString(Num_Args) %(scan_args_list)); %(arg_convert_list) wrapper->func_(%(arg_list)); return Qnil; } } catch(...) { RUBY_TRY { if(wrapper) { return wrapper->handler_->handle_exception(); } else { throw; } } RUBY_CATCH } } // --------------------------------------------------------------------- END # ====================================================================== # TODO: Should the handler copy the exception handler or keep a pointer # to it? hpp_template = < class Auto_Function_Wrapper%(specializations) : public Wrapped_Function { public: // typedef Ret_T (*Func)(%(typenames)); typedef Func_T Func; static const int Num_Args = %(j); Auto_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments = 0); static VALUE call(int argc, VALUE* args, VALUE self); private: Func func_; Data_Object handler_; Address_Registration_Guard handler_guard_; Arguments* arguments_; }; template class Auto_Function_Wrapper : public Wrapped_Function { public: // typedef void (*Func)(%(typenames)); typedef Func_T Func; static const int Num_Args = %(j); Auto_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments = 0); static VALUE call(int argc, VALUE* args, VALUE self); private: Func func_; Data_Object handler_; Address_Registration_Guard handler_guard_; Arguments* arguments_; }; // --------------------------------------------------------------------- END hpp_head = < Auto_Function_Wrapper:: Auto_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments) : Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args) , func_(func) , handler_(handler ? handler : new Default_Exception_Handler) , arguments_(arguments) { } template VALUE Auto_Function_Wrapper:: call() { Auto_Function_Wrapper * wrapper = 0; try { Data_Object data(detail::method_data()); wrapper = (Auto_Function_Wrapper*)data.get(); return to_ruby(wrapper->func_()); } catch(...) { RUBY_TRY { if(wrapper) { return wrapper->handler_->handle_exception(); } else { throw; } } RUBY_CATCH } } template Auto_Function_Wrapper:: Auto_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments) : Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args) , func_(func) , handler_(handler ? handler : new Default_Exception_Handler) , arguments_(arguments) { } template VALUE Auto_Function_Wrapper:: call() { Auto_Function_Wrapper * wrapper = 0; try { Data_Object data(detail::method_data()); wrapper = (Auto_Function_Wrapper *)data.get(); wrapper->func_(); return Qnil; } catch(...) { RUBY_TRY { if(wrapper) { return wrapper->handler_->handle_exception(); } else { throw; } } RUBY_CATCH } } END hpp_tail = < class Auto_Function_Wrapper : public Wrapped_Function { public: // typedef void (*Func)(); typedef Func_T Func; static const int Num_Args = 0; Auto_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments = new Arguments()); static VALUE call(); private: Func func_; Data_Object handler_; Arguments* arguments_; }; template class Auto_Function_Wrapper : public Wrapped_Function { public: // typedef void (*Func)(); typedef Func_T Func; static const int Num_Args = 0; Auto_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments = new Arguments()); static VALUE call(); private: Func func_; Data_Object handler_; Arguments* arguments_; }; END ipp_filename = 'detail/Auto_Function_Wrapper.ipp' hpp_filename = 'detail/Auto_Function_Wrapper.hpp' wrap_header(hpp_filename, 'Rice::detail', docstring, true, hpp_head) do |hpp| wrap_header(ipp_filename, 'Rice::detail', nil, false, ipp_head) do |ipp| MAX_ARGS.downto(0) do |j| t_array = (0..j).to_a scan_def_list = t_array.map { |x| "varg#{x}" }.join(', ') arg_def_list = t_array.map { |x| "Arg#{x}_T arg#{x};"} arg_list = t_array.map { |x| "arg#{x}" }.join(', ') scan_args_list = t_array.map { |x| ", &varg#{x}"} typenames = t_array.map { |x| "Arg#{x}_T" }.join(', ') arg_convert_list = t_array.map do |x| "Arg#{x}_T arg#{x} = args->getArgumentOrDefault(#{x}, varg#{x});" end.join("\n\t\t\t") self_arg_convert_list = (0...j).to_a.map do |x| n = x + 1 "Arg#{n}_T arg#{n} = args->getArgumentOrDefault(#{x}, varg#{x});" end.join("\n\t\t\t") if j == MAX_ARGS then typename_list = t_array.map { |x| "typename Arg#{x}_T" }.join(', ') typename_list_d = t_array.map { |x| "typename Arg#{x}_T = void" }.join(', ') specializations = '' else typename_list = t_array.map { |x| "typename Arg#{x}_T" }.join(', ') typename_list_d = typename_list specializations = "" end ipp.puts fill_template(ipp_template, { :scan_def_list => scan_def_list, :arg_list => arg_list, :typenames => typenames, :typename_list => typename_list, :arg_convert_list => arg_convert_list, :scan_args_list => scan_args_list, :self_arg_convert_list => self_arg_convert_list, }) hpp.puts fill_template(hpp_template, { :typenames => typenames, :typename_list_d => typename_list_d, :typename_list => typename_list, :j => j + 1, :specializations => specializations, }) end ipp.puts ipp_tail hpp.puts hpp_tail end end # ====================================================================== # TODO: Can I add another call() that works if from_ruby is defined # for a reference to self instead of a pointer to self (and same for # const reference and const pointer?) docstring = < Auto_Member_Function_Wrapper:: Auto_Member_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments) : Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args) , func_(func) , handler_(handler) , handler_guard_(&handler_) , arguments_(arguments) { if(arguments == 0) { arguments_ = new Arguments(); } else { arguments_ = arguments; } } template VALUE Auto_Member_Function_Wrapper:: call(int argc, VALUE* argv, VALUE self) { Auto_Member_Function_Wrapper * wrapper = 0; try { Data_Object data(detail::method_data()); wrapper = (Auto_Member_Function_Wrapper *)data.get(); Arguments* args = wrapper->arguments_; VALUE %(scan_def_list); %(arg_def_list) rb_scan_args(argc, argv, args->formatString(Num_Args), %(scan_args_list)); Self_T * obj = from_ruby(self); %(arg_convert_list) Func func = wrapper->func_; return to_ruby((*obj.*func)(%(arg_list))); } catch(...) { RUBY_TRY { if(wrapper) { return wrapper->handler_->handle_exception(); } else { throw; } } RUBY_CATCH } } template Auto_Member_Function_Wrapper:: Auto_Member_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments) : Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args) , func_(func) , handler_(handler) , handler_guard_(&handler_) , arguments_(arguments) { if(arguments == 0) { arguments_ = new Arguments(); } else { arguments_ = arguments; } } template VALUE Auto_Member_Function_Wrapper:: call(int argc, VALUE* argv, VALUE self) { Auto_Member_Function_Wrapper * wrapper = 0; try { Data_Object data(detail::method_data()); wrapper = (Auto_Member_Function_Wrapper *)data.get(); Arguments* args = wrapper->arguments_; VALUE %(scan_def_list); %(arg_def_list) rb_scan_args(argc, argv, args->formatString(Num_Args), %(scan_args_list)); Self_T * obj = from_ruby(self); %(arg_convert_list) Func func = wrapper->func_; (*obj.*func)(%(arg_list)); return Qnil; } catch(...) { RUBY_TRY { if(wrapper) { return wrapper->handler_->handle_exception(); } else { throw; } } RUBY_CATCH } } // --------------------------------------------------------------------- END ipp_tail = < Auto_Member_Function_Wrapper:: Auto_Member_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments) : Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args) , func_(func) , handler_(handler) , handler_guard_(&handler_) , arguments_(arguments) { if(arguments == 0) { arguments_ = new Arguments(); } else { arguments_ = arguments; } } template VALUE Auto_Member_Function_Wrapper:: call(int argc, VALUE* argv, VALUE self) { Auto_Member_Function_Wrapper * wrapper = 0; try { Data_Object data(detail::method_data()); wrapper = (Auto_Member_Function_Wrapper *)data.get(); rb_scan_args(argc, argv, "0"); Self_T * obj = from_ruby(self); Func func = wrapper->func_; return to_ruby((*obj.*func)()); } catch(...) { RUBY_TRY { if(wrapper) { return wrapper->handler_->handle_exception(); } else { throw; } } RUBY_CATCH } } template Auto_Member_Function_Wrapper:: Auto_Member_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments) : Wrapped_Function(RUBY_METHOD_FUNC(call), Num_Args) , func_(func) , handler_(handler) , handler_guard_(&handler_) , arguments_(arguments) { if(arguments == 0) { arguments_ = new Arguments(); } else { arguments_ = arguments; } } template VALUE Auto_Member_Function_Wrapper:: call(int argc, VALUE* argv, VALUE self) { Auto_Member_Function_Wrapper * wrapper = 0; try { Data_Object data(detail::method_data()); wrapper = (Auto_Member_Function_Wrapper *)data.get(); rb_scan_args(argc, argv, "0"); Self_T * obj = from_ruby(self); Func func = wrapper->func_; (*obj.*func)(); return Qnil; } catch(...) { RUBY_TRY { if(wrapper) { return wrapper->handler_->handle_exception(); } else { throw; } } RUBY_CATCH } } // --------------------------------------------------------------------- END hpp_template = < class Auto_Member_Function_Wrapper%(specializations) : public Wrapped_Function { public: typedef Func_T Func; static const int Num_Args = %(j); Auto_Member_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments = 0); static VALUE call(int argc, VALUE* argv, VALUE self); private: Func func_; Data_Object handler_; Address_Registration_Guard handler_guard_; Arguments* arguments_; }; template class Auto_Member_Function_Wrapper : public Wrapped_Function { public: typedef Func_T Func; static const int Num_Args = %(j); Auto_Member_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments = 0); static VALUE call(int argc, VALUE* argv, VALUE self); private: Func func_; Data_Object handler_; Address_Registration_Guard handler_guard_; Arguments* arguments_; }; // --------------------------------------------------------------------- END hpp_tail = < class Auto_Member_Function_Wrapper : public Wrapped_Function { public: typedef Func_T Func; static const int Num_Args = 0; Auto_Member_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments = 0); static VALUE call(int argc, VALUE* argv, VALUE self); private: Func func_; Data_Object handler_; Address_Registration_Guard handler_guard_; Arguments* arguments_; }; template class Auto_Member_Function_Wrapper : public Wrapped_Function { public: typedef Func_T Func; static const int Num_Args = 0; Auto_Member_Function_Wrapper( Func func, Data_Object handler, Arguments* arguments = 0); static VALUE call(int argc, VALUE* argv, VALUE self); private: Func func_; Data_Object handler_; Address_Registration_Guard handler_guard_; Arguments* arguments_; }; // --------------------------------------------------------------------- END ipp_head = < END ipp_filename = 'detail/Auto_Member_Function_Wrapper.ipp' hpp_filename = 'detail/Auto_Member_Function_Wrapper.hpp' wrap_header(hpp_filename, 'Rice::detail', docstring, true) do |hpp| wrap_header(ipp_filename, 'Rice::detail', nil, false, ipp_head) do |ipp| MAX_ARGS.downto(0) do |j| t_array = (0..j).to_a scan_def_list = t_array.map { |x| "varg#{x}" }.join(', ') arg_def_list = t_array.map { |x| "Arg#{x}_T arg#{x};"} arg_list = t_array.map { |x| "arg#{x}" }.join(', ') scan_args_list = t_array.map { |x| "&varg#{x}"}.join(', ') typenames = t_array.map { |x| ", Arg#{x}_T" } typenames_n = t_array.map { |x| "Arg#{x}_T" }.join(', ') arg_convert_list = t_array.map do |x| "if(args->isOptional(#{x}) && NIL_P(varg#{x})) { arg#{x} = args->get(#{x})->getDefaultValue(); } else { arg#{x} = from_ruby(varg#{x}); }" end.join("\n\t\t") if j == MAX_ARGS then typename_list = t_array.map { |x| ", typename Arg#{x}_T" }.join typename_list_d = t_array.map { |x| ", typename Arg#{x}_T = void" }.join specializations = '' else typename_list = t_array.map { |x| ", typename Arg#{x}_T" }.join typename_list_d = typename_list specializations = "" end ipp.puts fill_template(ipp_template, { :scan_def_list => scan_def_list, :arg_list => arg_list, :arg_def_list => arg_def_list, :typenames => typenames, :typename_list => typename_list, :scan_args_list => scan_args_list, :arg_convert_list => arg_convert_list, }) hpp.puts fill_template(hpp_template, { :typenames => typenames, :typename_list => typename_list, :typename_list_d => typename_list_d, :j => j + 1, :specializations => specializations, }) end hpp.puts hpp_tail ipp.puts ipp_tail end end docstring = < Wrapped_Function * wrap_function( Ret_T (*func)(%(typenames)), Data_Object handler, Arguments* arguments) { typedef Ret_T (*Func)(%(typenames)); return new Auto_Function_Wrapper(func, handler, arguments); } template Wrapped_Function * wrap_function( Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)), Data_Object handler, Arguments* arguments) { typedef Ret_T (Self_T::*Func)(%(typenames_no_self_no_comma)); return new Auto_Member_Function_Wrapper(func, handler, arguments); } template Wrapped_Function * wrap_function( Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)) const, Data_Object handler, Arguments* arguments) { typedef Ret_T (Self_T::*Func)(%(typenames_no_self_no_comma)) const; return new Auto_Member_Function_Wrapper(func, handler, arguments); } // --------------------------------------------------------------------- END hpp_template = < Wrapped_Function * wrap_function( Ret_T (*func)(%(typenames)), Data_Object handler = Rice::Nil, Arguments* arguments = 0); template Wrapped_Function * wrap_function( Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)), Data_Object handler = Rice::Nil, Arguments* arguments = 0); template Wrapped_Function * wrap_function( Ret_T (Self_T::*func)(%(typenames_no_self_no_comma)) const, Data_Object handler = Rice::Nil, Arguments* arguments = 0); // --------------------------------------------------------------------- END hpp_head = < Wrapped_Function * wrap_function( Ret_T (*func)(), Data_Object handler = Rice::Nil, Arguments* arguments = 0); END ipp_head = < Wrapped_Function * wrap_function( Ret_T (*func)(), Data_Object handler, Arguments* arguments) { typedef Ret_T (*Func)(); return new Auto_Function_Wrapper(func, handler, arguments); } END ipp_filename = 'detail/wrap_function.ipp' hpp_filename = 'detail/wrap_function.hpp' wrap_header(hpp_filename, 'Rice::detail', docstring, true, hpp_head) do |hpp| wrap_header(ipp_filename, 'Rice::detail', nil, false, ipp_head) do |ipp| ipp.puts ipp_start hpp.puts hpp_start for j in 0..MAX_ARGS do t_array = (0..j).to_a typenames = t_array.map { |x| "Arg#{x}_T" }.join(', ') typename_list = t_array.map { |x| "typename Arg#{x}_T" }.join(', ') t_array.shift typenames_no_self = t_array.map { |x| ", Arg#{x}_T" } typename_list_no_self = t_array.map { |x| ", typename Arg#{x}_T" } typenames_no_self_no_comma = typenames_no_self.to_s.sub(', ', '') ipp.puts fill_template(ipp_template, { :typenames => typenames, :typename_list => typename_list, :typenames_no_self => typenames_no_self, :typename_list_no_self => typename_list_no_self, :typenames_no_self_no_comma => typenames_no_self_no_comma, }) hpp.puts fill_template(hpp_template, { :typenames => typenames, :typename_list => typename_list, :typename_list_no_self => typename_list_no_self, :typenames_no_self_no_comma => typenames_no_self_no_comma, }) end end end # ====================================================================== # TODO: we have to implement this function in the class definition due # to a bug in g++ void_list = (0..MAX_ARGS).to_a.map { |x| ", typename Arg#{x}_T=void" } hpp_start = < class Constructor { private: Constructor() { } }; END hpp_template = < class Constructor { public: static void construct(Object self%(arg_list)) { DATA_PTR(self.value()) = new T(%(arg_names)); } }; END hpp_self_template = < class Constructor { public: static void construct(Object self%(arg_list)) { DATA_PTR(self.value()) = new T(self%(arg_names)); } }; END hpp_head = < typename_list, :type_list => type_list, :void_list => void_list, :arg_list => arg_list, :arg_names => arg_names }) end # For the self / Director system for j in 0..(MAX_ARGS - 1) do t_array = (1..j).to_a o_array = (j..(MAX_ARGS - 1)).to_a typename_list = t_array.map { |x| ", typename Arg#{x}_T" } type_list = t_array.map { |x| ", Arg#{x}_T" } void_list = o_array.map { |x| ", void" } arg_list = t_array.map { |x| ", Arg#{x}_T arg#{x}" } arg_names = t_array.map { |x| ", arg#{x}" } hpp.puts fill_template(hpp_self_template, { :typename_list => typename_list, :type_list => type_list, :void_list => void_list, :arg_list => arg_list, :arg_names => arg_names }) end end if ARGV[0] == '--clean' then $filenames.each do |filename| File.rm_f(filename) end end end # if __FILE__ == $0 then