The R Project SVN R

Rev

Rev 28254 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 r 1
/*
1160 maechler 2
 *  R : A Computer Language for Statistical Data Analysis
2 r 3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
18560 ripley 4
 *  Copyright (C) 1997--2002  Robert Gentleman, Ross Ihaka and the
4562 pd 5
 *                            R Development Core Team
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
18
 *  along with this program; if not, write to the Free Software
5458 ripley 19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
2 r 20
 */
21
 
5187 hornik 22
#ifdef HAVE_CONFIG_H
7701 hornik 23
#include <config.h>
5187 hornik 24
#endif
25
 
11499 ripley 26
#include <Defn.h>
27
#include <Rmath.h>
28
#include <Print.h>
2 r 29
 
4747 hornik 30
#ifdef HAVE_UNISTD_H
31
#include <unistd.h>
32
#endif
33
 
1820 ihaka 34
SEXP ScalarLogical(int x)
2 r 35
{
1839 ihaka 36
    SEXP ans = allocVector(LGLSXP, 1);
37
    INTEGER(ans)[0] = x;
38
    return ans;
1820 ihaka 39
}
2 r 40
 
1820 ihaka 41
SEXP ScalarInteger(int x)
2 r 42
{
1839 ihaka 43
    SEXP ans = allocVector(INTSXP, 1);
44
    INTEGER(ans)[0] = x;
45
    return ans;
1820 ihaka 46
}
47
 
48
SEXP ScalarReal(double x)
49
{
1839 ihaka 50
    SEXP ans = allocVector(REALSXP, 1);
51
    REAL(ans)[0] = x;
52
    return ans;
1820 ihaka 53
}
54
 
6994 pd 55
SEXP ScalarComplex(Rcomplex x)
1820 ihaka 56
{
1839 ihaka 57
    SEXP ans = allocVector(CPLXSXP, 1);
58
    COMPLEX(ans)[0] = x;
59
    return ans;
1820 ihaka 60
}
61
 
62
SEXP ScalarString(SEXP x)
63
{
1839 ihaka 64
    SEXP ans;
4230 rgentlem 65
    PROTECT(x);
66
    ans = allocVector(STRSXP, 1);
10172 luke 67
    SET_STRING_ELT(ans, 0, x);
1839 ihaka 68
    UNPROTECT(1);
69
    return ans;
1820 ihaka 70
}
71
 
13997 duncan 72
const static char * const truenames[] = {
1820 ihaka 73
    "T",
74
    "True",
75
    "TRUE",
76
    "true",
77
    (char *) 0,
2 r 78
};
79
 
13997 duncan 80
const static char * const falsenames[] = {
1820 ihaka 81
    "F",
82
    "False",
83
    "FALSE",
84
    "false",
85
    (char *) 0,
86
};
87
 
10714 maechler 88
/* int, not Rboolean, for NA_LOGICAL : */
1858 ihaka 89
int asLogical(SEXP x)
2 r 90
{
14055 ripley 91
    int warn = 0;
92
 
6098 pd 93
    if (isVectorAtomic(x)) {
1820 ihaka 94
	if (LENGTH(x) < 1)
10714 maechler 95
	    return NA_LOGICAL;
1820 ihaka 96
	switch (TYPEOF(x)) {
97
	case LGLSXP:
1858 ihaka 98
	    return LOGICAL(x)[0];
1820 ihaka 99
	case INTSXP:
14055 ripley 100
	    return LogicalFromInteger(INTEGER(x)[0], &warn);
1820 ihaka 101
	case REALSXP:
14055 ripley 102
	    return LogicalFromReal(REAL(x)[0], &warn);
1820 ihaka 103
	case CPLXSXP:
14055 ripley 104
	    return LogicalFromComplex(COMPLEX(x)[0], &warn);
2 r 105
	}
1820 ihaka 106
    }
1858 ihaka 107
    return NA_LOGICAL;
2 r 108
}
109
 
1858 ihaka 110
int asInteger(SEXP x)
2 r 111
{
14055 ripley 112
    int warn = 0, res;
16182 ripley 113
 
6098 pd 114
    if (isVectorAtomic(x) && LENGTH(x) >= 1) {
1820 ihaka 115
	switch (TYPEOF(x)) {
116
	case LGLSXP:
14055 ripley 117
	    return IntegerFromLogical(LOGICAL(x)[0], &warn);
118
	case INTSXP:
119
	    return INTEGER(x)[0];
120
	case REALSXP:
121
	    res = IntegerFromReal(REAL(x)[0], &warn);
122
	    CoercionWarning(warn);
123
	    return res;
124
	case CPLXSXP:
125
	    res = IntegerFromComplex(COMPLEX(x)[0], &warn);
126
	    CoercionWarning(warn);
127
	    return res;
128
	}
129
    }
130
    return NA_INTEGER;
131
}
132
 
2 r 133
double asReal(SEXP x)
134
{
14055 ripley 135
    int warn = 0;
136
    double res;
16182 ripley 137
 
14055 ripley 138
    if (isVectorAtomic(x) && LENGTH(x) >= 1) {
139
	switch (TYPEOF(x)) {
140
	case LGLSXP:
141
	    res = RealFromLogical(LOGICAL(x)[0], &warn);
142
	    CoercionWarning(warn);
16182 ripley 143
	    return res;
14055 ripley 144
	case INTSXP:
145
	    res = RealFromInteger(INTEGER(x)[0], &warn);
146
	    CoercionWarning(warn);
16182 ripley 147
	    return res;
14055 ripley 148
	case REALSXP:
149
	    return REAL(x)[0];
150
	case CPLXSXP:
151
	    res = RealFromComplex(COMPLEX(x)[0], &warn);
152
	    CoercionWarning(warn);
16182 ripley 153
	    return res;
14055 ripley 154
	}
155
    }
156
    return NA_REAL;
157
}
1820 ihaka 158
 
