The R Project SVN R

Rev

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

Rev 63223 Rev 63624
Line 155... Line 155...
155
{
155
{
156
    newargs = newintoold(newargs, oldargs);
156
    newargs = newintoold(newargs, oldargs);
157
    return listAppend(oldargs, newargs);
157
    return listAppend(oldargs, newargs);
158
}
158
}
159
 
159
 
-
 
160
/* R_MethodsNamespace is initialized to R_GlobalEnv when R is
-
 
161
   initialized.  If it set to the methods namespace when the latter is
-
 
162
   loaded, and back to R_GlobalEnv when it is unloaded. */
-
 
163
 
160
#ifdef S3_for_S4_warn /* not currently used */
164
#ifdef S3_for_S4_warn /* not currently used */
161
static SEXP s_check_S3_for_S4 = 0;
165
static SEXP s_check_S3_for_S4 = 0;
162
void R_warn_S3_for_S4(SEXP method) {
166
void R_warn_S3_for_S4(SEXP method) {
163
  SEXP call;
167
  SEXP call;
164
  if(!s_check_S3_for_S4)
168
  if(!s_check_S3_for_S4)
Line 914... Line 918...
914
		     /* what = */ CADR(args),
918
		     /* what = */ CADR(args),
915
		     /* which = */ CADDR(args));
919
		     /* which = */ CADDR(args));
916
}
920
}
917
 
921
 
918
 
922
 
-
 
923
/*
-
 
924
   ==============================================================
-
 
925
 
-
 
926
     code from here on down is support for the methods package
-
 
927
 
-
 
928
   ==============================================================
-
 
929
*/
-
 
930
 
919
/**
931
/**
920
 * Return the 0-based index of an is() match in a vector of class-name
932
 * Return the 0-based index of an is() match in a vector of class-name
921
 * strings terminated by an empty string.  Returns -1 for no match.
933
 * strings terminated by an empty string.  Returns -1 for no match.
922
 *
934
 *
923
 * @param x  an R object, about which we want is(x, .) information.
935
 * @param x  an R object, about which we want is(x, .) information.
Line 990... Line 1002...
990
	meth_classEnv = install(".classEnv");
1002
	meth_classEnv = install(".classEnv");
991
 
1003
 
992
    pkg = getAttrib(cl, R_PackageSymbol); /* ==R== packageSlot(class(x)) */
1004
    pkg = getAttrib(cl, R_PackageSymbol); /* ==R== packageSlot(class(x)) */
993
    if(!isNull(pkg)) { /* find  rho := correct class Environment */
1005
    if(!isNull(pkg)) { /* find  rho := correct class Environment */
994
	SEXP clEnvCall;
1006
	SEXP clEnvCall;
995
	// FIXME: fails if 'methods' is not attached.
1007
	// FIXME: fails if 'methods' is not loaded.
996
	PROTECT(clEnvCall = lang2(meth_classEnv, cl));
1008
	PROTECT(clEnvCall = lang2(meth_classEnv, cl));
997
	rho = eval(clEnvCall, R_GlobalEnv);
1009
	rho = eval(clEnvCall, R_MethodsNamespace);
998
	UNPROTECT(1);
1010
	UNPROTECT(1);
999
	if(!isEnvironment(rho))
1011
	if(!isEnvironment(rho))
1000
	    error(_("could not find correct environment; please report!"));
1012
	    error(_("could not find correct environment; please report!"));
1001
    }
1013
    }
1002
    return R_check_class_and_super(x, valid, rho);
1014
    return R_check_class_and_super(x, valid, rho);
1003
}
1015
}
1004
 
1016
 
1005
/*
-
 
1006
   ==============================================================
-
 
1007
 
-
 
1008
     code from here on down is support for the methods package
-
 
1009
 
-
 
1010
   ==============================================================
-
 
1011
*/
-
 
1012
 
-
 
