The R Project SVN R

Rev

Rev 73750 | Rev 84211 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 r 1
/*
465 maechler 2
 *  R : A Computer Language for Statistical Data Analysis
8552 maechler 3
 *  Copyright (C) 1995, 1996	Robert Gentleman and Ross Ihaka
74734 kalibera 4
 *  Copyright (C) 2000--2018	The R Core Team
58298 maechler 5
 *  Copyright (C) 2001--2012	The R Foundation
2 r 6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  (at your option) any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
42307 ripley 18
 *  along with this program; if not, a copy is available at
68947 ripley 19
 *  https://www.R-project.org/Licenses/
1895 ihaka 20
 *
21
 *
22
 *  EXPORTS	printMatrix()
4717 maechler 23
 *		printArray()
1754 pd 24
 *
1895 ihaka 25
 *  See ./printutils.c	 for general remarks on Printing
4717 maechler 26
 *			 and the Encode.. utils.
1895 ihaka 27
 *
28
 *  See ./format.c	 for the  format_FOO_  functions used below.
2 r 29
 */
1895 ihaka 30
 
5187 hornik 31
#ifdef HAVE_CONFIG_H
7701 hornik 32
#include <config.h>
5187 hornik 33
#endif
34
 
2 r 35
#include "Defn.h"
36
#include "Print.h"
37
 
39079 ripley 38
#include <stdlib.h> /* for div() */
39
 
69366 ripley 40
/* We need display width of a string.
41
   Used only for row/column names found by GetMatrixDimnames,
42
   so in native encoding.  (NULL ones from do_prmatrix are skipped.)
43
*/
44027 ripley 44
int Rstrwid(const char *str, int slen, int enc, int quote);  /* from printutils.c */
59177 ripley 45
#define strwidth(x) Rstrwid(x, (int) strlen(x), CE_NATIVE, 0)
34073 ripley 46
 
38980 maechler 47
/* ceil_DIV(a,b) :=  ceil(a / b)  in _int_ arithmetic : */
48
static R_INLINE
49
int ceil_DIV(int a, int b)
50
{
51
    div_t div_res = div(a, b);
52
    return div_res.quot + ((div_res.rem != 0) ? 1 : 0);
53
}
54
 
42077 ripley 55
/* moved from printutils.c */
38980 maechler 56
 
42077 ripley 57
static void MatrixColumnLabel(SEXP cl, int j, int w)
58
{
59
    if (!isNull(cl)) {
66734 maechler 60
	SEXP tmp = STRING_ELT(cl, j);
61
	int l = (tmp == NA_STRING) ? R_print.na_width_noquote : Rstrlen(tmp, 0);
42077 ripley 62
	Rprintf("%*s%s", w-l, "",
63
		EncodeString(tmp, l, 0, Rprt_adj_left));
64
    }
65
    else {
66
	Rprintf("%*s[,%ld]", w-IndexWidth(j+1)-3, "", j+1);
67
    }
68
}
69
 
70
static void RightMatrixColumnLabel(SEXP cl, int j, int w)
71
{
72
    if (!isNull(cl)) {
66734 maechler 73
	SEXP tmp = STRING_ELT(cl, j);
74
	int l = (tmp == NA_STRING) ? R_print.na_width_noquote : Rstrlen(tmp, 0);
42077 ripley 75
	/* This does not work correctly at least on FC3
76
	Rprintf("%*s", R_print.gap+w,
77
		EncodeString(tmp, l, 0, Rprt_adj_right)); */
78
	Rprintf("%*s%s", R_print.gap+w-l, "",
45446 ripley 79
		EncodeString(tmp, l, 0, Rprt_adj_right));
42077 ripley 80
    }
81
    else {
82
	Rprintf("%*s[,%ld]%*s", R_print.gap, "", j+1, w-IndexWidth(j+1)-3, "");
83
    }
84
}
85
 
