The R Project SVN R

Rev

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

Rev 28008 Rev 28045
Line 58... Line 58...
58
 
58
 
59
static Rconnection Connections[NCONNECTIONS];
59
static Rconnection Connections[NCONNECTIONS];
60
static SEXP OutTextData;
60
static SEXP OutTextData;
61
 
61
 
62
static int R_SinkNumber;
62
static int R_SinkNumber;
63
static int SinkCons[NSINKS], SinkConsClose[NSINKS];
63
static int SinkCons[NSINKS], SinkConsClose[NSINKS], R_SinkSplit[NSINKS];
64
 
64
 
65
static void
65
static void
66
pushback(Rconnection con, int newLine, char *line);
66
pushback(Rconnection con, int newLine, char *line);
67
 
67
 
68
/* ------------- admin functions (see also at end) ----------------- */
68
/* ------------- admin functions (see also at end) ----------------- */
Line 97... Line 97...
97
	error("invalid connection");
97
	error("invalid connection");
98
    return con;
98
    return con;
99
 
99
 
100
}
100
}
101
 
101
 
-
 
102
int getActiveSink(int n){
-
 
103
  if (n>=R_SinkNumber || n<0) 
-
 
104
    return 0;
-
 
105
  if (R_SinkSplit[R_SinkNumber-n])
-
 
106
    return SinkCons[R_SinkNumber-n-1];
-
 
107
  else
-
 
108
    return 0;
-
 
109
}
-
 
110
 
-
 
111
 
-
 
112
 
102
/* for use in REvprintf */
113
/* for use in REvprintf */
103
Rconnection getConnection_no_err(int n)
114
Rconnection getConnection_no_err(int n)
104
{
115
{
105
    Rconnection con = NULL;
116
    Rconnection con = NULL;
106
 
117
 
Line 2883... Line 2894...
2883
 
2894
 
2884
/* ------------------- sink functions  --------------------- */
2895
/* ------------------- sink functions  --------------------- */
2885
 
2896
 
2886
/* Switch output to connection number icon, or popd stack if icon < 0
2897
/* Switch output to connection number icon, or popd stack if icon < 0
2887
 */
2898
 */
-
 
2899
 
2888
Rboolean switch_stdout(int icon, int closeOnExit)
2900
Rboolean switch_or_tee_stdout(int icon, int closeOnExit, int tee)
2889
{
2901
{
2890
    int toclose;
2902
    int toclose;
2891
 
2903
 
2892
    if(icon == R_OutputCon) return FALSE;
2904
    if(icon == R_OutputCon) return FALSE;
2893
 
2905
 
Line 2896... Line 2908...
2896
 
2908
 
2897
    if(icon == 0)
2909
    if(icon == 0)
2898
	error("cannot switch output to stdin");
2910
	error("cannot switch output to stdin");
2899
    else if(icon == 1 || icon == 2) {
2911
    else if(icon == 1 || icon == 2) {
2900
	R_OutputCon = SinkCons[++R_SinkNumber] = icon;
2912
	R_OutputCon = SinkCons[++R_SinkNumber] = icon;
-
 
2913
	R_SinkSplit[R_SinkNumber] = tee;
2901
	SinkConsClose[R_SinkNumber] = 0;
2914
	SinkConsClose[R_SinkNumber] = 0;
2902
    } else if(icon >= 3) {
2915
    } else if(icon >= 3) {
2903
	Rconnection con = getConnection(icon); /* checks validity */
2916
	Rconnection con = getConnection(icon); /* checks validity */
2904
	toclose = 2*closeOnExit;
2917
	toclose = 2*closeOnExit;
2905
	if(!con->isopen) {
2918
	if(!con->isopen) {
2906
	    if(!con->open(con)) error("cannot open the connection");
2919
	    if(!con->open(con)) error("cannot open the connection");
2907
	    toclose = 1;
2920
	    toclose = 1;
2908
	}
2921
	}
2909
	R_OutputCon = SinkCons[++R_SinkNumber] = icon;
2922
	R_OutputCon = SinkCons[++R_SinkNumber] = icon;
2910
	SinkConsClose[R_SinkNumber] = toclose;
2923
	SinkConsClose[R_SinkNumber] = toclose;
-
 
2924
 	R_SinkSplit[R_SinkNumber] = tee;
2911
    } else { /* removing a sink */
2925
   } else { /* removing a sink */
2912
	if (R_SinkNumber <= 0) {
2926
	if (R_SinkNumber <= 0) {
2913
	    warning("no sink to remove");
2927
	    warning("no sink to remove");
2914
	    return FALSE;
2928
	    return FALSE;
2915
	} else {
2929
	} else {
2916
	    R_OutputCon = SinkCons[--R_SinkNumber];
2930
	    R_OutputCon = SinkCons[--R_SinkNumber];
Line 2924... Line 2938...
2924
	}
2938
	}
2925
    }
2939
    }
2926
    return TRUE;
2940
    return TRUE;
2927
}
2941
}
2928
 
2942
 
-
 
2943
/* This is not only used by cat(), but is in a public
-
 
2944
   header, so we need a wrapper */
-
 
2945
 
-
 
2946
Rboolean switch_stdout(int icon, int closeOnExit){
-
 
2947
  return switch_or_tee_stdout(icon, closeOnExit, 0);
-
 
2948
}
-
 
2949
 
2929
SEXP do_sink(SEXP call, SEXP op, SEXP args, SEXP rho)
2950
SEXP do_sink(SEXP call, SEXP op, SEXP args, SEXP rho)
2930
{
2951
{
2931
    int icon, closeOnExit, errcon;
2952
  int icon, closeOnExit, errcon, tee;
2932
 
2953
 
2933
    checkArity(op, args);
2954
    checkArity(op, args);
2934
    icon = asInteger(CAR(args));
2955
    icon = asInteger(CAR(args));
2935
    closeOnExit = asLogical(CADR(args));
2956
    closeOnExit = asLogical(CADR(args));
2936
    if(closeOnExit == NA_LOGICAL)
2957
    if(closeOnExit == NA_LOGICAL)
2937
	error("invalid value for closeOnExit");
2958
	error("invalid value for closeOnExit");
2938
    errcon = asLogical(CADDR(args));
2959
    errcon = asLogical(CADDR(args));
2939
    if(errcon == NA_LOGICAL) error("invalid value for type");
2960
    if(errcon == NA_LOGICAL) error("invalid value for type");
-
 
2961
    tee = asLogical(CADDDR(args));
-
 
2962
    if(tee == NA_LOGICAL) error("invalid value for split");
2940
 
2963
    
2941
    if(!errcon) {
2964
    if(!errcon) {
2942
	/* allow space for cat() to use sink() */
2965
	/* allow space for cat() to use sink() */
2943
	if(icon >= 0 && R_SinkNumber >= NSINKS - 2)
2966
	if(icon >= 0 && R_SinkNumber >= NSINKS - 2)
2944
	    error("sink stack is full");
2967
	    error("sink stack is full");
2945
	switch_stdout(icon, closeOnExit);
2968
	switch_or_tee_stdout(icon, closeOnExit, tee);
2946
    } else {
2969
    } else {
2947
	if(icon < 0) R_ErrorCon = 2;
2970
	if(icon < 0) R_ErrorCon = 2;
2948
	else {
2971
	else {
2949
	    getConnection(icon); /* check validity */
2972
	    getConnection(icon); /* check validity */
2950
	    R_ErrorCon = icon;
2973
	    R_ErrorCon = icon;