
n <- as.integer(commandArgs(TRUE)[1])

release_code <- '
#include <R.h>
#include <Rdefines.h>
#include <R_ext/Error.h>

SEXP releaser ( SEXP object, SEXP list ) {
    if (!isNull(list)) {
	if (object == CAR(list))
	    return CDR(list);
	else{
		SEXP cdr = releaser(object, CDR(list)) ;
	    SETCDR(list, cdr );
	}
    }
    return list;
}
'

remove_code <- '
#include <R.h>
#include <Rdefines.h>
#include <R_ext/Error.h>

SEXP remover ( SEXP object, SEXP list ) {

if( !isNull( list ) ){
SEXP x = list ;
SEXP y ;
while( CAR(x) != object && CADR(x) != R_NilValue ){
y = x ;
x = CDR(x) ;
}
if( CAR(x) == object ) SETCDR(y, CDR(x) ) ;
}
return list ;
}
'

writeLines( release_code, "release.c" ) 
system( "R CMD SHLIB release.c" )

writeLines( release_code, "remove.c" ) 
system( "R CMD SHLIB remove.c" )

dyn.load( "remove.so" )
dyn.load( "release.so" )

e <- new.env()
longlist <- append( list("foo"), append( replicate( n, list(1) ), e ) )

dyn.load( "releaser.so" )
dyn.load( "remover.so" )

call <- do.call( "call", longlist  )
system.time( res1 <- .Call( "remover", e, call ) )

call <- do.call( "call", longlist  )
system.time( res2 <- .Call( "releaser", e, call ) )
         
stopifnot( identical(res1, res2 ) )
