The R Project SVN R

Rev

Rev 5731 | Rev 6188 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5731 Rev 6113
Line 292... Line 292...
292
 
292
 
293
#define ARGUSED(x) LEVELS(x)
293
#define ARGUSED(x) LEVELS(x)
294
 
294
 
295
SEXP do_nextmethod(SEXP call, SEXP op, SEXP args, SEXP env)
295
SEXP do_nextmethod(SEXP call, SEXP op, SEXP args, SEXP env)
296
{
296
{
297
    char buf[128];
297
    char buf[128], b[512], tbuf[10];
298
    SEXP ans, s, t, class, method, matchedarg, generic, nextfun;
298
    SEXP ans, s, t, class, method, matchedarg, generic, nextfun;
299
    SEXP sysp, m, formals, actuals, tmp, newcall;
299
    SEXP sysp, m, formals, actuals, tmp, newcall;
300
    SEXP a;
300
    SEXP a, group, basename;
301
    RCNTXT *cptr;
301
    RCNTXT *cptr;
302
    int i,j;
302
    int i,j;
303
    SEXP group,realgroup;
-
 
304
    char tbuf[10];
-
 
305
 
303
 
306
    cptr = R_GlobalContext;
304
    cptr = R_GlobalContext;
307
 
305
 
308
    cptr->callflag = CTXT_GENERIC;
306
    cptr->callflag = CTXT_GENERIC;
309
 
307
 
Line 411... Line 409...
411
      .Class is used to determine the next method; if it doesn't
409
      .Class is used to determine the next method; if it doesn't
412
      exist the first argument to the current method is used
410
      exist the first argument to the current method is used
413
      the second argument to NextMethod is another option but
411
      the second argument to NextMethod is another option but
414
      isn't currently used).
412
      isn't currently used).
415
    */
413
    */
416
 
-
 
417
    class = dynamicfindVar(install(".Class"), R_GlobalContext);
414
    class = findVarInFrame( R_GlobalContext->sysparent, install(".Class"));
418
 
415
 
419
    if (class == R_UnboundValue) {
416
    if (class == R_UnboundValue) {
420
	s = GetObject(cptr);
417
	s = GetObject(cptr);
421
	if (!isObject(s))
418
	if (!isObject(s))
422
	    errorcall(call, "object not specified");
419
	    errorcall(call, "object not specified");
423
	class = getAttrib(s, R_ClassSymbol);
420
	class = getAttrib(s, R_ClassSymbol);
424
    }
421
    }
425
 
422
 
-
 
423
    /* the generic comes from either the sysparent or it's named */
426
    generic = eval(CAR(args), env);
424
    generic = findVarInFrame(R_GlobalContext->sysparent, install(".Generic"));
427
    if (generic == R_NilValue) {
425
    if (generic == R_UnboundValue)
428
	generic = dynamicfindVar(install(".Generic"), R_GlobalContext);
426
	generic = eval(CAR(args), env);
429
	if (generic == R_UnboundValue)
427
    if( generic == R_NilValue )
430
	    generic = mkString(CHAR(PRINTNAME(CAR(cptr->call))));
428
	errorcall(call,"generic function not specified");
431
    }
-
 
432
    PROTECT(generic);
429
    PROTECT(generic);
433
 
430
 
434
    if (!isString(generic) || length(generic) > 1)
431
    if (!isString(generic) || length(generic) > 1)
435
	errorcall(call,"invalid generic argument to NextMethod");
432
	errorcall(call,"invalid generic argument to NextMethod");
-
 
433
    
436
    if (strlen(CHAR(STRING(generic)[0])) == 0)
434
    if (strlen(CHAR(STRING(generic)[0])) == 0)
437
	errorcall(call,"generic function not specified");
435
	errorcall(call,"generic function not specified");
438
 
436
 
439
    group = dynamicfindVar(install(".Group"), R_GlobalContext);
437
    /* determine whether we are in a Group dispatch */
-
 
438
 
440
    PROTECT(realgroup = duplicate(group));
439
    group = findVarInFrame(R_GlobalContext->sysparent,install(".Group") );
441
    if (group == R_UnboundValue){
440
    if (group == R_UnboundValue){
442
	group = generic;
-
 
443
	UNPROTECT(1);
-
 
444
	PROTECT(realgroup = mkString(""));
441
	PROTECT(group = mkString(""));
445
    }
442
    }
-
 
443
    else
-
 
444
	PROTECT(group);
-
 
445
 
446
    if (!isString(group) || length(group) > 1)
446
    if (!isString(group) || length(group) > 1)
447
	errorcall(call, "invalid group argument found in NextMethod");
447
	errorcall(call, "invalid group argument found in NextMethod");
-
 
448
 
-
 
449
    /* determine the root: either the group or the generic will be it */
-
 
450
 
448
    if (strlen(CHAR(STRING(group)[0])) == 0)
451
    if( strlen(CHAR(STRING(group)[0])) == 0 )
449
	group = generic;
452
	basename = generic;
-
 
453
    else
-
 
454
	basename = group;
-
 
455
 
-
 
456
    nextfun = R_NilValue;
-
 
457
 
-
 
458
    /* find the method currently being invoked and jump over the current call */
-
 
459
    /* if t is R_UnboundValue then we called the current method directly */
-
 
460
 
-
 
461
    method = findVarInFrame(R_GlobalContext->sysparent,install(".Method") );
-
 
462
    if( method != R_UnboundValue) {
-
 
463
	if( !isString(method) ) 
-
 
464
	    error("Wrong value for .Method");
-
 
465
	for( i=0; i<length(method); i++ ) {
-
 
466
	  sprintf(b,"%s", CHAR(STRING(method)[i]));
-
 
467
	  if( strlen(b) )
-
 
468
	    break;
-
 
469
	}
-
 
470
    }
-
 
471
    else {
-
 
472
      sprintf(b,"%s", CHAR(PRINTNAME(CAR(cptr->call))));	
-
 
473
    }
450
 
474
 
451
    /* we need the value of i on exit from the for loop to figure out
475
    /* we need the value of i on exit from the for loop to figure out
452
       how many classes to drop
476
       how many classes to drop
453
    */
477
    */
454
 
478
 
455
    nextfun = R_NilValue;
-
 
456
    /* jump over the current call */
-
 
457
    t = CAR(cptr->call);
-
 
458
    for (j = 0; j < length(class); j++) {
479
    for (j = 0; j < length(class); j++) {
459
	sprintf(buf,"%s.%s", CHAR(STRING(group)[0]),
-
 
460
		CHAR(STRING(class)[j]));
-
 
461
	if (install(buf) == t)
-
 
462
	    break;
-
 
463
	sprintf(buf,"%s.%s",CHAR(STRING(generic)[0]),
480
      sprintf(buf,"%s.%s", CHAR(STRING(basename)[0]),
464
		CHAR(STRING(class)[j]));
481
	CHAR(STRING(class)[j]));
465
	if (install(buf) == t)
482
      if ( !strcmp(buf,b) ) 
466
	    break;
483
        break;
467
    }
484
    }
468
 
485
 
-
 
486
    if ( !strcmp(buf,b) ) /* we found a match and start from there */
-
 
487
      j++;
-
 
488
    else
-
 
489
      j = 0;  /*no match so start with the first element of .Class */
-
 
490
 
469
    for (i = j + 1; i < length(class); i++) {
491
    for (i = j ; i < length(class); i++) {
470
	sprintf(buf, "%s.%s", CHAR(STRING(generic)[0]),
492
	sprintf(buf, "%s.%s", CHAR(STRING(generic)[0]),
471
		CHAR(STRING(class)[i]));
493
		CHAR(STRING(class)[i]));
472
	nextfun = findVar(install(buf),env);
494
	nextfun = findVar(install(buf),env);
473
	if (isFunction(nextfun))
495
	if (isFunction(nextfun))
474
	    break;
496
	    break;
475
	sprintf(buf,"%s.%s",CHAR(STRING(group)[0]),
-
 
476
		CHAR(STRING(class)[i]));
-
 
477
	nextfun = findVar(install(buf), env);
-
 
478
	if (isFunction(nextfun))
-
 
479
	    break;
-
 
480
    }
497
    }
481
    if (!isFunction(nextfun)) {
498
    if (!isFunction(nextfun)) {
482
	sprintf(buf, "%s.default", CHAR(STRING(generic)[0]));
499
	sprintf(buf, "%s.default", CHAR(STRING(generic)[0]));
483
	nextfun = findVar(install(buf), env);
500
	nextfun = findVar(install(buf), env);
484
	if (!isFunction(nextfun)) {
501
	if (!isFunction(nextfun)) {
Line 505... Line 522...
505
    defineVar(install(".Method"), method, m);
522
    defineVar(install(".Method"), method, m);
506
    method = install(buf);
523
    method = install(buf);
507
 
524
 
508
    defineVar(install(".Generic"), generic, m);
525
    defineVar(install(".Generic"), generic, m);
509
 
526
 
510
    defineVar(install(".Group"), realgroup, m);
527
    defineVar(install(".Group"), group, m);
511
 
528
 
512
    CAR(newcall) = method;
529
    CAR(newcall) = method;
513
    ans = applyMethod(newcall, nextfun, matchedarg, env, m);
530
    ans = applyMethod(newcall, nextfun, matchedarg, env, m);
514
    UNPROTECT(9);
-
 
515
    UNPROTECT(1);
531
    UNPROTECT(10);
516
    return(ans);
532
    return(ans);
517
}
533
}
518
 
534
 
519
SEXP do_unclass(SEXP call, SEXP op, SEXP args, SEXP env)
535
SEXP do_unclass(SEXP call, SEXP op, SEXP args, SEXP env)
520
{
536
{