1013
/* standardGeneric:  uses a pointer to R_standardGeneric, to be
1017
/* standardGeneric:  uses a pointer to R_standardGeneric, to be
1014
   initialized when the methods package is attached.  When and if the
1018
   initialized when the methods namespace is loaded,
1015
   methods code is automatically included, the pointer will not be
-
 
1016
   needed
1019
   via R_initMethodDispatch.
1017
 
-
 
1018
*/
1020
*/
1019
static R_stdGen_ptr_t R_standardGeneric_ptr = 0;
1021
static R_stdGen_ptr_t R_standardGeneric_ptr = 0;
1020
static SEXP dispatchNonGeneric(SEXP name, SEXP env, SEXP fdef);
1022
static SEXP dispatchNonGeneric(SEXP name, SEXP env, SEXP fdef);
1021
#define NOT_METHODS_DISPATCH_PTR(ptr) (ptr == 0 || ptr == dispatchNonGeneric)
1023
#define NOT_METHODS_DISPATCH_PTR(ptr) (ptr == 0 || ptr == dispatchNonGeneric)
1022
 
1024
 
Line 1024... Line 1026...
1024
R_stdGen_ptr_t R_get_standardGeneric_ptr(void)
1026
R_stdGen_ptr_t R_get_standardGeneric_ptr(void)
1025
{
1027
{
1026
    return R_standardGeneric_ptr;
1028
    return R_standardGeneric_ptr;
1027
}
1029
}
1028
 
1030
 
-
 
1031
/* Also called from R_initMethodDispatch in methods C code, which is
-
 
1032
   called when the methods namespace is loaded. */
1029
R_stdGen_ptr_t R_set_standardGeneric_ptr(R_stdGen_ptr_t val, SEXP envir)
1033
R_stdGen_ptr_t R_set_standardGeneric_ptr(R_stdGen_ptr_t val, SEXP envir)
1030
{
1034
{
1031
    R_stdGen_ptr_t old = R_standardGeneric_ptr;
1035
    R_stdGen_ptr_t old = R_standardGeneric_ptr;
1032
    R_standardGeneric_ptr = val;
1036
    R_standardGeneric_ptr = val;
1033
    if(envir && !isNull(envir))
1037
    if(envir && !isNull(envir))
Line 1036... Line 1040...
1036
    if(!R_MethodsNamespace)
1040
    if(!R_MethodsNamespace)
1037
	R_MethodsNamespace = R_GlobalEnv;
1041
	R_MethodsNamespace = R_GlobalEnv;
1038
    return old;
1042
    return old;
1039
}
1043
}
1040
 
1044
 
1041
static SEXP R_isMethodsDispatchOn(SEXP onOff) {
1045
static SEXP R_isMethodsDispatchOn(SEXP onOff)
1042
    SEXP value = allocVector(LGLSXP, 1);
-
 
1043
    Rboolean onOffValue;
-
 
-
 
1046
{
1044
    R_stdGen_ptr_t old = R_get_standardGeneric_ptr();
1047
    R_stdGen_ptr_t old = R_get_standardGeneric_ptr();
1045
    LOGICAL(value)[0] = !NOT_METHODS_DISPATCH_PTR(old);
1048
    int ival =  !NOT_METHODS_DISPATCH_PTR(old);
1046
    if(length(onOff) > 0) {
1049
    if(length(onOff) > 0) {
1047
	onOffValue = asLogical(onOff);
1050
	Rboolean onOffValue = asLogical(onOff);
1048
	if(onOffValue == NA_INTEGER)
1051
	if(onOffValue == NA_INTEGER)
1049
	    error(_("'onOff' must be TRUE or FALSE"));
1052
	    error(_("'onOff' must be TRUE or FALSE"));
1050
	else if(onOffValue == FALSE)
1053
	else if(onOffValue == FALSE)
1051
	    R_set_standardGeneric_ptr(0, 0);
1054
	    R_set_standardGeneric_ptr(NULL, R_GlobalEnv);
-
 
1055
	// TRUE is not currently used
1052
	else if(NOT_METHODS_DISPATCH_PTR(old)) {
1056
	else if(NOT_METHODS_DISPATCH_PTR(old)) {
1053
	    SEXP call;
1057
	    // so not already on
-
 
1058
	    // This may not work correctly: the default arg is incorrect.
-
 
1059
	    warning("R_isMethodsDispatchOn(TRUE) called -- may not work correctly");
-
 
1060
	    // FIXME: use call = PROTECT(lang1(install("initMethodDispatch")));
1054
	    PROTECT(call = allocList(2));
1061
	    SEXP call = PROTECT(allocList(2));
1055
	    SETCAR(call, install("initMethodsDispatch"));
1062
	    SETCAR(call, install("initMethodDispatch"));
1056
	    eval(call, R_GlobalEnv); /* only works with
1063
	    eval(call, R_MethodsNamespace); // only works with methods loaded
1057
					methods	 attached */
-
 
1058
	    UNPROTECT(1);
1064
	    UNPROTECT(1);
1059
	}
1065
	}
1060
    }
1066
    }
1061
    return value;
1067
    return ScalarLogical(ival);
1062
}
1068
}
1063
 