86
static void LeftMatrixColumnLabel(SEXP cl, int j, int w)
87
{
88
    if (!isNull(cl)) {
66734 maechler 89
	SEXP tmp = STRING_ELT(cl, j);
90
	int l = (tmp == NA_STRING) ? R_print.na_width_noquote : Rstrlen(tmp, 0);
42077 ripley 91
	Rprintf("%*s%s%*s", R_print.gap, "",
92
		EncodeString(tmp, l, 0, Rprt_adj_left), w-l, "");
93
    }
94
    else {
95
	Rprintf("%*s[,%ld]%*s", R_print.gap, "", j+1, w-IndexWidth(j+1)-3, "");
96
    }
97
}
98
 
99
static void MatrixRowLabel(SEXP rl, int i, int rlabw, int lbloff)
100
{
101
    if (!isNull(rl)) {
66734 maechler 102
	SEXP tmp = STRING_ELT(rl, i);
103
	int l = (tmp == NA_STRING) ? R_print.na_width_noquote : Rstrlen(tmp, 0);
42077 ripley 104
	Rprintf("\n%*s%s%*s", lbloff, "",
105
		EncodeString(tmp, l, 0, Rprt_adj_left),
106
		rlabw-l-lbloff, "");
107
    }
108
    else {
109
	Rprintf("\n%*s[%ld,]", rlabw-3-IndexWidth(i + 1), "", i+1);
110
    }
111
}
112
 
113
 
114
 
38954 maechler 115
/* This is the first (of 6)  print<TYPE>Matrix()  functions.
116
 * We define macros that will be re-used in the other functions,
117
 * and comment the common code here (only):
118
*/
38961 maechler 119
static void printLogicalMatrix(SEXP sx, int offset, int r_pr, int r, int c,
66734 maechler 120
			       SEXP rl, SEXP cl, const char *rn, const char *cn,
121
			       Rboolean print_ij)