6994 pd 159
Rcomplex asComplex(SEXP x)
1858 ihaka 160
{
14055 ripley 161
    int warn = 0;
162
    Rcomplex z;
163
 
164
    z.r = NA_REAL;
165
    z.i = NA_REAL;
166
    if (isVectorAtomic(x) && LENGTH(x) >= 1) {
167
	switch (TYPEOF(x)) {
168
	case LGLSXP:
169
	    return ComplexFromLogical(LOGICAL(x)[0], &warn);
170
	case INTSXP:
171
	    return ComplexFromInteger(INTEGER(x)[0], &warn);
172
	case REALSXP:
173
	    return ComplexFromReal(REAL(x)[0], &warn);
174
	case CPLXSXP:
175
	    return COMPLEX(x)[0];
176
	}
177
    }
178
    return z;
179
}
180
 
2 r 181
SEXP asChar(SEXP x)
182
{
7916 ripley 183
    int w, d, e, wi, di, ei;
1820 ihaka 184
    char buf[MAXELTSIZE];
2 r 185
 
6098 pd 186
    if (isVectorAtomic(x) && LENGTH(x) >= 1) {
1820 ihaka 187
	switch (TYPEOF(x)) {
188
	case LGLSXP:
189
	    if (LOGICAL(x)[0] == NA_LOGICAL)
190
		return NA_STRING;
191
	    if (LOGICAL(x)[0])
192
		sprintf(buf, "T");
193
	    else
194
		sprintf(buf, "F");
195
	    return mkChar(buf);
196
	case INTSXP:
197
	    if (INTEGER(x)[0] == NA_INTEGER)
198
		return NA_STRING;
199
	    sprintf(buf, "%d", INTEGER(x)[0]);
200
	    return mkChar(buf);
201
	case REALSXP:
14357 ripley 202
	    formatReal(REAL(x), 1, &w, &d, &e, 0);
6575 pd 203
	    return mkChar(EncodeReal(REAL(x)[0], w, d, e));
7916 ripley 204
        case CPLXSXP:
14357 ripley 205
	    formatComplex(COMPLEX(x), 1, &w, &d, &e, &wi, &di, &ei, 0);
7916 ripley 206
	    return mkChar(EncodeComplex(COMPLEX(x)[0], w, d, e, wi, di, ei));
1820 ihaka 207
	case STRSXP:
10172 luke 208
	    return STRING_ELT(x, 0);
1820 ihaka 209
	default:
210
	    return NA_STRING;
2 r 211
	}
1820 ihaka 212
    }
213
    return NA_STRING;
2 r 214
}
215
 
28362 murdoch 216
R_len_t asVecSize(SEXP x)
217
{
218
    int warn = 0, res;
219
    double d;
1820 ihaka 220
 
28362 murdoch 221
    if (isVectorAtomic(x) && LENGTH(x) >= 1) {
222
	switch (TYPEOF(x)) {
223
	case LGLSXP:
224
	    res = IntegerFromLogical(LOGICAL(x)[0], &warn);
225
	    if(res == NA_INTEGER) error("vector size cannot be NA");
226
	    return res;
227
	case INTSXP:
228
	    res = INTEGER(x)[0];
229
	    if(res == NA_INTEGER) error("vector size cannot be NA");
230
	    return res;
231
	case REALSXP:
232
	    d = REAL(x)[0];
233
	    if(d < 0) error("vector size cannot be negative");
234
	    if(d > R_LEN_T_MAX) error("vector size specified is too large");
235
	    return (R_size_t) d;
236
	}
237
    }
238
    return -1;
239
}
240
 
241
 
13997 duncan 242
const static char type_msg[] = "invalid type passed to internal function\n";
2 r 243
 
1820 ihaka 244
 
2 r 245
void internalTypeCheck(SEXP call, SEXP s, SEXPTYPE type)
246
{
1820 ihaka 247
    if (TYPEOF(s) != type) {
248
	if (call)
249
	    errorcall(call, type_msg);
250
	else
251
	    error(type_msg);
252
    }
2 r 253
}
254
 
11139 maechler 255
Rboolean isValidString(SEXP x)
5111 ihaka 256
{
10172 luke 257
    return isString(x) && LENGTH(x) > 0 && !isNull(STRING_ELT(x, 0));
5111 ihaka 258
}
1820 ihaka 259
 
6201 maechler 260
/* non-empty ("") valid string :*/
11139 maechler 261
Rboolean isValidStringF(SEXP x)
6201 maechler 262
{
10172 luke 263
    return isValidString(x) && CHAR(STRING_ELT(x, 0))[0];
6201 maechler 264
}
265
 
11139 maechler 266
Rboolean isSymbol(SEXP s)
2 r 267
{
1820 ihaka 268
    return TYPEOF(s) == SYMSXP;
2 r 269
}
270
 
1820 ihaka 271
 
11139 maechler 272
Rboolean isUserBinop(SEXP s)
2 r 273
{
1839 ihaka 274
    if (isSymbol(s)) {
1820 ihaka 275
	char *str = CHAR(PRINTNAME(s));
13855 pd 276
	if (strlen(str) >= 2 && str[0] == '%' && str[strlen(str)-1] == '%')
11139 maechler 277
	    return TRUE;
1820 ihaka 278
    }
11139 maechler 279
    return FALSE;
2 r 280
}
281
 
1820 ihaka 282
 
