From sanders at fs.tum.de  Sun Apr  6 13:53:47 2008
From: sanders at fs.tum.de (Simon Anders)
Date: Sun, 06 Apr 2008 12:53:47 +0100
Subject: [Rd] manual 'Writing R Extensions': bug in example
Message-ID: <47F8B9CB.707@fs.tum.de>

Hi,

I would like to report a small bug in one of the code examples given in 
the 'Writing R extensions' manual. Section 5.9.2 ("Calling .External") 
defines the function "showArgs" in order to demonstrate how to access in 
C the pair-listed arguments passed by .External. The function aims at 
printing echoing all passed arguments to the screen but only prints 
every second argument.

The loop to go through the pair list starts as follows

   args = CDR(args); /* skip 'name' */
   for(i = 0; args != R_NilValue; i++, args = CDR(args)) {
      args = CDR(args);    /* <--- This line is wrong. */

As you can see, "args = CDR(args)" is called twice, resulting in every 
other argument skipped. The marked line should be deleted.

Furthermore, the function requires all arguments to be named, as it 
gives an error if TAG returns NIL in the line

    name = CHAR(PRINTNAME(TAG(args)));

It might improve the example to introduce here a test "if( TAG(args) != 
R_NilValue )".

May I suggest to the maintainer of the manual to change the example to 
the following code? (Changes to original: lines 1, 2, 15, 17, 18 added; 
one line deleted after line 13.)

  1  #include <R.h>
  2  #include <Rinternals.h>
  3  #include <R_ext/PrtUtil.h>
  4
  5  SEXP showArgs(SEXP args)
  6  {
  7    int i, nargs;
  8    Rcomplex cpl;
  9    const char *name;
10    SEXP el;
11
12    args = CDR(args); /* skip 'name' */
13    for(i = 0; args != R_NilValue; i++, args = CDR(args)) {
14
15	if( TAG(args) != R_NilValue )
16	   name = CHAR(PRINTNAME(TAG(args)));
17	else
18	   name = "<unnamed>";
19	switch(TYPEOF(CAR(args))) {
20	case REALSXP:
21	  Rprintf("[%d] '%s' %f\n", i+1, name, REAL(CAR(args))[0]);
22	  break;
23	case LGLSXP:
24	case INTSXP:
25	  Rprintf("[%d] '%s' %d\n", i+1, name, INTEGER(CAR(args))[0]);
26	  break;
27	case CPLXSXP:
28	  cpl = COMPLEX(CAR(args))[0];
29	  Rprintf("[%d] '%s' %f + %fi\n", i+1, name, cpl.r, cpl.i);
30	  break;
31	case STRSXP:
32	  Rprintf("[%d] '%s' %s\n", i+1, name,
33		 CHAR(STRING_ELT(CAR(args), 0)));
34	  break;
35	default:
36	  Rprintf("[%d] '%s' R type\n", i+1, name);
37	}
38    }
39    return(R_NilValue);
40  }
41

Best regards
   Simon Anders


+---
| Dr. Simon Anders, Dipl. Phys.
| European Bioinformatics Institute, Hinxton, Cambridgeshire, UK
| office phone +44-1223-494478, mobile phone +44-7505-841692
| preferred (permanent) e-mail: sanders at fs.tum.de



[Rd] manual 'Writing R Extensions': bug in example
Simon Anders