2 r 122
{
38954 maechler 123
/* initialization; particularly of row labels, rl= dimnames(.)[[1]] and
124
 * rn = names(dimnames(.))[1] : */
125
#define _PRINT_INIT_rl_rn				\
58298 maechler 126
    int *w = (int *) R_alloc(c, sizeof(int));		\
38954 maechler 127
    int width, rlabw = -1, clabw = -1; /* -Wall */	\
128
    int i, j, jmin = 0, jmax = 0, lbloff = 0;		\
129
							\
130
    if (!isNull(rl))					\
73750 luke 131
	formatString(STRING_PTR_RO(rl), r, &rlabw, 0);	\
38954 maechler 132
    else						\
133
	rlabw = IndexWidth(r + 1) + 3;			\
134
							\
135
    if (rn) {						\
136
	int rnw = strwidth(rn);				\
137
	if ( rnw < rlabw + R_MIN_LBLOFF )		\
138
	    lbloff = R_MIN_LBLOFF;			\
139
	else						\
140
	    lbloff = rnw - rlabw;			\
141
							\
142
	rlabw += lbloff;				\
143
    }
4731 pd 144
 
66734 maechler 145
#   define _COMPUTE_W2_(_FORMAT_j_, _LAST_j_)				\
146
    /* compute w[j] = column-width of j(+1)-th column : */		\
147
    for (j = 0; j < c; j++) {						\
148
	if(print_ij) { _FORMAT_j_; } else w[j] = 0;			\
149
									\
150
	if (!isNull(cl)) {						\
151
	    const void *vmax = vmaxget();				\
152
	    if(STRING_ELT(cl, j) == NA_STRING)				\
153
		clabw = R_print.na_width_noquote;			\
40705 ripley 154
	    else clabw = strwidth(translateChar(STRING_ELT(cl, j)));	\
66734 maechler 155
	    vmaxset(vmax);						\
156
	} else								\
157
	    clabw = IndexWidth(j + 1) + 3;				\
158
									\
159
	if (w[j] < clabw)						\
160
	    w[j] = clabw;						\
161
	_LAST_j_;							\
162
    }
38954 maechler 163
 
66734 maechler 164
#   define _COMPUTE_W_(F_j) _COMPUTE_W2_(F_j, w[j] += R_print.gap)
165
    //                               _LAST_j  ------------------- for all but String
38954 maechler 166
 
66734 maechler 167
#   define _PRINT_ROW_LAB			\
168
						\
169
    if (cn != NULL)				\
170
	Rprintf("%*s%s\n", rlabw, "", cn);	\
171
    if (rn != NULL)				\
172
	Rprintf("%*s", -rlabw, rn);		\
173
    else					\
174
	Rprintf("%*s", rlabw, "")
38954 maechler 175
 
66734 maechler 176
#   define _PRINT_MATRIX_(_W_EXTRA_, DO_COLUMN_LABELS, ENCODE_I_J)	\
177
									\
178
    if (c == 0) {							\
179
	_PRINT_ROW_LAB;							\
180
	for (i = 0; i < r; i++)						\
181
	    MatrixRowLabel(rl, i, rlabw, lbloff);			\
182
	Rprintf("\n");							\
183
    }									\
184
    else while (jmin < c) {						\
185
	/* print columns  jmin:(jmax-1)	 where jmax has to be determined first */ \
186
									\
187
	width = rlabw;							\
188
	/* initially, jmax = jmin */					\
189
	do {								\
190
	    width += w[jmax] _W_EXTRA_;					\
191
	    jmax++;							\
192
	}								\
193
	while (jmax < c && width + w[jmax] _W_EXTRA_ < R_print.width);	\
194
									\
195
	_PRINT_ROW_LAB;							\
196
									\
197
	DO_COLUMN_LABELS;						\
198
									\
199
	for (i = 0; i < r_pr; i++) {					\
200
	    MatrixRowLabel(rl, i, rlabw, lbloff); /* starting with an "\n" */ \
201
	    if(print_ij) for (j = jmin; j < jmax; j++) {		\
202
		ENCODE_I_J;						\
203
	    }								\
204
	}								\
205
	Rprintf("\n");							\
206
	jmin = jmax;							\
20812 ripley 207
    }
38954 maechler 208
 
66734 maechler 209
#   define STD_ColumnLabels			\
210
	for (j = jmin; j < jmax ; j++)		\
211
	    MatrixColumnLabel(cl, j, w[j])
38954 maechler 212
 
66734 maechler 213
    _PRINT_INIT_rl_rn;
73728 luke 214
    const int *x = LOGICAL_RO(sx) + offset;
4731 pd 215
 
74734 kalibera 216
    _COMPUTE_W_( formatLogical(&x[j * (R_xlen_t) r], (R_xlen_t) r, &w[j]) );
38961 maechler 217
 
66734 maechler 218
    _PRINT_MATRIX_( , STD_ColumnLabels,
74734 kalibera 219
		   Rprintf("%s", EncodeLogical(x[i + j * (R_xlen_t) r], w[j])));
4731 pd 220
 
2 r 221
}
222
 
38961 maechler 223
static void printIntegerMatrix(SEXP sx, int offset, int r_pr, int r, int c,
66734 maechler 224
			       SEXP rl, SEXP cl, const char *rn, const char *cn,
225
			       Rboolean print_ij)
2 r 226
{
38954 maechler 227
    _PRINT_INIT_rl_rn;
73728 luke 228
    const int *x = INTEGER_RO(sx) + offset;
4717 maechler 229
 
74734 kalibera 230
    _COMPUTE_W_( formatInteger(&x[j * (R_xlen_t) r], (R_xlen_t) r, &w[j]) );
4710 pd 231
 
66734 maechler 232
    _PRINT_MATRIX_( , STD_ColumnLabels,
74734 kalibera 233
		   Rprintf("%s", EncodeInteger(x[i + j * (R_xlen_t) r], w[j])));
2 r 234
}
235
 
38961 maechler 236
static void printRealMatrix(SEXP sx, int offset, int r_pr, int r, int c,
66734 maechler 237
			    SEXP rl, SEXP cl, const char *rn, const char *cn,
238
			    Rboolean print_ij)