11139 maechler 283
Rboolean isNull(SEXP s)
2 r 284
{
2379 hornik 285
    return (s == R_NilValue ||
286
	    (TYPEOF(s) == EXPRSXP && LENGTH(s) == 0));
1839 ihaka 287
}
2 r 288
 
1820 ihaka 289
 
11139 maechler 290
Rboolean isFunction(SEXP s)
2 r 291
{
2398 maechler 292
    return (TYPEOF(s) == CLOSXP ||
293
	    TYPEOF(s) == BUILTINSXP ||
1820 ihaka 294
	    TYPEOF(s) == SPECIALSXP);
2 r 295
}
296
 
16707 jmc 297
Rboolean isPrimitive(SEXP s)
298
{
299
    return (TYPEOF(s) == BUILTINSXP ||
300
	    TYPEOF(s) == SPECIALSXP);
301
}
1820 ihaka 302
 
16707 jmc 303
 
11139 maechler 304
Rboolean isList(SEXP s)
2 r 305
{
1820 ihaka 306
    return (s == R_NilValue || TYPEOF(s) == LISTSXP);
2 r 307
}
308
 
1820 ihaka 309
 
11139 maechler 310
Rboolean isNewList(SEXP s)
1839 ihaka 311
{
312
    return (s == R_NilValue || TYPEOF(s) == VECSXP);
313
}
314
 
11139 maechler 315
Rboolean isPairList(SEXP s)
1820 ihaka 316
{
317
    switch (TYPEOF(s)) {
318
    case NILSXP:
319
    case LISTSXP:
320
    case LANGSXP:
11139 maechler 321
	return TRUE;
1820 ihaka 322
    default:
11139 maechler 323
	return FALSE;
1820 ihaka 324
    }
325
}
326
 
11139 maechler 327
Rboolean isVectorList(SEXP s)
1820 ihaka 328
{
1839 ihaka 329
    switch (TYPEOF(s)) {
330
    case VECSXP:
331
    case EXPRSXP:
11139 maechler 332
	return TRUE;
1839 ihaka 333
    default:
11139 maechler 334
	return FALSE;
1839 ihaka 335
    }
1820 ihaka 336
}
337
 
11139 maechler 338
Rboolean isVectorAtomic(SEXP s)
1820 ihaka 339
{
340
    switch (TYPEOF(s)) {
341
    case LGLSXP:
342
    case INTSXP:
343
    case REALSXP:
344
    case CPLXSXP:
345
    case STRSXP:
11139 maechler 346
	return TRUE;
13258 maechler 347
    default: /* including NULL */
11139 maechler 348
	return FALSE;
6098 pd 349
    }
350
}
351
 
11139 maechler 352
Rboolean isVector(SEXP s)/* === isVectorList() or isVectorAtomic() */
6098 pd 353
{
354
    switch(TYPEOF(s)) {
355
    case LGLSXP:
356
    case INTSXP:
357
    case REALSXP:
358
    case CPLXSXP:
359
    case STRSXP:
6994 pd 360
 
1820 ihaka 361
    case VECSXP:
362
    case EXPRSXP:
11139 maechler 363
	return TRUE;
1820 ihaka 364
    default:
11139 maechler 365
	return FALSE;
1820 ihaka 366
    }
367
}
368
 
369
 
11139 maechler 370
Rboolean isFrame(SEXP s)
2 r 371
{
1820 ihaka 372
    SEXP class;
373
    int i;
1839 ihaka 374
    if (isObject(s)) {
1820 ihaka 375
	class = getAttrib(s, R_ClassSymbol);
1839 ihaka 376
	for (i = 0; i < length(class); i++)
11139 maechler 377
	    if (!strcmp(CHAR(STRING_ELT(class, i)), "data.frame")) return TRUE;
1820 ihaka 378
    }
11139 maechler 379
    return FALSE;
2 r 380
}
381
 
11139 maechler 382
Rboolean isEnvironment(SEXP s)
2 r 383
{
2810 maechler 384
    return (TYPEOF(s) == NILSXP || TYPEOF(s) == ENVSXP);
2 r 385
}
386
 
11139 maechler 387
Rboolean isExpression(SEXP s)
2 r 388
{
1820 ihaka 389
    return TYPEOF(s) == EXPRSXP;
2 r 390
}
391
 
11139 maechler 392
Rboolean isLanguage(SEXP s)
2 r 393
{
1820 ihaka 394
    return (s == R_NilValue || TYPEOF(s) == LANGSXP);
2 r 395
}
396
 
1820 ihaka 397
 
11139 maechler 398
Rboolean isMatrix(SEXP s)
2 r 399
{
1820 ihaka 400
    SEXP t;
401
    if (isVector(s)) {
402
	t = getAttrib(s, R_DimSymbol);
403
	if (TYPEOF(t) == INTSXP && LENGTH(t) == 2)
11139 maechler 404
	    return TRUE;
1820 ihaka 405
    }
11139 maechler 406
    return FALSE;
2 r 407
}
408
 
11139 maechler 409
Rboolean isArray(SEXP s)
2 r 410
{
1820 ihaka 411
    SEXP t;
412
    if (isVector(s)) {
413
	t = getAttrib(s, R_DimSymbol);
414
	if (TYPEOF(t) == INTSXP && LENGTH(t) > 0)
11139 maechler 415
	    return TRUE;
1820 ihaka 416
    }
11139 maechler 417
    return FALSE;
2 r 418
}
419
 
1820 ihaka 420
 
11139 maechler 421
Rboolean isTs(SEXP s)
2 r 422
{
2810 maechler 423
    return (isVector(s) && getAttrib(s, R_TspSymbol) != R_NilValue);
2 r 424
}
425
 
