The R Project SVN R

Rev

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

Rev 24735 Rev 27365
Line 224... Line 224...
224
{
224
{
225
    int canstretch, count, i, nmax;
225
    int canstretch, count, i, nmax;
226
    SEXP indx;
226
    SEXP indx;
227
    canstretch = *stretch;
227
    canstretch = *stretch;
228
    if (!canstretch && ns > nx)
228
    if (!canstretch && ns > nx)
229
	error("(subscript) logical subscript too long");
229
        error("(subscript) logical subscript too long");
230
    nmax = (ns > nx) ? ns : nx;
230
    nmax = (ns > nx) ? ns : nx;
231
    *stretch = (ns > nx) ? ns : 0;
231
    *stretch = (ns > nx) ? ns : 0;
232
    if (ns == 0)
232
    if (ns == 0)
233
	return(allocVector(INTSXP, 0));
233
        return(allocVector(INTSXP, 0));
234
    count = 0;
234
    count = 0;
235
    for (i = 0; i < nmax; i++)
235
    for (i = 0; i < nmax; i++)
236
	if (LOGICAL(s)[i%ns])
236
        if (LOGICAL(s)[i%ns] != FALSE)
237
	    count++;
237
            count++;
238
    indx = allocVector(INTSXP, count);
238
    indx = allocVector(INTSXP, count);
239
    count = 0;
239
    count = 0;
240
    for (i = 0; i < nmax; i++)
240
    for (i = 0; i < nmax; i++) {
241
	if (LOGICAL(s)[i%ns]) {
241
        int tmp = LOGICAL(s)[i%ns];
242
	    if (LOGICAL(s)[i%ns] == NA_LOGICAL)
242
        if (tmp == NA_LOGICAL)
243
		INTEGER(indx)[count++] = NA_INTEGER;
243
            INTEGER(indx)[count++] = NA_INTEGER;
244
	    else
-
 
245
		INTEGER(indx)[count++] = i + 1;
244
        else if (tmp == TRUE) INTEGER(indx)[count++] = i + 1;
246
	}
245
    }
247
    return indx;
246
    return indx;
248
}
247
}
249
 
248
 
250
static SEXP negativeSubscript(SEXP s, int ns, int nx)
249
static SEXP negativeSubscript(SEXP s, int ns, int nx)
251
{
250
{
252
    SEXP indx;
-
 
253
    int stretch = 0;
251
    int count, i;
254
    int i;
-
 
255
    PROTECT(indx = allocVector(INTSXP, nx));
252
    SEXP indx = PROTECT(allocVector(LGLSXP, nx));
-
 
253
 
256
    for (i = 0; i < nx; i++)
254
    for (i = 0; i < nx; i++)
257
	INTEGER(indx)[i] = 1;
255
        LOGICAL(indx)[i] = TRUE;
-
 
256
    count = nx;
258
    for (i = 0; i < ns; i++)
257
    for (i = 0; i < ns; i++)
259
	if (INTEGER(s)[i] != 0)
258
        if (INTEGER(s)[i] != 0) {
260
	    INTEGER(indx)[-INTEGER(s)[i] - 1] = 0;
259
            LOGICAL(indx)[-INTEGER(s)[i] - 1] = FALSE;
-
 
260
            count--;
-
 
261
        }
261
    s = logicalSubscript(indx, nx, nx, &stretch);
262
    s = allocVector(INTSXP, count);
-
 
263
    count = 0;
-
 
264
    for (i = 0; i < nx; i++)
-
 
265
        if (LOGICAL(indx)[i])
-
 
266
            INTEGER(s)[count++] = i + 1;
-
 
267
 
262
    UNPROTECT(1);
268
    UNPROTECT(1);
263
    return s;
269
    return s;
264
}
270
}
265
 
271
 
266
static SEXP positiveSubscript(SEXP s, int ns, int nx)
272
static SEXP positiveSubscript(SEXP s, int ns, int nx)
267
{
273
{
268
    SEXP indx;
274
    SEXP indx;
269
    int i, zct = 0;
275
    int i, zct = 0;
270
    for (i = 0; i < ns; i++) {
276
    for (i = 0; i < ns; i++) {
271
	if (INTEGER(s)[i] == 0)
277
        if (INTEGER(s)[i] == 0)
272
	    zct++;
278
            zct++;
273
    }
279
    }
274
    if (zct) {
280
    if (zct) {
275
	indx = allocVector(INTSXP, (ns - zct));
281
        indx = allocVector(INTSXP, (ns - zct));
276
	for (i = 0, zct = 0; i < ns; i++)
282
        for (i = 0, zct = 0; i < ns; i++)
277
	    if (INTEGER(s)[i] != 0)
283
            if (INTEGER(s)[i] != 0)
278
		INTEGER(indx)[zct++] = INTEGER(s)[i];
284
                INTEGER(indx)[zct++] = INTEGER(s)[i];
279
	return indx;
285
        return indx;
280
    }
-
 
281
    else
-
 
282
	return s;
286
    } else return s;
283
}
287
}
284
 