2 r 239
{
38954 maechler 240
    _PRINT_INIT_rl_rn;
73728 luke 241
    const double *x = REAL_RO(sx) + offset;
58298 maechler 242
    int *d = (int *) R_alloc(c, sizeof(int)),
243
	*e = (int *) R_alloc(c, sizeof(int));
2 r 244
 
74734 kalibera 245
    _COMPUTE_W_( formatReal(&x[j * (R_xlen_t) r], (R_xlen_t) r, &w[j],
246
                            &d[j], &e[j], 0) );
4731 pd 247
 
66734 maechler 248
    _PRINT_MATRIX_( , STD_ColumnLabels,
74734 kalibera 249
		   Rprintf("%s", EncodeReal0(x[i + j * (R_xlen_t) r],
250
                                             w[j], d[j], e[j], OutDec)) );
2 r 251
}
252
 
38961 maechler 253
static void printComplexMatrix(SEXP sx, int offset, int r_pr, int r, int c,
66734 maechler 254
			       SEXP rl, SEXP cl, const char *rn, const char *cn,
255
			       Rboolean print_ij)
2 r 256
{
38954 maechler 257
    _PRINT_INIT_rl_rn;
73728 luke 258
    const Rcomplex *x = COMPLEX_RO(sx) + offset;
58298 maechler 259
    int *dr = (int *) R_alloc(c, sizeof(int)),
260
	*er = (int *) R_alloc(c, sizeof(int)),
261
	*wr = (int *) R_alloc(c, sizeof(int)),
262
	*di = (int *) R_alloc(c, sizeof(int)),
263
	*ei = (int *) R_alloc(c, sizeof(int)),
264
	*wi = (int *) R_alloc(c, sizeof(int));
2 r 265
 
580 ihaka 266
    /* Determine the column widths */
74734 kalibera 267
    _COMPUTE_W_( formatComplex(&x[j * (R_xlen_t) r], (R_xlen_t) r,
66734 maechler 268
			       &wr[j], &dr[j], &er[j],
269
			       &wi[j], &di[j], &ei[j], 0);
270
		 w[j] = wr[j] + wi[j] + 2 );
2 r 271
 
66734 maechler 272
    _PRINT_MATRIX_( , STD_ColumnLabels,
74734 kalibera 273
		   if (ISNA(x[i + j * (R_xlen_t) r].r) ||
274
		       ISNA(x[i + j * (R_xlen_t) r].i))
275
 
66734 maechler 276
		       Rprintf("%s", EncodeReal0(NA_REAL, w[j], 0, 0, OutDec));
277
		   else
70352 murdoch 278
		       /* Note that the label printing may modify w[j], so wr[j] is not 
279
		          necessarily still valid, and we use w[j] - wi[j] - 2  */
66734 maechler 280
		       Rprintf("%s",
74734 kalibera 281
			       EncodeComplex(x[i + j * (R_xlen_t) r],
70352 murdoch 282
					     w[j] - wi[j] - 2, dr[j], er[j],
66734 maechler 283
					     wi[j], di[j], ei[j], OutDec)) )
2 r 284
}
285
 
38961 maechler 286
static void printStringMatrix(SEXP sx, int offset, int r_pr, int r, int c,
4717 maechler 287
			      int quote, int right, SEXP rl, SEXP cl,
66734 maechler 288
			      const char *rn, const char *cn, Rboolean print_ij)
2 r 289
{
38954 maechler 290
    _PRINT_INIT_rl_rn;
73750 luke 291
    const SEXP *x = STRING_PTR_RO(sx)+offset;
2 r 292
 
74734 kalibera 293
    _COMPUTE_W2_( formatString(&x[j * (R_xlen_t) r], (R_xlen_t) r,
294
                               &w[j], quote), );
4731 pd 295
 
66734 maechler 296
    _PRINT_MATRIX_( + R_print.gap,
297
	           /* DO_COLUMN_LABELS = */
298
		   if (right) {
299
		       for (j = jmin; j < jmax ; j++)
300
			   RightMatrixColumnLabel(cl, j, w[j]);
301
		   }
302
		   else {
303
		       for (j = jmin; j < jmax ; j++)
304
			   LeftMatrixColumnLabel(cl, j, w[j]);
305
		   },
306
		   /* ENCODE_I = */
307
		   Rprintf("%*s%s", R_print.gap, "",
74734 kalibera 308
			   EncodeString(x[i + j * (R_xlen_t) r],
309
		                        w[j], quote, right)) );
2 r 310
}
311
 