11139 maechler 426
Rboolean tsConform(SEXP x, SEXP y)
2 r 427
{
1820 ihaka 428
    if ((x = getAttrib(x, R_TspSymbol)) != R_NilValue &&
429
	(y = getAttrib(y, R_TspSymbol)) != R_NilValue)
430
	return INTEGER(x)[0] == INTEGER(x)[0] &&
431
	    INTEGER(x)[1] == INTEGER(x)[1] &&
432
	    INTEGER(x)[2] == INTEGER(x)[2];
11139 maechler 433
    return FALSE;
2 r 434
}
435
 
436
 
1820 ihaka 437
/* Check to see if a list can be made into a vector. */
1858 ihaka 438
/* it must have every element being a vector of length 1. */
24599 ripley 439
/* BUT it does not exclude 0! */
1820 ihaka 440
 
11139 maechler 441
Rboolean isVectorizable(SEXP s)
2 r 442
{
24599 ripley 443
    if (isNull(s)) return TRUE;
1858 ihaka 444
    else if (isNewList(s)) {
445
	int i, n;
24599 ripley 446
 
1858 ihaka 447
	n = LENGTH(s);
24599 ripley 448
	for (i = 0 ; i < n; i++)
10172 luke 449
	    if (!isVector(VECTOR_ELT(s, i)) || LENGTH(VECTOR_ELT(s, i)) > 1)
11139 maechler 450
		return FALSE;
24599 ripley 451
	return TRUE;
1858 ihaka 452
    }
453
    else if (isList(s)) {
24599 ripley 454
	for ( ; s != R_NilValue; s = CDR(s))
455
	    if (!isVector(CAR(s)) || LENGTH(CAR(s)) > 1) return FALSE;
456
	return TRUE;
1858 ihaka 457
    }
11139 maechler 458
    else return FALSE;
1858 ihaka 459
}
2 r 460
 
1895 ihaka 461
 
1820 ihaka 462
/* Check to see if the arrays "x" and "y" have the identical extents */
463
 
11139 maechler 464
Rboolean conformable(SEXP x, SEXP y)
2 r 465
{
1820 ihaka 466
    int i, n;
467
    PROTECT(x = getAttrib(x, R_DimSymbol));
468
    y = getAttrib(y, R_DimSymbol);
469
    UNPROTECT(1);
470
    if ((n = length(x)) != length(y))
11139 maechler 471
	return FALSE;
1820 ihaka 472
    for (i = 0; i < n; i++)
473
	if (INTEGER(x)[i] != INTEGER(y)[i])
11139 maechler 474
	    return FALSE;
475
    return TRUE;
2 r 476
}
477
 
1820 ihaka 478
 
2 r 479
int nrows(SEXP s)
480
{
1820 ihaka 481
    SEXP t;
1839 ihaka 482
    if (isVector(s) || isList(s)) {
1820 ihaka 483
	t = getAttrib(s, R_DimSymbol);
1839 ihaka 484
	if (t == R_NilValue) return LENGTH(s);
1820 ihaka 485
	return INTEGER(t)[0];
486
    }
1839 ihaka 487
    else if (isFrame(s)) {
1820 ihaka 488
	return nrows(CAR(s));
489
    }
5731 ripley 490
    else error("object is not a matrix");
1820 ihaka 491
    return -1;
2 r 492
}
493
 
1820 ihaka 494
 
2 r 495
int ncols(SEXP s)
496
{
1820 ihaka 497
    SEXP t;
1839 ihaka 498
    if (isVector(s) || isList(s)) {
1820 ihaka 499
	t = getAttrib(s, R_DimSymbol);
1839 ihaka 500
	if (t == R_NilValue) return 1;
1820 ihaka 501
	return INTEGER(t)[1];
502
    }
1839 ihaka 503
    else if (isFrame(s)) {
1820 ihaka 504
	return length(s);
505
    }
5731 ripley 506
    else error("object is not a matrix");
1820 ihaka 507
    return -1;/*NOTREACHED*/
2 r 508
}
509
 
1820 ihaka 510
 
1054 maechler 511
int nlevels(SEXP f)
512
{
1839 ihaka 513
    if (!isFactor(f))
1820 ihaka 514
	return 0;
515
    return LENGTH(getAttrib(f, R_LevelsSymbol));
1054 maechler 516
}
517
 
1820 ihaka 518
/* Is an object of numeric type. */
18797 maechler 519
/* FIXME:  the LGLSXP case should be excluded here
520
 * (really? in many places we affirm they are treated like INTs)*/
1054 maechler 521
 
11139 maechler 522
Rboolean isNumeric(SEXP s)
2 r 523
{
1820 ihaka 524
    switch(TYPEOF(s)) {
18797 maechler 525
    case INTSXP:
526
	if (inherits(s,"factor")) return FALSE;
1820 ihaka 527
    case LGLSXP:
528
    case REALSXP:
11139 maechler 529
	return TRUE;
1820 ihaka 530
    default:
11139 maechler 531
	return FALSE;
1820 ihaka 532
    }
2 r 533
}
534
 
11139 maechler 535
Rboolean isString(SEXP s)
2 r 536
{
2810 maechler 537
    return (TYPEOF(s) == STRSXP);
2 r 538
}
539
 
1820 ihaka 540
 
11139 maechler 541
Rboolean isLogical(SEXP s)
2 r 542
{
1820 ihaka 543
    return (TYPEOF(s) == LGLSXP);
2 r 544
}
545
 
1820 ihaka 546
 