288
 
285
static SEXP integerSubscript(SEXP s, int ns, int nx, int *stretch)
289
static SEXP integerSubscript(SEXP s, int ns, int nx, int *stretch)
286
{
290
{
287
    int i, ii, min, max, canstretch;
291
    int i, ii, min, max, canstretch;
-
 
292
    int have_na = 0;
288
    canstretch = *stretch;
293
    canstretch = *stretch;
289
    *stretch = 0;
294
    *stretch = 0;
290
    min = 0;
295
    min = 1;
291
    max = 0;
296
    max = 0;
292
    for (i = 0; i < ns; i++) {
297
    for (i = 0; i < ns; i++) {
293
	ii = INTEGER(s)[i];
298
        ii = INTEGER(s)[i];
294
	if (ii != NA_INTEGER) {
299
        if (ii == NA_INTEGER) {
-
 
300
            have_na = 1;
-
 
301
        } else {
295
	    if (ii < min)
302
            if (ii < min)
296
		min = ii;
303
                min = ii;
297
	    if (ii > max)
304
            if (ii > max)
298
		max = ii;
305
                max = ii;
299
	}
306
        }
300
    }
307
    }
301
    if (min < -nx)
308
    if (min < -nx)
302
	error("subscript out of bounds");
309
        error("subscript out of bounds");
303
    if (max > nx) {
310
    if (max > nx) {
304
	if(canstretch) *stretch = max;
311
        if(canstretch) *stretch = max;
305
	else error("subscript out of bounds");
312
        else error("subscript out of bounds");
306
    }
313
    }
307
    if (min < 0) {
314
    if (min < 0) {
308
	if (max == 0) return negativeSubscript(s, ns, nx);
315
        if (max != 0 || have_na)
309
	else error("only 0's may mix with negative subscripts");
316
            error("only 0's may mix with negative subscripts");
-
 
317
        return negativeSubscript(s, ns, nx);
310
    }
318
    }
-
 
319
    if (have_na || min == 0)
311
    else return positiveSubscript(s, ns, nx);
320
        return positiveSubscript(s, ns, nx);
312
    return R_NilValue;
321
    else return s;
313
}
322
}
314
 
323
 
-
 
324
typedef SEXP (*StringEltGetter)(SEXP x, int i); 
-
 
325
 
315
static SEXP stringSubscript(SEXP s, int ns, int nx, SEXP names, int *stretch)
326
static SEXP stringSubscript(SEXP s, int ns, int nx, SEXP names,
-
 
327
                            StringEltGetter strg,
-
 
328
                            int *stretch)