38961 maechler 312
static void printRawMatrix(SEXP sx, int offset, int r_pr, int r, int c,
66734 maechler 313
			   SEXP rl, SEXP cl, const char *rn, const char *cn,
314
			   Rboolean print_ij)
34538 ripley 315
{
38954 maechler 316
    _PRINT_INIT_rl_rn;
73728 luke 317
    const Rbyte *x = RAW_RO(sx) + offset;
34538 ripley 318
 
74734 kalibera 319
    _COMPUTE_W_( formatRaw(&x[j * (R_xlen_t) r], (R_xlen_t) r, &w[j]) )
34538 ripley 320
 
66734 maechler 321
    _PRINT_MATRIX_( , STD_ColumnLabels,
74734 kalibera 322
		   Rprintf("%*s%s", w[j]-2, "",
323
		   EncodeRaw(x[i + j * (R_xlen_t) r], "")) );
34538 ripley 324
}
325
 
69366 ripley 326
/* rm and cn are found by GetMatrixDimnames so in native encoding */
61776 ripley 327
attribute_hidden
1858 ihaka 328
void printMatrix(SEXP x, int offset, SEXP dim, int quote, int right,
41784 ripley 329
		 SEXP rl, SEXP cl, const char *rn, const char *cn)
2 r 330
{
38954 maechler 331
/* 'rl' and 'cl' are dimnames(.)[[1]] and dimnames(.)[[2]]  whereas
332
 * 'rn' and 'cn' are the  names(dimnames(.))
333
 */
63155 luke 334
    const void *vmax = vmaxget();
73728 luke 335
    const int *pdim = INTEGER_RO(dim);
336
    int r = pdim[0];
337
    int c = pdim[1], r_pr;
12976 pd 338
    /* PR#850 */
38980 maechler 339
    if ((rl != R_NilValue) && (r > length(rl)))
32871 ripley 340
	error(_("too few row labels"));
38980 maechler 341
    if ((cl != R_NilValue) && (c > length(cl)))
32871 ripley 342
	error(_("too few column labels"));
66734 maechler 343
    if (r == 0 && c == 0) { // FIXME?  names(dimnames(.)) :
20812 ripley 344
	Rprintf("<0 x 0 matrix>\n");
345
	return;
346
    }
38961 maechler 347
    r_pr = r;
348
    if(c > 0 && R_print.max / c < r) /* avoid integer overflow */
38980 maechler 349
	/* using floor(), not ceil(), since 'c' could be huge: */
38961 maechler 350
	r_pr = R_print.max / c;
1820 ihaka 351
    switch (TYPEOF(x)) {
352
    case LGLSXP:
66734 maechler 353
	printLogicalMatrix(x, offset, r_pr, r, c, rl, cl, rn, cn, TRUE);
1820 ihaka 354
	break;
355
    case INTSXP:
66734 maechler 356
	printIntegerMatrix(x, offset, r_pr, r, c, rl, cl, rn, cn, TRUE);
1820 ihaka 357
	break;
358
    case REALSXP:
66734 maechler 359
	printRealMatrix	  (x, offset, r_pr, r, c, rl, cl, rn, cn, TRUE);
1820 ihaka 360
	break;
361
    case CPLXSXP:
66734 maechler 362
	printComplexMatrix(x, offset, r_pr, r, c, rl, cl, rn, cn, TRUE);
1820 ihaka 363
	break;
364
    case STRSXP:
365
	if (quote) quote = '"';
66734 maechler 366
	printStringMatrix (x, offset, r_pr, r, c, quote, right, rl, cl, rn, cn, TRUE);
1820 ihaka 367
	break;
34538 ripley 368
    case RAWSXP:
66734 maechler 369
	printRawMatrix	  (x, offset, r_pr, r, c, rl, cl, rn, cn, TRUE);
34538 ripley 370
	break;
34547 ripley 371
    default:
372
	UNIMPLEMENTED_TYPE("printMatrix", x);
1820 ihaka 373
    }
39078 ripley 374
#ifdef ENABLE_NLS
60801 ripley 375
    if(r_pr < r) // number of formats must be consistent here
376
	Rprintf(ngettext(" [ reached getOption(\"max.print\") -- omitted %d row ]\n",
58733 maechler 377
			 " [ reached getOption(\"max.print\") -- omitted %d rows ]\n",
38980 maechler 378
			 r - r_pr),
38961 maechler 379
		r - r_pr);
39078 ripley 380
#else
66734 maechler 381
    if(r_pr < r)
58733 maechler 382
	Rprintf(" [ reached getOption(\"max.print\") -- omitted %d rows ]\n",
39078 ripley 383
		r - r_pr);
384
#endif
63155 luke 385
    vmaxset(vmax);
1820 ihaka 386
}
387
 