1069
 
1064
/* simpler version for internal use, in attrib.c and print.c */
1070
/* simpler version for internal use, in attrib.c and print.c */
1065
attribute_hidden
1071
attribute_hidden
1066
Rboolean isMethodsDispatchOn(void)
1072
Rboolean isMethodsDispatchOn(void)
1067
{
1073
{
1068
    return !NOT_METHODS_DISPATCH_PTR(R_standardGeneric_ptr);
1074
    return !NOT_METHODS_DISPATCH_PTR(R_standardGeneric_ptr);
1069
}
1075
}
1070
 
1076
 
1071
 
1077
 
-
 
1078
/* primitive for .isMethodsDispatchOn
-
 
1079
   This is generally called without an arg, but is call with
-
 
1080
   onOff=FALSE when package methods is detached/unloaded.
-
 
1081
 
-
 
1082
   It seems it is not currently called with onOff = TRUE (and would
-
 
1083
   not have worked prior to 3.0.2).
-
 
1084
*/ 
1072
attribute_hidden
1085
attribute_hidden
1073
SEXP do_S4on(SEXP call, SEXP op, SEXP args, SEXP env)
1086
SEXP do_S4on(SEXP call, SEXP op, SEXP args, SEXP env)
1074
{
1087
{
1075
    if(length(args) == 0) return ScalarLogical(isMethodsDispatchOn());
1088
    if(length(args) == 0) return ScalarLogical(isMethodsDispatchOn());
1076
    return R_isMethodsDispatchOn(CAR(args));
1089
    return R_isMethodsDispatchOn(CAR(args));
Line 1495... Line 1508...
1495
	error(_("C level MAKE_CLASS macro called with NULL string pointer"));
1508
	error(_("C level MAKE_CLASS macro called with NULL string pointer"));
1496
    if(!s_getClass) s_getClass = install("getClass");
1509
    if(!s_getClass) s_getClass = install("getClass");
1497
    PROTECT(call = allocVector(LANGSXP, 2));
1510
    PROTECT(call = allocVector(LANGSXP, 2));
1498
    SETCAR(call, s_getClass);
1511
    SETCAR(call, s_getClass);
1499
    SETCAR(CDR(call), mkString(what));
1512
    SETCAR(CDR(call), mkString(what));
1500
    e = eval(call, R_GlobalEnv);
1513
    e = eval(call, R_MethodsNamespace);
1501
    UNPROTECT(1);
1514
    UNPROTECT(1);
1502
    return(e);
1515
    return(e);
1503
}
1516
}
1504
 
1517
 
1505
/* this very similar, but gives NULL instead of an error for a non-existing class */
1518
/* this very similar, but gives NULL instead of an error for a non-existing class */
Line 1511... Line 1524...
1511
	error(_("R_getClassDef(.) called with NULL string pointer"));
1524
	error(_("R_getClassDef(.) called with NULL string pointer"));
1512
    if(!s_getClassDef) s_getClassDef = install("getClassDef");
1525
    if(!s_getClassDef) s_getClassDef = install("getClassDef");
1513
    PROTECT(call = allocVector(LANGSXP, 2));
1526
    PROTECT(call = allocVector(LANGSXP, 2));
1514
    SETCAR(call, s_getClassDef);
1527
    SETCAR(call, s_getClassDef);
1515
    SETCAR(CDR(call), mkString(what));
1528
    SETCAR(CDR(call), mkString(what));
1516
    e = eval(call, R_GlobalEnv);
1529
    e = eval(call, R_MethodsNamespace);
1517
    UNPROTECT(1);
1530
    UNPROTECT(1);
1518
    return(e);
1531
    return(e);
1519
}
1532
}
1520
 
1533
 
1521
/* in Rinternals.h */
1534
/* in Rinternals.h */