11139 maechler 547
Rboolean isInteger(SEXP s)
2 r 548
{
7081 pd 549
    return (TYPEOF(s) == INTSXP && !inherits(s, "factor"));
2 r 550
}
551
 
1820 ihaka 552
 
11139 maechler 553
Rboolean isReal(SEXP s)
2 r 554
{
1820 ihaka 555
    return (TYPEOF(s) == REALSXP);
2 r 556
}
557
 
1820 ihaka 558
 
11139 maechler 559
Rboolean isComplex(SEXP s)
2 r 560
{
1820 ihaka 561
    return (TYPEOF(s) == CPLXSXP);
2 r 562
}
563
 
1820 ihaka 564
 
11139 maechler 565
Rboolean isUnordered(SEXP s)
2 r 566
{
10714 maechler 567
    return (TYPEOF(s) == INTSXP
1820 ihaka 568
	    && inherits(s, "factor")
569
	    && !inherits(s, "ordered"));
2 r 570
}
571
 
1820 ihaka 572
 
11139 maechler 573
Rboolean isOrdered(SEXP s)
2 r 574
{
10714 maechler 575
    return (TYPEOF(s) == INTSXP
1820 ihaka 576
	    && inherits(s, "factor")
577
	    && inherits(s, "ordered"));
2 r 578
}
579
 
1820 ihaka 580
 
11139 maechler 581
Rboolean isFactor(SEXP s)
2 r 582
{
7081 pd 583
    return (TYPEOF(s) == INTSXP  && inherits(s, "factor"));
2 r 584
}
585
 
1820 ihaka 586
 
11139 maechler 587
Rboolean isObject(SEXP s)
2 r 588
{
11139 maechler 589
    return OBJECT(s);/* really `1-bit unsigned int' */
2 r 590
}
591
 
1820 ihaka 592
 
11139 maechler 593
Rboolean inherits(SEXP s, char *name)
2 r 594
{
1820 ihaka 595
    SEXP class;
596
    int i, nclass;
1839 ihaka 597
    if (isObject(s)) {
1820 ihaka 598
	class = getAttrib(s, R_ClassSymbol);
599
	nclass = length(class);
1839 ihaka 600
	for (i = 0; i < nclass; i++) {
10172 luke 601
	    if (!strcmp(CHAR(STRING_ELT(class, i)), name))
11139 maechler 602
		return TRUE;
2 r 603
	}
1820 ihaka 604
    }
11139 maechler 605
    return FALSE;
2 r 606
}
607
 
1820 ihaka 608
 
13997 duncan 609
const static struct {
610
    const char * const str;
611
    const int type;
2 r 612
}
613
TypeTable[] = {
2810 maechler 614
    { "NULL",		NILSXP	   },  /* real types */
615
    { "symbol",		SYMSXP	   },
1820 ihaka 616
    { "pairlist",	LISTSXP	   },
2810 maechler 617
    { "closure",	CLOSXP	   },
618
    { "environment",	ENVSXP	   },
619
    { "promise",	PROMSXP	   },
620
    { "language",	LANGSXP	   },
1820 ihaka 621
    { "special",	SPECIALSXP },
622
    { "builtin",	BUILTINSXP },
2810 maechler 623
    { "char",		CHARSXP	   },
624
    { "logical",	LGLSXP	   },
625
    { "integer",	INTSXP	   },
626
    { "double",		REALSXP	   }, /*-  "real", for R <= 0.61.x */
627
    { "complex",	CPLXSXP	   },
628
    { "character",	STRSXP	   },
629
    { "...",		DOTSXP	   },
630
    { "any",		ANYSXP	   },
631
    { "expression",	EXPRSXP	   },
1820 ihaka 632
    { "list",		VECSXP	   },
11390 luke 633
    { "externalptr",	EXTPTRSXP  },
24523 luke 634
#ifdef BYTECODE
635
    { "bytecode",	BCODESXP   },
636
#endif
15928 luke 637
    { "weakref",	WEAKREFSXP },
2810 maechler 638
    /* aliases : */
639
    { "numeric",	REALSXP	   },
1820 ihaka 640
    { "name",		SYMSXP	   },
2 r 641
 
2810 maechler 642
    { (char *)0,	-1	   }
2 r 643
};
644
 
645
 
646
SEXPTYPE str2type(char *s)
647
{
1820 ihaka 648
    int i;
1839 ihaka 649
    for (i = 0; TypeTable[i].str; i++) {
1820 ihaka 650
	if (!strcmp(s, TypeTable[i].str))
651
	    return TypeTable[i].type;
652
    }
1839 ihaka 653
    return -1;
2 r 654
}
655
 
1820 ihaka 656
 
2 r 657
SEXP type2str(SEXPTYPE t)
658
{
1820 ihaka 659
    int i;
2 r 660
 
1839 ihaka 661
    for (i = 0; TypeTable[i].str; i++) {
1820 ihaka 662
	if (TypeTable[i].type == t)
663
	    return mkChar(TypeTable[i].str);
664
    }
665
    UNIMPLEMENTED("type2str");
666
    return R_NilValue; /* for -Wall */
2 r 667
}
668
 
15459 jmc 669
SEXP type2symbol(SEXPTYPE t)
670
{
671
    int i;
672
    /* for efficiency, a hash table set up to index TypeTable, and
673
       with TypeTable pointing to both the
674
       character string and to the symbol would be better */
675
    for (i = 0; TypeTable[i].str; i++) {
676
	if (TypeTable[i].type == t)
15737 iacus 677
	    return install((char *)&TypeTable[i].str);
15459 jmc 678
    }
679
    UNIMPLEMENTED("type2str");
680
    return R_NilValue; /* for -Wall */
681
}
682
 
12256 pd 683
Rboolean isBlankString(char *s)
6622 maechler 684
{
685
    while (*s)
12256 pd 686
	if (!isspace((int)*s++)) return FALSE;
11139 maechler 687
    return TRUE;
6622 maechler 688
}
689
 
11139 maechler 690
Rboolean StringBlank(SEXP x)
1839 ihaka 691
{
11139 maechler 692
    if (x == R_NilValue) return TRUE;
1839 ihaka 693
    else return CHAR(x)[0] == '\0';
694
}
2 r 695
 
1820 ihaka 696
/* Function to test whether a string is a true value */
697
 
11139 maechler 698
Rboolean StringTrue(char *name)
2 r 699
{
1820 ihaka 700
    int i;
701
    for (i = 0; truenames[i]; i++)
702
	if (!strcmp(name, truenames[i]))
11139 maechler 703
	    return TRUE;
704
    return FALSE;
2 r 705
}
706
 
11139 maechler 707
Rboolean StringFalse(char *name)
2 r 708
{
1820 ihaka 709
    int i;
710
    for (i = 0; falsenames[i]; i++)
711
	if (!strcmp(name, falsenames[i]))
11139 maechler 712
	    return TRUE;
713
    return FALSE;
2 r 714
}
715
 
3279 pd 716
SEXP EnsureString(SEXP s)
717
{
718
    switch(TYPEOF(s)) {
719
    case SYMSXP:
720
	s = PRINTNAME(s);
721
	break;
722
    case STRSXP:
10172 luke 723
	s = STRING_ELT(s, 0);
3279 pd 724
	break;
725
    case CHARSXP:
726
	break;
727
    case NILSXP:
728
	s = R_BlankString;
729
	break;
730
    default:
5731 ripley 731
	error("invalid tag in name extraction");
3279 pd 732
    }
733
    return s;
734
}
1820 ihaka 735
 
3279 pd 736
 
2 r 737
void checkArity(SEXP op, SEXP args)
738
{
1820 ihaka 739
    if (PRIMARITY(op) >= 0 && PRIMARITY(op) != length(args))
5731 ripley 740
	error("%d argument%s passed to \"%s\" which requires %d.",
1820 ihaka 741
	      length(args), (length(args) == 1 ? "" : "s"),
742
	      PRIMNAME(op), PRIMARITY(op));
2 r 743
}
744
 
1820 ihaka 745
 
2 r 746
SEXP nthcdr(SEXP s, int n)
747
{
1820 ihaka 748
    if (isList(s) || isLanguage(s) || isFrame(s) || TYPEOF(s) == DOTSXP ) {
749
	while( n-- > 0 ) {
1839 ihaka 750
	    if (s == R_NilValue)
5731 ripley 751
		error("\"nthcdr\" list shorter than %d", n);
1820 ihaka 752
	    s = CDR(s);
2 r 753
	}
1820 ihaka 754
	return s;
755
    }
5731 ripley 756
    else error("\"nthcdr\" needs a list to CDR down");
1820 ihaka 757
    return R_NilValue;/* for -Wall */
2 r 758
}
759
 
1820 ihaka 760
 
2 r 761
SEXP do_nargs(SEXP call, SEXP op, SEXP args, SEXP rho)
762
{
1820 ihaka 763
    SEXP t;
10381 luke 764
    RCNTXT *cptr;
765
    int nargs = NA_INTEGER;
766
    for (cptr = R_GlobalContext; cptr != NULL; cptr = cptr->nextcontext) {
767
	if ((cptr->callflag & CTXT_FUNCTION) && cptr->cloenv == rho) {
768
	    nargs = length(cptr->promargs);
769
	    break;
770
	}
771
    }
1820 ihaka 772
    t = allocVector(INTSXP, 1);
10381 luke 773
    *INTEGER(t) = nargs;
1820 ihaka 774
    return (t);
2 r 775
}
776
 
1820 ihaka 777
 
2 r 778
void setIVector(int * vec, int len, int val)
779
{
1820 ihaka 780
    int i;
781
    for (i = 0; i < len; i++)
782
	vec[i] = val;
2 r 783
}
784
 
1820 ihaka 785
 
2 r 786
void setRVector(double * vec, int len, double val)
787
{
1820 ihaka 788
    int i;
789
    for (i = 0; i < len; i++)
790
	vec[i] = val;
2 r 791
}
792
 
1820 ihaka 793
 
2 r 794
void setSVector(SEXP * vec, int len, SEXP val)
795
{
1820 ihaka 796
    int i;
797
    for (i = 0; i < len; i++)
798
	vec[i] = val;
2 r 799
}
800
 
1820 ihaka 801
 
11139 maechler 802
Rboolean isFree(SEXP val)
2 r 803
{
1820 ihaka 804
    SEXP t;
805
    for (t = R_FreeSEXP; t != R_NilValue; t = CAR(t))
806
	if (val == t)
11139 maechler 807
	    return TRUE;
808
    return FALSE;
2 r 809
}
214 rgentlem 810
 
811
 
1820 ihaka 812
/* Debugging functions (hence the d-prefix). */
813
/* These are intended to be called interactively from */
814
/* a debugger such as gdb, so you don't have to remember */
815
/* the names of the data structure components. */
816
 
214 rgentlem 817
int dtype(SEXP q)
818
{
1820 ihaka 819
    return((int)TYPEOF(q));
214 rgentlem 820
}
821
 
1820 ihaka 822
 
214 rgentlem 823
SEXP dcar(SEXP l)
824
{
1820 ihaka 825
    return(CAR(l));
214 rgentlem 826
}
827
 
1820 ihaka 828
 
214 rgentlem 829
SEXP dcdr(SEXP l)
830
{
1820 ihaka 831
    return(CDR(l));
214 rgentlem 832
}
4747 hornik 833
 
14202 maechler 834
/* merge(xinds, yinds, all.x, all.y) */
12256 pd 835
SEXP do_merge(SEXP call, SEXP op, SEXP args, SEXP rho)
836
{
14549 maechler 837
    SEXP xi, yi, ansx, ansy, ans, ansnames, x_lone, y_lone;
838
    int y, nx = 0, ny = 0, i, j, k, nans = 0, nx_lone = 0, ny_lone = 0;
839
    int all_x = 0, all_y = 0, ll = 0/* "= 0" : for -Wall */;
12256 pd 840
 
841
    checkArity(op, args);
842
    xi = CAR(args);
843
    if ( !isInteger(xi) || !(nx = LENGTH(xi)) )
844
	error("invalid `xinds' argument");
845
    yi = CADR(args);
846
    if ( !isInteger(yi) || !(ny = LENGTH(yi)) )
847
	error("invalid `yinds' argument");
14202 maechler 848
    if(!LENGTH(ans = CADDR(args)) || NA_LOGICAL == (all_x = asLogical(ans)))
16182 ripley 849
	errorcall(call, "`all.x' must be TRUE or FALSE");
14202 maechler 850
    if(!LENGTH(ans = CADDDR(args))|| NA_LOGICAL == (all_y = asLogical(ans)))
851
	errorcall(call, "`all.y' must be TRUE or FALSE");
14549 maechler 852
    /* 1. determine result sizes */
16182 ripley 853
    if(all_x) {
14549 maechler 854
	for (i = 0; i < nx; i++)
855
	    if (INTEGER(xi)[i] == 0) nx_lone++;
856
    }
12256 pd 857
    for (j = 0; j < ny; j++)
14549 maechler 858
	if ((y = INTEGER(yi)[j]) > 0) {
12256 pd 859
	    for (i = 0; i < nx; i++) {
860
		if (INTEGER(xi)[i] == y) nans++;
861
	    }
14549 maechler 862
        } else /* y == 0 */ if (all_y) ny_lone++;
863
    /* 2. allocate and store result components */
864
    PROTECT(ans = allocVector(VECSXP, 4));
14202 maechler 865
    ansx = allocVector(INTSXP, nans);    SET_VECTOR_ELT(ans, 0, ansx);
866
    ansy = allocVector(INTSXP, nans);    SET_VECTOR_ELT(ans, 1, ansy);
16182 ripley 867
    if(all_x) {
868
	x_lone = allocVector(INTSXP, nx_lone);
14549 maechler 869
	SET_VECTOR_ELT(ans, 2, x_lone);
870
	ll = 0;
871
	for (i = 0; i < nx; i++)
872
	    if (INTEGER(xi)[i] == 0) INTEGER(x_lone)[ll++] = i + 1;
873
    }
16182 ripley 874
    if(all_y) {
875
	y_lone = allocVector(INTSXP, ny_lone);
14549 maechler 876
	SET_VECTOR_ELT(ans, 3, y_lone);
877
	ll = 0;
878
    } else
879
	y_lone = R_NilValue;
12256 pd 880
    for (j = 0, k = 0; j < ny; j++)
14549 maechler 881
	if ((y = INTEGER(yi)[j]) > 0) {
16182 ripley 882
	    for (i = 0; i < nx; i++)
12256 pd 883
		if (INTEGER(xi)[i] == y) {
884
		INTEGER(ansx)[k]   = i + 1;
885
		INTEGER(ansy)[k++] = j + 1;
886
	    }
14549 maechler 887
	} else /* y == 0 */ if (all_y) INTEGER(y_lone)[ll++] = j + 1;
888
 
889
    PROTECT(ansnames = allocVector(STRSXP, 4));
12256 pd 890
    SET_STRING_ELT(ansnames, 0, mkChar("xi"));
891
    SET_STRING_ELT(ansnames, 1, mkChar("yi"));
14549 maechler 892
    SET_STRING_ELT(ansnames, 2, mkChar("x.alone"));
893
    SET_STRING_ELT(ansnames, 3, mkChar("y.alone"));
12256 pd 894
    setAttrib(ans, R_NamesSymbol, ansnames);
895
    UNPROTECT(2);
896
    return ans;
897
}
898
 
899
 
4747 hornik 900
/* Functions for getting and setting the working directory. */
4894 ripley 901
#ifdef Win32
902
#include <windows.h>
903
#endif
4747 hornik 904
 
12256 pd 905
SEXP do_getwd(SEXP call, SEXP op, SEXP args, SEXP rho)
906
{
4747 hornik 907
    SEXP rval = R_NilValue;
26187 ripley 908
    char buf[2 * PATH_MAX];
4747 hornik 909
 
910
    checkArity(op, args);
4768 hornik 911
 
4766 hornik 912
#ifdef R_GETCWD
4768 hornik 913
    R_GETCWD(buf, PATH_MAX);
26183 ripley 914
#ifdef Win32
26187 ripley 915
    {
916
	char *p;
917
	for(p = buf; *p; p++) if(*p == '\\') *p = '/';
918
    }
26183 ripley 919
#endif
4747 hornik 920
    rval = mkString(buf);
921
#endif
922
    return(rval);
923
}
924
 
6994 pd 925
#if defined(Win32) && defined(_MSC_VER)
926
#include <direct.h> /* for chdir */
927
#endif
928
 
12256 pd 929
SEXP do_setwd(SEXP call, SEXP op, SEXP args, SEXP rho)
930
{
6994 pd 931
    SEXP s = R_NilValue;	/* -Wall */
4747 hornik 932
    const char *path;
933
 
934
    checkArity(op, args);
6098 pd 935
    if (!isPairList(args) || !isValidString(s = CAR(args)))
6191 maechler 936
	errorcall(call, "character argument expected");
10172 luke 937
    path = R_ExpandFileName(CHAR(STRING_ELT(s, 0)));
18817 ripley 938
#ifdef HAVE_CHDIR
4747 hornik 939
    if(chdir(path) < 0)
18817 ripley 940
#endif
6191 maechler 941
	errorcall(call, "cannot change working directory");
4747 hornik 942
    return(R_NilValue);
943
}
4894 ripley 944
 
945
/* remove portion of path before file separator if one exists */
12256 pd 946
 
947
SEXP do_basename(SEXP call, SEXP op, SEXP args, SEXP rho)
4894 ripley 948
{
21647 ripley 949
    SEXP ans, s = R_NilValue;	/* -Wall */
4894 ripley 950
    char  buf[PATH_MAX], *p, fsp = FILESEP[0];
21647 ripley 951
    int i, n;
4894 ripley 952
 
953
    checkArity(op, args);
21647 ripley 954
    if (TYPEOF(s = CAR(args)) != STRSXP)
955
	errorcall(call, "a character vector argument expected");
956
    PROTECT(ans = allocVector(STRSXP, n = LENGTH(s)));
957
    for(i = 0; i < n; i++) {
958
	p = R_ExpandFileName(CHAR(STRING_ELT(s, i)));
959
	if (strlen(p) > PATH_MAX - 1)
960
	    errorcall(call, "path too long");
961
	strcpy (buf, p);
4894 ripley 962
#ifdef Win32
21647 ripley 963
	for (p = buf; *p != '\0'; p++)
964
	    if (*p == '\\') *p = '/';
4894 ripley 965
#endif
21647 ripley 966
	/* remove trailing file separator(s) */
967
	while ( *(p = buf + strlen(buf) - 1) == fsp ) *p = '\0';
968
	if ((p = strrchr(buf, fsp)))
969
	    p++;
970
	else
971
	    p = buf;
972
	SET_STRING_ELT(ans, i, mkChar(p));
973
    }
974
    UNPROTECT(1);
975
    return(ans);
4894 ripley 976
}
977
 
978
/* remove portion of path after last file separator if one exists, else
6994 pd 979
   return "."
980
   */
12256 pd 981
 
982
SEXP do_dirname(SEXP call, SEXP op, SEXP args, SEXP rho)
4894 ripley 983
{
21647 ripley 984
    SEXP ans, s = R_NilValue;	/* -Wall */
4894 ripley 985
    char  buf[PATH_MAX], *p, fsp = FILESEP[0];
21647 ripley 986
    int i, n;
4894 ripley 987
 
988
    checkArity(op, args);
21647 ripley 989
    if (TYPEOF(s = CAR(args)) != STRSXP)
990
	errorcall(call, "a character vector argument expected");
991
    PROTECT(ans = allocVector(STRSXP, n = LENGTH(s)));
992
    for(i = 0; i < n; i++) {
21657 luke 993
	p = R_ExpandFileName(CHAR(STRING_ELT(s, i)));
21647 ripley 994
	if (strlen(p) > PATH_MAX - 1)
995
	    errorcall(call, "path too long");
996
	strcpy (buf, p);
4894 ripley 997
#ifdef Win32
21647 ripley 998
	for(p = buf; *p != '\0'; p++)
999
	    if(*p == '\\') *p = '/';
4894 ripley 1000
#endif
21647 ripley 1001
	/* remove trailing file separator(s) */
1002
	while ( *(p = buf + strlen(buf) - 1) == fsp  && p > buf
14280 ripley 1003
#ifdef Win32
21647 ripley 1004
		&& *(p-1) != ':'
14280 ripley 1005
#endif
21647 ripley 1006
	    ) *p = '\0';
1007
	p = strrchr(buf, fsp);
1008
	if(p == NULL)
1009
	    strcpy(buf, ".");
1010
	else {
1011
	    while(p > buf && *p == fsp
14280 ripley 1012
#ifdef Win32
21647 ripley 1013
		  && *(p-1) != ':'
14280 ripley 1014
#endif
21647 ripley 1015
		) --p;
1016
	    p[1] = '\0';
1017
	}
1018
	SET_STRING_ELT(ans, i, mkChar(buf));
14249 hornik 1019
    }
21647 ripley 1020
    UNPROTECT(1);    
1021
    return(ans);
4894 ripley 1022
}
16182 ripley 1023
 
1024
 
1025
 
1026
void F77_SYMBOL(rexitc)(char *msg, int *nchar)
1027
{
1028
    int nc = *nchar;
1029
    char buf[256];
1030
    if(nc > 255) {
1031
        warning("error message truncated to 255 chars");
1032
	nc = 255;
1033
    }
1034
    strncpy(buf, msg, nc);
1035
    buf[nc] = '\0';
1036
    error(buf);
1037
}
1038
 
1039
void F77_SYMBOL(rwarnc)(char *msg, int *nchar)
1040
{
1041
    int nc = *nchar;
1042
    char buf[256];
1043
    if(nc > 255) {
1044
        warning("warning message truncated to 255 chars");
1045
	nc = 255;
1046
    }
1047
    strncpy(buf, msg, nc);
1048
    buf[nc] = '\0';
1049
    warning(buf);
1050
}
27381 ripley 1051
 
1052
void F77_SYMBOL(rchkusr)(void)
1053
{
1054
    R_CheckUserInterrupt();
1055
}