61776 ripley 388
attribute_hidden
389
void printArray(SEXP x, SEXP dim, int quote, int right, SEXP dimnames)
1820 ihaka 390
{
3076 pd 391
/* == printArray(.) */
63155 luke 392
    const void *vmax = vmaxget();
38915 maechler 393
    int ndim = LENGTH(dim);
41937 ripley 394
    const char *rn = NULL, *cn = NULL;
1820 ihaka 395
 
396
    if (ndim == 1)
397
	printVector(x, 1, quote);
398
    else if (ndim == 2) {
399
	SEXP rl, cl;
4710 pd 400
	GetMatrixDimnames(x, &rl, &cl, &rn, &cn);
401
	printMatrix(x, 0, dim, quote, 0, rl, cl, rn, cn);
1820 ihaka 402
    }
38961 maechler 403
    else { /* ndim >= 3 */
38915 maechler 404
	SEXP dn, dnn, dn0, dn1;
73728 luke 405
	const int *dims = INTEGER_RO(dim);
66734 maechler 406
	int i, j, nb, nb_pr, nr_last,
73728 luke 407
	    nr = dims[0], nc = dims[1],
66734 maechler 408
	    b = nr * nc;
409
	Rboolean max_reached, has_dimnames = (dimnames != R_NilValue),
410
	    has_dnn = has_dimnames;
38961 maechler 411
 
66734 maechler 412
	if (!has_dimnames) {
1858 ihaka 413
	    dn0 = R_NilValue;
414
	    dn1 = R_NilValue;
38915 maechler 415
	    dnn = R_NilValue; /* -Wall */
1858 ihaka 416
	}
417
	else {
10172 luke 418
	    dn0 = VECTOR_ELT(dimnames, 0);
419
	    dn1 = VECTOR_ELT(dimnames, 1);
4710 pd 420
	    dnn = getAttrib(dimnames, R_NamesSymbol);
4717 maechler 421
	    has_dnn = !isNull(dnn);
4710 pd 422
	    if ( has_dnn ) {
41784 ripley 423
		rn = (char *) translateChar(STRING_ELT(dnn, 0));
424
		cn = (char *) translateChar(STRING_ELT(dnn, 1));
4710 pd 425
	    }
1858 ihaka 426
	}
38961 maechler 427
	/* nb := #{entries} in a slice such as x[1,1,..] or equivalently,
428
	 *       the number of matrix slices   x[ , , *, ..]  which
429
	 *       are printed as matrices -- if options("max.print") allows */
430
	for (i = 2, nb = 1; i < ndim; i++)
66734 maechler 431
	    nb *= dims[i];
38980 maechler 432
	max_reached = (b > 0 && R_print.max / b < nb);
433
	if (max_reached) { /* i.e., also  b > 0, nr > 0, nc > 0, nb > 0 */
434
	    /* nb_pr := the number of matrix slices to be printed */
435
	    nb_pr = ceil_DIV(R_print.max, b);
436
	    /* for the last, (nb_pr)th matrix slice, use only nr_last rows;
437
	     *  using floor(), not ceil(), since 'nc' could be huge: */
438
	    nr_last = (R_print.max - b * (nb_pr - 1)) / nc;
439
	    if(nr_last == 0) { nb_pr--; nr_last = nr; }
440
	} else {
66734 maechler 441
	    nb_pr = (nb > 0) ? nb : 1; // do print *something* when dim = c(a,b,0)
38980 maechler 442
	    nr_last = nr;
443
	}
444
	for (i = 0; i < nb_pr; i++) {
66734 maechler 445
	    Rboolean do_ij = nb > 0,
446
		i_last = (i == nb_pr - 1); /* for the last slice */
447
	    int use_nr = i_last ? nr_last : nr;
448
	    if(do_ij) {
449
		int k = 1;
450
		Rprintf(", ");
451
		for (j = 2 ; j < ndim; j++) {
452
		    int l = (i / k) % dims[j] + 1;
453
		    if (has_dimnames &&
454
			((dn = VECTOR_ELT(dimnames, j)) != R_NilValue)) {
455
			if ( has_dnn )
456
			    Rprintf(", %s = %s",
457
				    translateChar(STRING_ELT(dnn, j)),
458
				    translateChar(STRING_ELT(dn, l - 1)));
459
			else
460
			    Rprintf(", %s", translateChar(STRING_ELT(dn, l - 1)));
461
		    } else
462
			Rprintf(", %d", l);
463
		    k *= dims[j];
464
		}
465
		Rprintf("\n\n");
466
	    } else { // nb == 0 -- e.g. <2 x 3 x 0 array of logical>
467
		for (i = 0; i < ndim; i++)
468
		    Rprintf("%s%d", (i == 0) ? "<" : " x ", dims[i]);
469
		Rprintf(" array of %s>\n", CHAR(type2str_nowarn(TYPEOF(x))));
38980 maechler 470
	    }
1820 ihaka 471
	    switch (TYPEOF(x)) {
472
	    case LGLSXP:
66734 maechler 473
		printLogicalMatrix(x, i * b, use_nr, nr, nc, dn0, dn1, rn, cn, do_ij);
2 r 474
		break;
1820 ihaka 475
	    case INTSXP:
66734 maechler 476
		printIntegerMatrix(x, i * b, use_nr, nr, nc, dn0, dn1, rn, cn, do_ij);
2 r 477
		break;
1820 ihaka 478
	    case REALSXP:
66734 maechler 479
		printRealMatrix   (x, i * b, use_nr, nr, nc, dn0, dn1, rn, cn, do_ij);
2 r 480
		break;
1820 ihaka 481
	    case CPLXSXP:
66734 maechler 482
		printComplexMatrix(x, i * b, use_nr, nr, nc, dn0, dn1, rn, cn, do_ij);
2 r 483
		break;
1820 ihaka 484
	    case STRSXP:
2 r 485
		if (quote) quote = '"';
38980 maechler 486
		printStringMatrix (x, i * b, use_nr, nr, nc,
66734 maechler 487
				   quote, right, dn0, dn1, rn, cn, do_ij);
2 r 488
		break;
34538 ripley 489
	    case RAWSXP:
66734 maechler 490
		printRawMatrix    (x, i * b, use_nr, nr, nc, dn0, dn1, rn, cn, do_ij);
34538 ripley 491
		break;
1820 ihaka 492
	    }
493
	    Rprintf("\n");
2 r 494
	}
38980 maechler 495
 
496
	if(max_reached && nb_pr < nb) {
497
	    Rprintf(" [ reached getOption(\"max.print\") -- omitted");
498
	    if(nr_last < nr) Rprintf(" %d row(s) and", nr - nr_last);
499
	    Rprintf(" %d matrix slice(s) ]\n", nb - nb_pr);
500
	}
1820 ihaka 501
    }
63155 luke 502
    vmaxset(vmax);
2 r 503
}
504