316
{
329
{
317
    SEXP indx, indexnames;
330
    SEXP indx, indexnames;
318
    int i, j, nnames, sub, extra;
331
    int i, j, nnames, sub, extra;
319
    int canstretch = *stretch;
332
    int canstretch = *stretch;
320
    PROTECT(s);
333
    PROTECT(s);
Line 330... Line 343...
330
    /* the previous subscripts. */
343
    /* the previous subscripts. */
331
 
344
 
332
    for (i = 0; i < ns; i++) {
345
    for (i = 0; i < ns; i++) {
333
	sub = 0;
346
	sub = 0;
334
	if (names != R_NilValue) {
347
	if (names != R_NilValue) {
335
	    for (j = 0; j < nnames; j++)
348
	    for (j = 0; j < nnames; j++) {
-
 
349
        SEXP name_j = strg(names, j);
-
 
350
        if (TYPEOF(name_j) != CHARSXP)
-
 
351
            error("character vector element does not have type CHARSXP");
336
		if (NonNullStringMatch(STRING_ELT(s, i), STRING_ELT(names, j))) {
352
		if (NonNullStringMatch(STRING_ELT(s, i), name_j)) {
337
		    sub = j + 1;
353
		    sub = j + 1;
338
		    SET_STRING_ELT(indexnames, i, R_NilValue);
354
		    SET_STRING_ELT(indexnames, i, R_NilValue);
339
		    break;
355
		    break;
340
		}
356
		}
-
 
357
        }
341
	}
358
	}
342
	if (sub == 0) {
359
	if (sub == 0) {
343
	    for (j = 0 ; j < i ; j++)
360
	    for (j = 0 ; j < i ; j++)
344
		if (NonNullStringMatch(STRING_ELT(s, i), STRING_ELT(s, j))) {
361
		if (NonNullStringMatch(STRING_ELT(s, i), STRING_ELT(s, j))) {
345
		    sub = INTEGER(indx)[j];
362
		    sub = INTEGER(indx)[j];
Line 372... Line 389...
372
    dim is the dimension (0 to k-1)
389
    dim is the dimension (0 to k-1)
373
    s is the subscript list, 
390
    s is the subscript list, 
374
    dims is the dimensions of x
391
    dims is the dimensions of x
375
    dng is a function (usually getAttrib) that obtains the dimnames
392
    dng is a function (usually getAttrib) that obtains the dimnames
376
    x is the array to be subscripted. 
393
    x is the array to be subscripted. 
-
 
394
   strg extracts elements of a string vector, either obtained by using
-
 
395
   dng(x, R_NamesSymbol) or from one of the elements of an VECSXP
-
 
396
   obtained from dng(x, R_DimNamesSymbol).
377
*/
397
*/
378
 
398
 
379
typedef SEXP AttrGetter(SEXP x, SEXP data);
399
typedef SEXP (*AttrGetter)(SEXP x, SEXP data);
380
 
400
 
381
SEXP arraySubscript(int dim, SEXP s, SEXP dims, AttrGetter dng, SEXP x)
401
SEXP arraySubscript(int dim, SEXP s, SEXP dims,
-
 
402
                    AttrGetter dng, StringEltGetter strg, SEXP x)
382
{
403
{
383
    int nd, ns, stretch = 0;
404
    int nd, ns, stretch = 0;
384
    SEXP dnames, tmp;
405
    SEXP dnames, tmp;
385
    ns = length(s);
406
    ns = length(s);
386
    nd = INTEGER(dims)[dim];
407
    nd = INTEGER(dims)[dim];
Line 400... Line 421...
400
    case STRSXP:
421
    case STRSXP:
401
	dnames = dng(x, R_DimNamesSymbol);
422
	dnames = dng(x, R_DimNamesSymbol);
402
	if (dnames == R_NilValue)
423
	if (dnames == R_NilValue)
403
	    error("no dimnames attribute for array");
424
	    error("no dimnames attribute for array");
404
	dnames = VECTOR_ELT(dnames, dim);
425
	dnames = VECTOR_ELT(dnames, dim);
405
	return stringSubscript(s, ns, nd, dnames, &stretch);
426
	return stringSubscript(s, ns, nd, dnames, strg,
-
 
427
                           &stretch);
406
    case SYMSXP:
428
    case SYMSXP:
407
	if (s == R_MissingArg)
429
	if (s == R_MissingArg)
408
	    return nullSubscript(nd);
430
	    return nullSubscript(nd);
409
    default:
431
    default:
410
	error("invalid subscript");
432
	error("invalid subscript");
Line 427... Line 449...
427
 
449
 
428
    ans = R_NilValue;
450
    ans = R_NilValue;
429
    if (isVector(x) || isList(x) || isLanguage(x)) {
451
    if (isVector(x) || isList(x) || isLanguage(x)) {
430
	nx = length(x);
452
	nx = length(x);
431
 
453
 
432
	ans = vectorSubscript(nx, s, stretch, getAttrib, x);
454
	ans = vectorSubscript(nx, s, stretch, getAttrib,
-
 
455
                          (STRING_ELT), x);
433
    }
456
    }
434
    else error("subscripting on non-vector");
457
    else error("subscripting on non-vector");
435
    return ans;
458
    return ans;
436
 
459
 
437
}
460
}
438
 
461
 
439
/* nx is the length of the object being subscripted,
462
/* nx is the length of the object being subscripted,
440
   s is the R subscript value,
463
   s is the R subscript value,
441
   dng gets a given attrib for x, which is the object we are
464
   dng gets a given attrib for x, which is the object we are
442
   subsetting,
465
   subsetting,
-
 
466
   strg extracts elements of a string vector, either obtained by using
-
 
467
   dng(x, R_NamesSymbol) or from one of the elements of an VECSXP
-
 
468
   obtained from dng(x, R_DimNamesSymbol).
443
*/
469
*/
444
 
470
 
445
SEXP vectorSubscript(int nx, SEXP s, int *stretch, AttrGetter dng,
471
SEXP vectorSubscript(int nx, SEXP s, int *stretch,
446
		     SEXP x) 
472
                     AttrGetter dng, StringEltGetter strg, SEXP x)
447
{
473
{
448
    int ns;
474
    int ns;
449
    SEXP ans=R_NilValue, tmp;
475
    SEXP ans=R_NilValue, tmp;
450
 
476
 
451
    ns = length(s);
477
    ns = length(s);
Line 478... Line 504...
478
	break;
504
	break;
479
    case STRSXP:
505
    case STRSXP:
480
    {
506
    {
481
	SEXP names = dng(x, R_NamesSymbol);
507
	SEXP names = dng(x, R_NamesSymbol);
482
	/* *stretch = 0; */
508
	/* *stretch = 0; */
483
	ans = stringSubscript(s, ns, nx, names, stretch);
509
	ans = stringSubscript(s, ns, nx, names, strg,
-
 
510
                          stretch);
484
    }
511
    }
485
    break;
512
    break;
486
    case SYMSXP:
513
    case SYMSXP:
487
	*stretch = 0;
514
	*stretch = 0;
488
	if (s == R_MissingArg) {
515
	if (s == R_MissingArg) {
Line 493... Line 520...
493
	error("invalid subscript type");
520
	error("invalid subscript type");
494
    }
521
    }
495
    UNPROTECT(1);
522
    UNPROTECT(1);
496
    return ans;
523
    return ans;
497
}
524
}
498
 
-
 
499
 
-
 
500
 
-