184
/* ------------------------------------------------------------
185
* autodoc level declarations
186
* ------------------------------------------------------------ */
189
NO_AUTODOC = -2, // no autodoc
190
STRING_AUTODOC = -1, // use provided string
191
NAMES_AUTODOC = 0, // only parameter names
192
TYPES_AUTODOC = 1, // parameter names and types
193
EXTEND_AUTODOC = 2, // extended documentation and parameter names
194
EXTEND_TYPES_AUTODOC = 3 // extended documentation and parameter types + names
198
String* last_autodoc;
202
autodoc_l autodoc_level(String *autodoc) {
203
autodoc_l dlevel = NO_AUTODOC;
205
char *c = Char(autodoc);
206
if (c && isdigit(c[0])) {
207
dlevel = (autodoc_l) atoi(c);
209
if (strcmp(c, "extended") == 0) {
210
dlevel = EXTEND_AUTODOC;
212
dlevel = STRING_AUTODOC;
221
/* ------------------------------------------------------------
223
* Check if there is a docstring directive and it has text,
224
* or there is an autodoc flag set
225
* ------------------------------------------------------------ */
227
bool have_docstring(Node *n) {
228
String *str = Getattr(n, "feature:docstring");
229
return (str != NULL && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
232
/* ------------------------------------------------------------
234
* Get the docstring text, stripping off {} if neccessary,
235
* and enclose in triple double quotes. If autodoc is also
236
* set then it will build a combined docstring.
237
* ------------------------------------------------------------ */
239
String *docstring(Node *n, autodoc_t ad_type) {
241
String *str = Getattr(n, "feature:docstring");
242
bool have_ds = (str != NULL && Len(str) > 0);
243
bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
244
String *autodoc = NULL;
251
Delitem(str, DOH_END);
256
autodoc = make_autodoc(n, ad_type);
257
have_auto = (autodoc != NULL && Len(autodoc) > 0);
259
// If there is more than one line then make docstrings like this:
262
// And here is line2 followed by the rest of them
264
// otherwise, put it all on a single line
266
if (have_auto && have_ds) { // Both autodoc and docstring are present
268
Printv(doc, "\n", autodoc, "\n", str, NIL);
269
} else if (!have_auto && have_ds) { // only docstring
270
if (Strchr(str, '\n') == NULL) {
271
doc = NewString(str);
274
Printv(doc, str, NIL);
276
} else if (have_auto && !have_ds) { // only autodoc
277
if (Strchr(autodoc, '\n') == NULL) {
278
doc = NewStringf("%s", autodoc);
281
Printv(doc, "\n", autodoc, NIL);
286
// Save the generated strings in the parse tree in case they are used later
287
// by post processing tools
288
Setattr(n, "ruby:docstring", doc);
289
Setattr(n, "ruby:autodoc", autodoc);
293
/* ------------------------------------------------------------
294
* make_autodocParmList()
295
* Generate the documentation for the function parameters
296
* ------------------------------------------------------------ */
298
String *make_autodocParmList(Node *n, bool showTypes) {
299
String *doc = NewString("");
300
String *pdocs = Copy(Getattr(n, "feature:pdocs"));
301
ParmList *plist = CopyParmList(Getattr(n, "parms"));
306
const int maxwidth = 50;
309
Append(pdocs, ".\n");
312
Swig_typemap_attach_parms("in", plist, 0);
313
Swig_typemap_attach_parms("doc", plist, 0);
315
for (p = plist; p; p = pnext) {
320
String *pdoc = Getattr(p, "tmap:doc");
322
name = Getattr(p, "tmap:doc:name");
323
type = Getattr(p, "tmap:doc:type");
324
value = Getattr(p, "tmap:doc:value");
325
ptype = Getattr(p, "tmap:doc:pytype");
328
name = name ? name : Getattr(p, "name");
329
type = type ? type : Getattr(p, "type");
330
value = value ? value : Getattr(p, "value");
333
String *tm = Getattr(p, "tmap:in");
335
pnext = Getattr(p, "tmap:in:next");
337
pnext = nextSibling(p);
340
// Skip ignored input attributes
341
if (checkAttribute(p, "tmap:in:numinputs", "0"))
344
// Skip the 'self' parameter which in ruby is implicit
345
if ( Cmp(name, "self") == 0 )
348
// Make __p parameters just p (as used in STL)
349
Replace( name, "__", "", DOH_REPLACE_FIRST );
352
// add a comma to the previous one if any
355
// Do we need to wrap a long line?
356
if ((Len(doc) - lines * maxwidth) > maxwidth) {
357
Printf(doc, "\n%s", tab4);
361
// Do the param type too?
363
type = SwigType_base(type);
364
lookup = Swig_symbol_clookup(type, 0);
366
type = Getattr(lookup, "sym:name");
367
Printf(doc, "%s ", type);
374
pdocs = NewString("Parameters:\n");
375
Printf(pdocs, " %s.\n", pdoc);
382
if (Strcmp(value, "NULL") == 0)
383
value = NewString("nil");
384
else if (Strcmp(value, "true") == 0 || Strcmp(value, "TRUE") == 0)
385
value = NewString("true");
386
else if (Strcmp(value, "false") == 0 || Strcmp(value, "FALSE") == 0)
387
value = NewString("false");
389
lookup = Swig_symbol_clookup(value, 0);
391
value = Getattr(lookup, "sym:name");
393
Printf(doc, "=%s", value);
397
Setattr(n, "feature:pdocs", pdocs);
402
/* ------------------------------------------------------------
404
* Build a docstring for the node, using parameter and other
405
* info in the parse tree. If the value of the autodoc
406
* attribute is "0" then do not include parameter types, if
407
* it is "1" (the default) then do. If it has some other
408
* value then assume it is supplied by the extension writer
409
* and use it directly.
410
* ------------------------------------------------------------ */
412
String *make_autodoc(Node *n, autodoc_t ad_type) {
414
// If the function is overloaded then this funciton is called
415
// for the last one. Rewind to the first so the docstrings are
417
while (Getattr(n, "sym:previousSibling"))
418
n = Getattr(n, "sym:previousSibling");
420
Node *pn = Swig_methodclass(n);
421
String* super_names = NewString("");
422
String* class_name = Getattr(pn, "sym:name") ;
424
if ( !class_name ) class_name = NewString("");
427
class_name = Copy(class_name);
428
List *baselist = Getattr(pn, "bases");
429
if (baselist && Len(baselist)) {
430
Iterator base = First(baselist);
431
while (base.item && GetFlag(base.item, "feature:ignore")) {
436
for ( ;base.item; ++count) {
437
if ( count ) Append(super_names, ", ");
438
String *basename = Getattr(base.item, "sym:name");
440
String* basenamestr = NewString(basename);
441
Node* parent = parentNode(base.item);
444
String *parent_name = Copy( Getattr(parent, "sym:name") );
445
if ( !parent_name ) {
446
Node* mod = Getattr(parent, "module");
448
parent_name = Copy( Getattr(mod, "name") );
451
(Char(parent_name))[0] = toupper((Char(parent_name))[0]);
456
Insert(basenamestr, 0, "::");
457
Insert(basenamestr, 0, parent_name);
460
parent = parentNode(parent);
463
Append(super_names, basenamestr );
471
full_name = NewString(module);
472
if (class_name && Len(class_name) > 0) Append(full_name, "::");
475
full_name = NewString("");
476
Append(full_name, class_name);
478
String* symname = Getattr(n, "sym:name");
479
if ( Getattr( special_methods, symname ) )
480
symname = Getattr( special_methods, symname );
482
String* methodName = NewString(full_name);
483
Append(methodName, symname);
486
// Each overloaded function will try to get documented,
487
// so we keep the name of the last overloaded function and its type.
488
// Documenting just from functionWrapper() is not possible as
489
// sym:name has already been changed to include the class name
490
if ( last_mode == ad_type && Cmp(methodName, last_autodoc) == 0 ) {
495
return NewString("");
500
last_autodoc = Copy(methodName);
502
String *doc = NewString("/*\n");
504
bool skipAuto = false;
506
for ( ; n; ++counter ) {
508
bool showTypes = false;
509
String *autodoc = Getattr(n, "feature:autodoc");
510
autodoc_l dlevel = autodoc_level(autodoc);
524
case EXTEND_TYPES_AUTODOC:
533
SwigType *type = Getattr(n, "type");
536
if (Strcmp(type, "void") == 0)
539
SwigType *qt = SwigType_typedef_resolve_all(type);
540
if (SwigType_isenum(qt))
541
type = NewString("int");
543
type = SwigType_base(type);
544
Node *lookup = Swig_symbol_clookup(type, 0);
546
type = Getattr(lookup, "sym:name");
554
Printf(doc, " Document-class: %s", full_name);
555
if ( Len(super_names) > 0 )
556
Printf( doc, " < %s", super_names);
560
Printf(doc, " Document-method: %s.new\n\n", full_name);
566
case AUTODOC_STATICFUNC:
567
Printf(doc, " Document-method: %s.%s\n\n", full_name, symname);
573
Printf(doc, " Document-method: %s.%s\n\n", full_name, symname);
576
Printf(doc, " Document-method: %s.%s=\n\n", full_name, symname);
583
if ( counter == 0 ) Printf(doc, " call-seq:\n");
586
case AUTODOC_STATICFUNC:
591
String *paramList = make_autodocParmList(n, showTypes);
593
Printf(doc, " %s(%s)", symname, paramList);
595
Printf(doc, " %s", symname);
597
Printf(doc, " -> %s", type);
602
Printf(doc, " %s=(x)", symname);
603
if (type) Printf(doc, " -> %s", type);
614
// Only do the autodoc if there isn't a docstring for the class
615
String *str = Getattr(n, "feature:docstring");
616
if (counter == 0 && (str == NULL || Len(str) == 0)) {
618
Printf(doc, " Proxy of C++ %s class", full_name);
620
Printf(doc, " Proxy of C %s struct", full_name);
626
if (counter == 0) Printf(doc, " call-seq:\n");
627
if (Strcmp(class_name, symname) == 0) {
628
String *paramList = make_autodocParmList(n, showTypes);
630
Printf(doc, " %s.new(%s)", class_name, paramList);
632
Printf(doc, " %s.new", class_name);
634
Printf(doc, " %s.new(%s)", class_name,
635
make_autodocParmList(n, showTypes));
641
case AUTODOC_STATICFUNC:
646
if (counter == 0) Printf(doc, " call-seq:\n");
647
String *paramList = make_autodocParmList(n, showTypes);
649
Printf(doc, " %s(%s)", symname, paramList);
651
Printf(doc, " %s", symname);
653
Printf(doc, " -> %s", type);
658
Printf(doc, " call-seq:\n");
659
Printf(doc, " %s=(x)", symname);
660
if (type) Printf(doc, " -> %s", type);
666
// if it's overloaded then get the next decl and loop around again
667
n = Getattr(n, "sym:nextSibling");
679
Printf(doc, "Class constructor.\n");
681
case AUTODOC_STATICFUNC:
682
Printf(doc, "A class method.\n");
685
Printf(doc, "A module function.\n");
688
Printf(doc, "An instance method.\n");
691
Printf(doc, "Get value of attribute.\n");
694
Printf(doc, "Set new value for attribute.\n");
702
String *autodoc = Getattr(n, "feature:autodoc");
703
autodoc_l dlevel = autodoc_level(autodoc);
705
symname = Getattr(n, "sym:name");
706
if ( Getattr( special_methods, symname ) )
707
symname = Getattr( special_methods, symname );
717
Replaceall( autodoc, "$class", class_name );
718
Printv(doc, autodoc, ".", NIL);
721
case EXTEND_TYPES_AUTODOC:
728
String *pdocs = Getattr(n, "feature:pdocs");
730
Printv(doc, "\n\n", pdocs, NULL);
733
if ( extended == 2 ) break;
735
n = Getattr(n, "sym:nextSibling");
738
Append(doc, "\n*/\n");
171
749
/* ---------------------------------------------------------------------
1369
1994
Wrapper_add_local(f, "ii", "int ii");
1371
1996
if (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) {
1372
1998
Printf(f->code, "argc = nargs + 1;\n");
1373
1999
Printf(f->code, "argv[0] = self;\n");
1374
Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs + 1);
1375
Printf(f->code, "for (ii = 1; (ii < argc); ii++) {\n");
2000
Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs);
2001
Printf(f->code, "for (ii = 1; (ii < argc); ++ii) {\n");
1376
2002
Printf(f->code, "argv[ii] = args[ii-1];\n");
1377
2003
Printf(f->code, "}\n");
1379
2005
Printf(f->code, "argc = nargs;\n");
1380
2006
Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs);
1381
Printf(f->code, "for (ii = 0; (ii < argc); ii++) {\n");
2007
Printf(f->code, "for (ii = 0; (ii < argc); ++ii) {\n");
1382
2008
Printf(f->code, "argv[ii] = args[ii];\n");
1383
2009
Printf(f->code, "}\n");
1386
2012
Replaceall(dispatch, "$args", "nargs, args, self");
1387
2013
Printv(f->code, dispatch, "\n", NIL);
1388
Printf(f->code, "fail:\n");
1389
Printf(f->code, "rb_raise(rb_eArgError, \"No matching function for overloaded '%s'\");\n", symname);
1390
Printf(f->code, "return Qnil;\n");
2017
// Generate prototype list, go to first node
2020
String* type = SwigType_str(Getattr(sibl,"type"),NULL);
2022
while (Getattr(sibl, "sym:previousSibling"))
2023
sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up
2025
// Constructors will be treated specially
2026
const bool isCtor = Cmp(Getattr(sibl,"feature:new"), "1") == 0;
2027
const bool isMethod = ( Cmp(Getattr(sibl, "ismember"), "1") == 0 &&
2030
// Construct real method name
2031
String* methodName = NewString("");
2033
Printv( methodName, Getattr(parentNode(sibl),"sym:name"), ".", NIL );
2034
Append( methodName, Getattr(sibl,"sym:name" ) );
2035
if ( isCtor ) Append( methodName, ".new" );
2037
// Generate prototype list
2038
String *protoTypes = NewString("");
2040
Append( protoTypes, "\n\" ");
2041
if ( !isCtor ) Printv( protoTypes, type, " ", NIL );
2042
Printv(protoTypes, methodName, NIL );
2043
Parm* p = Getattr(sibl, "wrap:parms");
2044
if (p && (current == MEMBER_FUNC || current == MEMBER_VAR ||
2046
p = nextSibling(p); // skip self
2047
Append( protoTypes, "(" );
2050
Append( protoTypes, SwigType_str(Getattr(p,"type"), Getattr(p,"name")) );
2051
if ( ( p = nextSibling(p)) ) Append(protoTypes, ", ");
2053
Append( protoTypes, ")\\n\"" );
2054
} while ((sibl = Getattr(sibl, "sym:nextSibling")));
2056
Append(f->code, "fail:\n");
2057
Printf(f->code, "Ruby_Format_OverloadedError( argc, %d, \"%s\", %s);\n",
2058
maxargs, methodName, protoTypes);
2059
Append(f->code, "\nreturn Qnil;\n");
1391
2065
Printv(f->code, "}\n", NIL);
1392
2066
Wrapper_print(f, f_wrappers);
1393
2067
create_command(n, Char(symname));