STL stream support for Ruby.
docstring and autodoc support for Ruby. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9750 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
1992714551
commit
594483bbda
12 changed files with 630 additions and 3 deletions
|
|
@ -8,13 +8,12 @@ Version 1.3.32 (in progress)
|
||||||
Added typename for raw lua_State*
|
Added typename for raw lua_State*
|
||||||
Added documentation on native functions.
|
Added documentation on native functions.
|
||||||
|
|
||||||
05/07/2007: gga
|
05/02/2007: gga
|
||||||
[Ruby]
|
[Ruby]
|
||||||
Docstrings are now supported.
|
Docstrings are now supported.
|
||||||
%feature("autodoc") and %feature("docstring") are now
|
%feature("autodoc") and %feature("docstring") are now
|
||||||
properly supported in Ruby. These features will generate
|
properly supported in Ruby. These features will generate
|
||||||
a _wrap.cxx file with rdoc comments in them.
|
a _wrap.cxx file with rdoc comments in them.
|
||||||
TODO: add doxygen -> rdoc conversion support.
|
|
||||||
|
|
||||||
05/05/2007: gga
|
05/05/2007: gga
|
||||||
[Ruby]
|
[Ruby]
|
||||||
|
|
@ -40,6 +39,14 @@ Version 1.3.32 (in progress)
|
||||||
exceptions. Now, nil is returned instead, following ruby's
|
exceptions. Now, nil is returned instead, following ruby's
|
||||||
standard Array behavior.
|
standard Array behavior.
|
||||||
|
|
||||||
|
05/02/2007: gga
|
||||||
|
[Ruby]
|
||||||
|
Changed the value of SWIG_TYPECHECK_BOOL to be 10000 (ie. higher
|
||||||
|
than that of all integers). This is because Ruby allows typecasting
|
||||||
|
integers down to booleans which can make overloaded functions on
|
||||||
|
bools and integers to fail.
|
||||||
|
(bug# 1488142)
|
||||||
|
|
||||||
05/02/2007: gga
|
05/02/2007: gga
|
||||||
[Ruby]
|
[Ruby]
|
||||||
Fixed a subtle bug in multiple argouts that could get triggered if
|
Fixed a subtle bug in multiple argouts that could get triggered if
|
||||||
|
|
|
||||||
59
Examples/test-suite/li_std_stream.i
Normal file
59
Examples/test-suite/li_std_stream.i
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
%module li_std_stream
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct A;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%include <std_iostream.i>
|
||||||
|
%include <std_sstream.i>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%callback(1) A::bar;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
|
||||||
|
struct B {
|
||||||
|
virtual ~B()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct A : B
|
||||||
|
{
|
||||||
|
void __add__(int a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void __add__(double a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bar(int a){
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int foo(int a, int (*pf)(int a))
|
||||||
|
{
|
||||||
|
return pf(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream& __rlshift__(std::ostream& out)
|
||||||
|
{
|
||||||
|
out << "A class";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
%extend std::basic_ostream<char>{
|
||||||
|
std::basic_ostream<char>&
|
||||||
|
operator<<(const A& a)
|
||||||
|
{
|
||||||
|
*self << "A class";
|
||||||
|
return *self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
22
Examples/test-suite/ruby/li_std_stream_runme.rb
Executable file
22
Examples/test-suite/ruby/li_std_stream_runme.rb
Executable file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
#
|
||||||
|
# Simple test of std::ostringstream.
|
||||||
|
#
|
||||||
|
# Author:: gga
|
||||||
|
# Copyright:: 2007
|
||||||
|
# License:: Ruby
|
||||||
|
#
|
||||||
|
|
||||||
|
require 'swig_assert'
|
||||||
|
|
||||||
|
require 'li_std_stream'
|
||||||
|
include Li_std_stream
|
||||||
|
|
||||||
|
swig_assert_each_line(<<'EOF', binding)
|
||||||
|
|
||||||
|
a = A.new
|
||||||
|
o = Ostringstream.new
|
||||||
|
o << a << " " << 2345 << " " << 1.435
|
||||||
|
o.str == "A class 2345 1.435"
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
@ -4,6 +4,9 @@
|
||||||
/* ------------------------------------------------------------
|
/* ------------------------------------------------------------
|
||||||
* Fragment section
|
* Fragment section
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
|
/* bool is dangerous in Ruby, change precedence */
|
||||||
|
#undef SWIG_TYPECHECK_BOOL
|
||||||
|
%define SWIG_TYPECHECK_BOOL 10000 %enddef
|
||||||
|
|
||||||
/* Include fundamental fragemt definitions */
|
/* Include fundamental fragemt definitions */
|
||||||
%include <typemaps/fragments.swg>
|
%include <typemaps/fragments.swg>
|
||||||
|
|
|
||||||
97
Lib/ruby/std_basic_string.i
Normal file
97
Lib/ruby/std_basic_string.i
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
#if !defined(SWIG_STD_STRING)
|
||||||
|
#define SWIG_STD_BASIC_STRING
|
||||||
|
|
||||||
|
%include <rubycontainer.swg>
|
||||||
|
|
||||||
|
#define %swig_basic_string(Type...) %swig_sequence_methods_val(Type)
|
||||||
|
|
||||||
|
|
||||||
|
%traits_swigtype(std::basic_string<char>);
|
||||||
|
%fragment(SWIG_Traits_frag(std::basic_string<char>));
|
||||||
|
|
||||||
|
|
||||||
|
%fragment(SWIG_AsPtr_frag(std::basic_string<char>),"header",
|
||||||
|
fragment="SWIG_AsCharPtrAndSize") {
|
||||||
|
SWIGINTERN int
|
||||||
|
SWIG_AsPtr(std::basic_string<char>)(VALUE obj, std::string **val)
|
||||||
|
{
|
||||||
|
static swig_type_info* string_info =
|
||||||
|
SWIG_TypeQuery("std::basic_string<char> *");
|
||||||
|
std::string *vptr;
|
||||||
|
if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) == SWIG_OK) {
|
||||||
|
if (val) *val = vptr;
|
||||||
|
return SWIG_OLDOBJ;
|
||||||
|
} else {
|
||||||
|
char* buf = 0 ; size_t size = 0; int alloc = 0;
|
||||||
|
if (SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc) == SWIG_OK) {
|
||||||
|
if (buf) {
|
||||||
|
if (val) *val = new std::string(buf, size - 1);
|
||||||
|
if (alloc == SWIG_NEWOBJ) %delete_array(buf);
|
||||||
|
return SWIG_NEWOBJ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (val) {
|
||||||
|
rb_raise( rb_eTypeError, "a string is expected");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%fragment(SWIG_From_frag(std::basic_string<char>),"header",
|
||||||
|
fragment="SWIG_FromCharPtrAndSize") {
|
||||||
|
SWIGINTERNINLINE VALUE
|
||||||
|
SWIG_From(std::basic_string<char>)(const std::string& s)
|
||||||
|
{
|
||||||
|
return SWIG_FromCharPtrAndSize(s.data(), s.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%include <std/std_basic_string.i>
|
||||||
|
%typemaps_asptrfromn(%checkcode(STRING), std::basic_string<char>);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(SWIG_STD_WSTRING)
|
||||||
|
|
||||||
|
%fragment(SWIG_AsPtr_frag(std::basic_string<wchar_t>),"header",
|
||||||
|
fragment="SWIG_AsWCharPtrAndSize") {
|
||||||
|
SWIGINTERN int
|
||||||
|
SWIG_AsPtr(std::basic_string<wchar_t>)(VALUE obj, std::wstring **val)
|
||||||
|
{
|
||||||
|
static swig_type_info* string_info =
|
||||||
|
SWIG_TypeQuery("std::basic_string<wchar_t> *");
|
||||||
|
std::wstring *vptr;
|
||||||
|
if (SWIG_ConvertPtr(obj, (void**)&vptr, string_info, 0) == SWIG_OK) {
|
||||||
|
if (val) *val = vptr;
|
||||||
|
return SWIG_OLDOBJ;
|
||||||
|
} else {
|
||||||
|
wchar_t *buf = 0 ; size_t size = 0; int alloc = 0;
|
||||||
|
if (SWIG_AsWCharPtrAndSize(obj, &buf, &size, &alloc) == SWIG_OK) {
|
||||||
|
if (buf) {
|
||||||
|
if (val) *val = new std::wstring(buf, size - 1);
|
||||||
|
if (alloc == SWIG_NEWOBJ) %delete_array(buf);
|
||||||
|
return SWIG_NEWOBJ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (val) {
|
||||||
|
rb_raise( rb_eTypeError, "a string is expected");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%fragment(SWIG_From_frag(std::basic_string<wchar_t>),"header",
|
||||||
|
fragment="SWIG_FromWCharPtrAndSize") {
|
||||||
|
SWIGINTERNINLINE VALUE
|
||||||
|
SWIG_From(std::basic_string<wchar_t>)(const std::wstring& s)
|
||||||
|
{
|
||||||
|
return SWIG_FromWCharPtrAndSize(s.data(), s.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%typemaps_asptrfromn(%checkcode(UNISTRING), std::basic_string<wchar_t>);
|
||||||
|
|
||||||
|
#endif
|
||||||
1
Lib/ruby/std_char_traits.i
Normal file
1
Lib/ruby/std_char_traits.i
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
%include <std/std_char_traits.i>
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
|
||||||
|
#pragma SWIG nowarn=801
|
||||||
|
|
||||||
%rename(ios_base_in) std::ios_base::in;
|
%rename(ios_base_in) std::ios_base::in;
|
||||||
|
|
||||||
%include <std/std_ios.i>
|
%include <std/std_ios.i>
|
||||||
|
|
|
||||||
12
Lib/ruby/std_iostream.i
Normal file
12
Lib/ruby/std_iostream.i
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
%callback("%s") endl;
|
||||||
|
%callback("%s") ends;
|
||||||
|
%callback("%s") flush;
|
||||||
|
}
|
||||||
|
|
||||||
|
%warnfilter(365) operator+=;
|
||||||
|
%warnfilter(802) std::basic_iostream; // turn off multiple inheritance warning
|
||||||
|
|
||||||
|
%include <std/std_iostream.i>
|
||||||
|
|
||||||
2
Lib/ruby/std_sstream.i
Normal file
2
Lib/ruby/std_sstream.i
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
%include <std/std_sstream.i>
|
||||||
1
Lib/ruby/std_streambuf.i
Normal file
1
Lib/ruby/std_streambuf.i
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
%include <std/std_streambuf.i>
|
||||||
|
|
@ -1 +1,6 @@
|
||||||
|
|
||||||
|
%warnfilter(801) std::string; // wrong class name
|
||||||
|
%warnfilter(378) std::basic_string::operator!=;
|
||||||
|
|
||||||
%include <typemaps/std_string.swg>
|
%include <typemaps/std_string.swg>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,16 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* flags for the make_autodoc function */
|
||||||
|
enum autodoc_t {
|
||||||
|
AUTODOC_CLASS,
|
||||||
|
AUTODOC_CTOR,
|
||||||
|
AUTODOC_DTOR,
|
||||||
|
AUTODOC_STATICFUNC,
|
||||||
|
AUTODOC_FUNC,
|
||||||
|
AUTODOC_METHOD
|
||||||
|
};
|
||||||
|
|
||||||
static const char *usage = "\
|
static const char *usage = "\
|
||||||
Ruby Options (available with -ruby)\n\
|
Ruby Options (available with -ruby)\n\
|
||||||
-globalmodule - Wrap everything into the global module\n\
|
-globalmodule - Wrap everything into the global module\n\
|
||||||
|
|
@ -166,6 +176,378 @@ private:
|
||||||
STATIC_VAR
|
STATIC_VAR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------
|
||||||
|
* autodoc level declarations
|
||||||
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
enum autodoc_l {
|
||||||
|
NO_AUTODOC = -2, // no autodoc
|
||||||
|
STRING_AUTODOC = -1, // use provided string
|
||||||
|
NAMES_AUTODOC = 0, // only parameter names
|
||||||
|
TYPES_AUTODOC = 1, // parameter names and types
|
||||||
|
EXTEND_AUTODOC = 2, // extended documentation and parameter names
|
||||||
|
EXTEND_TYPES_AUTODOC = 3 // extended documentation and parameter types + names
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
autodoc_l autodoc_level(String *autodoc) {
|
||||||
|
autodoc_l dlevel = NO_AUTODOC;
|
||||||
|
if (autodoc) {
|
||||||
|
char *c = Char(autodoc);
|
||||||
|
if (c && isdigit(c[0])) {
|
||||||
|
dlevel = (autodoc_l) atoi(c);
|
||||||
|
} else {
|
||||||
|
if (strcmp(c, "extended") == 0) {
|
||||||
|
dlevel = EXTEND_AUTODOC;
|
||||||
|
} else {
|
||||||
|
dlevel = STRING_AUTODOC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------
|
||||||
|
* have_docstring()
|
||||||
|
* Check if there is a docstring directive and it has text,
|
||||||
|
* or there is an autodoc flag set
|
||||||
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
bool have_docstring(Node *n) {
|
||||||
|
String *str = Getattr(n, "feature:docstring");
|
||||||
|
return (str != NULL && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------
|
||||||
|
* docstring()
|
||||||
|
* Get the docstring text, stripping off {} if neccessary,
|
||||||
|
* and enclose in triple double quotes. If autodoc is also
|
||||||
|
* set then it will build a combined docstring.
|
||||||
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
String *docstring(Node *n, autodoc_t ad_type) {
|
||||||
|
String *str = Getattr(n, "feature:docstring");
|
||||||
|
bool have_ds = (str != NULL && Len(str) > 0);
|
||||||
|
bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
|
||||||
|
String *autodoc = NULL;
|
||||||
|
String *doc = NULL;
|
||||||
|
|
||||||
|
if (have_ds) {
|
||||||
|
char *t = Char(str);
|
||||||
|
if (*t == '{') {
|
||||||
|
Delitem(str, 0);
|
||||||
|
Delitem(str, DOH_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_auto) {
|
||||||
|
autodoc = make_autodoc(n, ad_type);
|
||||||
|
have_auto = (autodoc != NULL && Len(autodoc) > 0);
|
||||||
|
}
|
||||||
|
// If there is more than one line then make docstrings like this:
|
||||||
|
//
|
||||||
|
// This is line1
|
||||||
|
// And here is line2 followed by the rest of them
|
||||||
|
//
|
||||||
|
// otherwise, put it all on a single line
|
||||||
|
//
|
||||||
|
if (have_auto && have_ds) { // Both autodoc and docstring are present
|
||||||
|
doc = NewString("");
|
||||||
|
Printv(doc, "\n", autodoc, "\n", str, NIL);
|
||||||
|
} else if (!have_auto && have_ds) { // only docstring
|
||||||
|
if (Strchr(str, '\n') == NULL) {
|
||||||
|
doc = NewString(str);
|
||||||
|
} else {
|
||||||
|
doc = NewString("");
|
||||||
|
Printv(doc, str, NIL);
|
||||||
|
}
|
||||||
|
} else if (have_auto && !have_ds) { // only autodoc
|
||||||
|
if (Strchr(autodoc, '\n') == NULL) {
|
||||||
|
doc = NewStringf("%s", autodoc);
|
||||||
|
} else {
|
||||||
|
doc = NewString("");
|
||||||
|
Printv(doc, "\n", autodoc, NIL);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
doc = NewString("");
|
||||||
|
|
||||||
|
// Save the generated strings in the parse tree in case they are used later
|
||||||
|
// by post processing tools
|
||||||
|
Setattr(n, "ruby:docstring", doc);
|
||||||
|
Setattr(n, "ruby:autodoc", autodoc);
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------
|
||||||
|
* make_autodocParmList()
|
||||||
|
* Generate the documentation for the function parameters
|
||||||
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
String *make_autodocParmList(Node *n, bool showTypes) {
|
||||||
|
String *doc = NewString("");
|
||||||
|
String *pdocs = Copy(Getattr(n, "feature:pdocs"));
|
||||||
|
ParmList *plist = CopyParmList(Getattr(n, "parms"));
|
||||||
|
Parm *p;
|
||||||
|
Parm *pnext;
|
||||||
|
Node *lookup;
|
||||||
|
int lines = 0;
|
||||||
|
const int maxwidth = 50;
|
||||||
|
|
||||||
|
if (pdocs)
|
||||||
|
Append(pdocs, "\n");
|
||||||
|
|
||||||
|
|
||||||
|
Swig_typemap_attach_parms("in", plist, 0);
|
||||||
|
Swig_typemap_attach_parms("doc", plist, 0);
|
||||||
|
|
||||||
|
for (p = plist; p; p = pnext) {
|
||||||
|
String *name = 0;
|
||||||
|
String *type = 0;
|
||||||
|
String *value = 0;
|
||||||
|
String *ptype = 0;
|
||||||
|
String *pdoc = Getattr(p, "tmap:doc");
|
||||||
|
if (pdoc) {
|
||||||
|
name = Getattr(p, "tmap:doc:name");
|
||||||
|
type = Getattr(p, "tmap:doc:type");
|
||||||
|
value = Getattr(p, "tmap:doc:value");
|
||||||
|
ptype = Getattr(p, "tmap:doc:pytype");
|
||||||
|
}
|
||||||
|
|
||||||
|
name = name ? name : Getattr(p, "name");
|
||||||
|
type = type ? type : Getattr(p, "type");
|
||||||
|
value = value ? value : Getattr(p, "value");
|
||||||
|
|
||||||
|
String *tm = Getattr(p, "tmap:in");
|
||||||
|
if (tm) {
|
||||||
|
pnext = Getattr(p, "tmap:in:next");
|
||||||
|
} else {
|
||||||
|
pnext = nextSibling(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the 'self' parameter which in ruby is implicit
|
||||||
|
if ( Cmp(name, "self") == 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Len(doc)) {
|
||||||
|
// add a comma to the previous one if any
|
||||||
|
Append(doc, ", ");
|
||||||
|
|
||||||
|
// Do we need to wrap a long line?
|
||||||
|
if ((Len(doc) - lines * maxwidth) > maxwidth) {
|
||||||
|
Printf(doc, "\n%s", tab4);
|
||||||
|
lines += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Do the param type too?
|
||||||
|
if (showTypes) {
|
||||||
|
type = SwigType_base(type);
|
||||||
|
lookup = Swig_symbol_clookup(type, 0);
|
||||||
|
if (lookup)
|
||||||
|
type = Getattr(lookup, "sym:name");
|
||||||
|
Printf(doc, "%s ", type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
Append(doc, name);
|
||||||
|
if (pdoc) {
|
||||||
|
if (!pdocs)
|
||||||
|
pdocs = NewString("Parameters:\n");
|
||||||
|
Printf(pdocs, " %s\n", pdoc);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Append(doc, "?");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
if (Strcmp(value, "NULL") == 0)
|
||||||
|
value = NewString("nil");
|
||||||
|
else if (Strcmp(value, "true") == 0 || Strcmp(value, "TRUE") == 0)
|
||||||
|
value = NewString("true");
|
||||||
|
else if (Strcmp(value, "false") == 0 || Strcmp(value, "FALSE") == 0)
|
||||||
|
value = NewString("false");
|
||||||
|
else {
|
||||||
|
lookup = Swig_symbol_clookup(value, 0);
|
||||||
|
if (lookup)
|
||||||
|
value = Getattr(lookup, "sym:name");
|
||||||
|
}
|
||||||
|
Printf(doc, "=%s", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pdocs)
|
||||||
|
Setattr(n, "feature:pdocs", pdocs);
|
||||||
|
Delete(plist);
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------
|
||||||
|
* make_autodoc()
|
||||||
|
* Build a docstring for the node, using parameter and other
|
||||||
|
* info in the parse tree. If the value of the autodoc
|
||||||
|
* attribute is "0" then do not include parameter types, if
|
||||||
|
* it is "1" (the default) then do. If it has some other
|
||||||
|
* value then assume it is supplied by the extension writer
|
||||||
|
* and use it directly.
|
||||||
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
String *make_autodoc(Node *n, autodoc_t ad_type) {
|
||||||
|
int extended = 0;
|
||||||
|
// If the function is overloaded then this funciton is called
|
||||||
|
// for the last one. Rewind to the first so the docstrings are
|
||||||
|
// in order.
|
||||||
|
while (Getattr(n, "sym:previousSibling"))
|
||||||
|
n = Getattr(n, "sym:previousSibling");
|
||||||
|
|
||||||
|
Node *pn = Swig_methodclass(n);
|
||||||
|
String* class_name = Getattr(pn, "sym:name");
|
||||||
|
String* full_name;
|
||||||
|
if ( module ) {
|
||||||
|
full_name = NewString(module);
|
||||||
|
Append(full_name, "::");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
full_name = NewString("");
|
||||||
|
if ( class_name )
|
||||||
|
Append(full_name, class_name);
|
||||||
|
|
||||||
|
String *doc = NewString("/*\n");
|
||||||
|
int counter = 0;
|
||||||
|
for ( ; n; ++counter ) {
|
||||||
|
bool showTypes = false;
|
||||||
|
bool skipAuto = false;
|
||||||
|
String *autodoc = Getattr(n, "feature:autodoc");
|
||||||
|
autodoc_l dlevel = autodoc_level(autodoc);
|
||||||
|
switch (dlevel) {
|
||||||
|
case NO_AUTODOC:
|
||||||
|
break;
|
||||||
|
case NAMES_AUTODOC:
|
||||||
|
showTypes = false;
|
||||||
|
break;
|
||||||
|
case TYPES_AUTODOC:
|
||||||
|
showTypes = true;
|
||||||
|
break;
|
||||||
|
case EXTEND_AUTODOC:
|
||||||
|
extended = 1;
|
||||||
|
showTypes = false;
|
||||||
|
break;
|
||||||
|
case EXTEND_TYPES_AUTODOC:
|
||||||
|
extended = 1;
|
||||||
|
showTypes = true;
|
||||||
|
break;
|
||||||
|
case STRING_AUTODOC:
|
||||||
|
Append(doc, autodoc);
|
||||||
|
skipAuto = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!skipAuto) {
|
||||||
|
String *symname = Getattr(n, "sym:name");
|
||||||
|
if ( Getattr( special_methods, symname ) )
|
||||||
|
symname = Getattr( special_methods, symname );
|
||||||
|
|
||||||
|
SwigType *type = Getattr(n, "type");
|
||||||
|
|
||||||
|
if (type) {
|
||||||
|
if (Strcmp(type, "void") == 0)
|
||||||
|
type = NULL;
|
||||||
|
else {
|
||||||
|
SwigType *qt = SwigType_typedef_resolve_all(type);
|
||||||
|
if (SwigType_isenum(qt))
|
||||||
|
type = NewString("int");
|
||||||
|
else {
|
||||||
|
type = SwigType_base(type);
|
||||||
|
Node *lookup = Swig_symbol_clookup(type, 0);
|
||||||
|
if (lookup)
|
||||||
|
type = Getattr(lookup, "sym:name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ad_type) {
|
||||||
|
case AUTODOC_CLASS:
|
||||||
|
{
|
||||||
|
// Only do the autodoc if there isn't a docstring for the class
|
||||||
|
String *str = Getattr(n, "feature:docstring");
|
||||||
|
if (counter == 0 && (str == NULL || Len(str) == 0)) {
|
||||||
|
if (CPlusPlus) {
|
||||||
|
Printf(doc, " Document-class: %s\n\n Proxy of C++ %s class",
|
||||||
|
full_name, class_name);
|
||||||
|
} else {
|
||||||
|
Printf(doc, " Document-class: %s\n\n Proxy of C %s struct",
|
||||||
|
full_name, class_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AUTODOC_CTOR:
|
||||||
|
if (counter == 0)
|
||||||
|
Append(doc, " Document-method: new\n\n call-seq:\n");
|
||||||
|
if (Strcmp(class_name, symname) == 0) {
|
||||||
|
String *paramList = make_autodocParmList(n, showTypes);
|
||||||
|
if (Len(paramList))
|
||||||
|
Printf(doc, " %s.new(%s)", class_name, paramList);
|
||||||
|
else
|
||||||
|
Printf(doc, " %s.new", class_name);
|
||||||
|
} else
|
||||||
|
Printf(doc, " %s.new(%s)", class_name,
|
||||||
|
make_autodocParmList(n, showTypes));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUTODOC_DTOR:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUTODOC_STATICFUNC:
|
||||||
|
if (counter == 0)
|
||||||
|
Printf(doc, " Document-method: %s\n\n call-seq:\n", full_name);
|
||||||
|
Printf(doc, " %s(%s)", full_name,
|
||||||
|
make_autodocParmList(n, showTypes));
|
||||||
|
|
||||||
|
if (type)
|
||||||
|
Printf(doc, " -> %s", type);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUTODOC_FUNC:
|
||||||
|
if (counter == 0)
|
||||||
|
Printf(doc, " Document-method: %s\n\n call-seq:\n", symname);
|
||||||
|
Printf(doc, " %s(%s)", symname,
|
||||||
|
make_autodocParmList(n, showTypes));
|
||||||
|
if (type)
|
||||||
|
Printf(doc, " -> %s", type);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUTODOC_METHOD:
|
||||||
|
if (counter == 0)
|
||||||
|
Printf(doc, " Document-method: %s\n\n call-seq:\n", symname);
|
||||||
|
String *paramList = make_autodocParmList(n, showTypes);
|
||||||
|
if (Len(paramList))
|
||||||
|
Printf(doc, " %s(%s)", symname, paramList);
|
||||||
|
else
|
||||||
|
Printf(doc, " %s", symname);
|
||||||
|
if (type)
|
||||||
|
Printf(doc, " -> %s", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (extended) {
|
||||||
|
String *pdocs = Getattr(n, "feature:pdocs");
|
||||||
|
if (pdocs) {
|
||||||
|
Printv(doc, "\n", pdocs, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's overloaded then get the next decl and loop around again
|
||||||
|
n = Getattr(n, "sym:nextSibling");
|
||||||
|
if (n)
|
||||||
|
Append(doc, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Append(doc, "\n\n*/\n");
|
||||||
|
Delete(full_name);
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
/* ---------------------------------------------------------------------
|
||||||
|
|
@ -1064,6 +1446,9 @@ public:
|
||||||
bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
|
bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
|
||||||
int start = (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) ? 1 : 0;
|
int start = (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) ? 1 : 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Now write the wrapper function itself */
|
/* Now write the wrapper function itself */
|
||||||
if (current == CONSTRUCTOR_ALLOCATE) {
|
if (current == CONSTRUCTOR_ALLOCATE) {
|
||||||
Printf(f->def, "#ifdef HAVE_RB_DEFINE_ALLOC_FUNC\n");
|
Printf(f->def, "#ifdef HAVE_RB_DEFINE_ALLOC_FUNC\n");
|
||||||
|
|
@ -1110,7 +1495,7 @@ public:
|
||||||
insertArgOutputCode(l, outarg, need_result);
|
insertArgOutputCode(l, outarg, need_result);
|
||||||
|
|
||||||
/* if the object is a director, and the method call originated from its
|
/* if the object is a director, and the method call originated from its
|
||||||
* underlying python object, resolve the call by going up the c++
|
* underlying Ruby object, resolve the call by going up the c++
|
||||||
* inheritance chain. otherwise try to resolve the method in python.
|
* inheritance chain. otherwise try to resolve the method in python.
|
||||||
* without this check an infinite loop is set up between the director and
|
* without this check an infinite loop is set up between the director and
|
||||||
* shadow class method calls.
|
* shadow class method calls.
|
||||||
|
|
@ -1751,6 +2136,9 @@ public:
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
virtual int classHandler(Node *n) {
|
virtual int classHandler(Node *n) {
|
||||||
|
String* docs = docstring(n, AUTODOC_CLASS);
|
||||||
|
Printf(f_wrappers, "%s", docs);
|
||||||
|
Delete(docs);
|
||||||
|
|
||||||
String *name = Getattr(n, "name");
|
String *name = Getattr(n, "name");
|
||||||
String *symname = Getattr(n, "sym:name");
|
String *symname = Getattr(n, "sym:name");
|
||||||
|
|
@ -1842,6 +2230,11 @@ public:
|
||||||
|
|
||||||
virtual int memberfunctionHandler(Node *n) {
|
virtual int memberfunctionHandler(Node *n) {
|
||||||
current = MEMBER_FUNC;
|
current = MEMBER_FUNC;
|
||||||
|
|
||||||
|
String* docs = docstring(n, AUTODOC_METHOD);
|
||||||
|
Printf(f_wrappers, "%s", docs);
|
||||||
|
Delete(docs);
|
||||||
|
|
||||||
Language::memberfunctionHandler(n);
|
Language::memberfunctionHandler(n);
|
||||||
current = NO_CPP;
|
current = NO_CPP;
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
|
|
@ -1908,7 +2301,13 @@ public:
|
||||||
Delete(self);
|
Delete(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Now do the instance initialize method */
|
/* Now do the instance initialize method */
|
||||||
|
String* docs = docstring(n, AUTODOC_CTOR);
|
||||||
|
Printf(f_wrappers, "%s", docs);
|
||||||
|
Delete(docs);
|
||||||
|
|
||||||
current = CONSTRUCTOR_INITIALIZE;
|
current = CONSTRUCTOR_INITIALIZE;
|
||||||
Swig_name_register((String_or_char *) "construct", (String_or_char *) "new_%c");
|
Swig_name_register((String_or_char *) "construct", (String_or_char *) "new_%c");
|
||||||
Language::constructorHandler(n);
|
Language::constructorHandler(n);
|
||||||
|
|
@ -2005,6 +2404,10 @@ public:
|
||||||
* -------------------------------------------------------------------- */
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
virtual int membervariableHandler(Node *n) {
|
virtual int membervariableHandler(Node *n) {
|
||||||
|
String* docs = docstring(n, AUTODOC_METHOD);
|
||||||
|
Printf(f_wrappers, "%s", docs);
|
||||||
|
Delete(docs);
|
||||||
|
|
||||||
current = MEMBER_VAR;
|
current = MEMBER_VAR;
|
||||||
Language::membervariableHandler(n);
|
Language::membervariableHandler(n);
|
||||||
current = NO_CPP;
|
current = NO_CPP;
|
||||||
|
|
@ -2018,6 +2421,10 @@ public:
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
virtual int staticmemberfunctionHandler(Node *n) {
|
virtual int staticmemberfunctionHandler(Node *n) {
|
||||||
|
String* docs = docstring(n, AUTODOC_STATICFUNC);
|
||||||
|
Printf(f_wrappers, "%s", docs);
|
||||||
|
Delete(docs);
|
||||||
|
|
||||||
current = STATIC_FUNC;
|
current = STATIC_FUNC;
|
||||||
Language::staticmemberfunctionHandler(n);
|
Language::staticmemberfunctionHandler(n);
|
||||||
current = NO_CPP;
|
current = NO_CPP;
|
||||||
|
|
@ -2031,6 +2438,10 @@ public:
|
||||||
* --------------------------------------------------------------------- */
|
* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
virtual int memberconstantHandler(Node *n) {
|
virtual int memberconstantHandler(Node *n) {
|
||||||
|
String* docs = docstring(n, AUTODOC_STATICFUNC);
|
||||||
|
Printf(f_wrappers, "%s", docs);
|
||||||
|
Delete(docs);
|
||||||
|
|
||||||
current = CLASS_CONST;
|
current = CLASS_CONST;
|
||||||
Language::memberconstantHandler(n);
|
Language::memberconstantHandler(n);
|
||||||
current = NO_CPP;
|
current = NO_CPP;
|
||||||
|
|
@ -2042,6 +2453,10 @@ public:
|
||||||
* --------------------------------------------------------------------- */
|
* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
virtual int staticmembervariableHandler(Node *n) {
|
virtual int staticmembervariableHandler(Node *n) {
|
||||||
|
String* docs = docstring(n, AUTODOC_STATICFUNC);
|
||||||
|
Printf(f_wrappers, "%s", docs);
|
||||||
|
Delete(docs);
|
||||||
|
|
||||||
current = STATIC_VAR;
|
current = STATIC_VAR;
|
||||||
Language::staticmembervariableHandler(n);
|
Language::staticmembervariableHandler(n);
|
||||||
current = NO_CPP;
|
current = NO_CPP;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue