Matrix r4655
Loading...
Searching...
No Matches
attrib.c
Go to the documentation of this file.
1#include "Mdefines.h"
2#include "attrib.h"
3
4/* .... Dimnames .................................................... */
5
7{
8 return
9 isNull(VECTOR_ELT(dn, 0)) &&
10 isNull(VECTOR_ELT(dn, 1)) &&
11 isNull(getAttrib(dn, R_NamesSymbol));
12}
13
15{
16 SEXP rn, cn, ndn;
17 const char *nrn, *ncn;
18 int n;
19
20 return
21 !((!isNull(rn = VECTOR_ELT(dn, 0)) &&
22 !isNull(cn = VECTOR_ELT(dn, 1)) &&
23 rn != cn &&
24 ((n = LENGTH(rn)) != LENGTH(cn) ||
25 !equal_character_vectors(rn, cn, n))) ||
26 ((!isNull(ndn = getAttrib(dn, R_NamesSymbol)) &&
27 *(nrn = CHAR(STRING_ELT(ndn, 0))) != '\0' &&
28 *(ncn = CHAR(STRING_ELT(ndn, 1))) != '\0' &&
29 strcmp(nrn, ncn) != 0)));
30}
31
33{
34 return ScalarLogical(DimNames_is_symmetric(dn));
35}
36
37void symDN(SEXP dest, SEXP src, int J /* -1|0|1 */)
38{
39 SEXP s;
40 if (J < 0) {
41 if (!isNull(s = VECTOR_ELT(src, J = 1)) ||
42 !isNull(s = VECTOR_ELT(src, J = 0))) {
43 SET_VECTOR_ELT(dest, 0, s);
44 SET_VECTOR_ELT(dest, 1, s);
45 } else {
46 J = 1;
47 }
48 } else {
49 if (!isNull(s = VECTOR_ELT(src, J))) {
50 SET_VECTOR_ELT(dest, 0, s);
51 SET_VECTOR_ELT(dest, 1, s);
52 }
53 }
54 PROTECT(s = getAttrib(src, R_NamesSymbol));
55 if (!isNull(s)) {
56 SEXP destnms = PROTECT(allocVector(STRSXP, 2));
57 if (*CHAR(s = STRING_ELT(s, J)) != '\0') {
58 SET_STRING_ELT(destnms, 0, s);
59 SET_STRING_ELT(destnms, 1, s);
60 }
61 setAttrib(dest, R_NamesSymbol, destnms);
62 UNPROTECT(1);
63 }
64 UNPROTECT(1);
65 return;
66}
67
68void revDN(SEXP dest, SEXP src) {
69 SEXP s;
70 if (!isNull(s = VECTOR_ELT(src, 0)))
71 SET_VECTOR_ELT(dest, 1, s);
72 if (!isNull(s = VECTOR_ELT(src, 1)))
73 SET_VECTOR_ELT(dest, 0, s);
74 PROTECT(s = getAttrib(src, R_NamesSymbol));
75 if (!isNull(s)) {
76 SEXP srcnms = s, destnms = PROTECT(allocVector(STRSXP, 2));
77 if (*CHAR(s = STRING_ELT(srcnms, 0)) != '\0')
78 SET_STRING_ELT(destnms, 1, s);
79 if (*CHAR(s = STRING_ELT(srcnms, 1)) != '\0')
80 SET_STRING_ELT(destnms, 0, s);
81 setAttrib(dest, R_NamesSymbol, destnms);
82 UNPROTECT(1);
83 }
84 UNPROTECT(1);
85 return;
86}
87
88SEXP R_symDN(SEXP dn)
89{
90 if (DimNames_is_trivial(dn))
91 return dn;
92 SEXP newdn = PROTECT(allocVector(VECSXP, 2));
93 symDN(newdn, dn, -1);
94 UNPROTECT(1);
95 return newdn;
96}
97
98SEXP R_revDN(SEXP dn)
99{
100 if (DimNames_is_trivial(dn))
101 return dn;
102 SEXP newdn = PROTECT(allocVector(VECSXP, 2));
103 revDN(newdn, dn);
104 UNPROTECT(1);
105 return newdn;
106}
107
108SEXP get_symmetrized_DimNames(SEXP obj, int J) {
109 SEXP dn = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym));
110 if (DimNames_is_trivial(dn)) {
111 UNPROTECT(1);
112 return dn;
113 }
114 SEXP newdn = PROTECT(allocVector(VECSXP, 2));
115 symDN(newdn, dn, J);
116 UNPROTECT(2);
117 return newdn;
118}
119
120SEXP get_reversed_DimNames(SEXP obj) {
121 SEXP dn = PROTECT(GET_SLOT(obj, Matrix_DimNamesSym));
122 if (DimNames_is_trivial(dn)) {
123 UNPROTECT(1);
124 return dn;
125 }
126 SEXP newdn = PROTECT(allocVector(VECSXP, 2));
127 revDN(newdn, dn);
128 UNPROTECT(2);
129 return newdn;
130}
131
132void set_symmetrized_DimNames(SEXP obj, SEXP dn, int J) {
133 if (!DimNames_is_trivial(dn)) {
134 SEXP newdn = PROTECT(allocVector(VECSXP, 2));
135 symDN(newdn, dn, J);
136 SET_SLOT(obj, Matrix_DimNamesSym, newdn);
137 UNPROTECT(1);
138 }
139 return;
140}
141
142void set_reversed_DimNames(SEXP obj, SEXP dn) {
143 if (!DimNames_is_trivial(dn)) {
144 SEXP newdn = PROTECT(allocVector(VECSXP, 2));
145 revDN(newdn, dn);
146 SET_SLOT(obj, Matrix_DimNamesSym, newdn);
147 UNPROTECT(1);
148 }
149 return;
150}
151
152
153/* .... factors ..................................................... */
154
155static
156int strmatch(const char *x, SEXP valid)
157{
158 int i, n = LENGTH(valid);
159 for (i = 0; i < n; ++i)
160 if (strcmp(x, CHAR(STRING_ELT(valid, i))) == 0)
161 return i;
162 return -1;
163}
164
165static
166SEXP append_to_named_list(SEXP x, const char *nm, SEXP val)
167{
168 PROTECT(val);
169 R_xlen_t n = XLENGTH(x);
170 SEXP y = PROTECT(allocVector(VECSXP, n + 1)),
171 ny = PROTECT(allocVector(STRSXP, n + 1)),
172 nval = PROTECT(mkChar(nm));
173 if (n > 0) {
174 SEXP nx = PROTECT(getAttrib(x, R_NamesSymbol));
175 R_xlen_t i;
176 for (i = 0; i < n; ++i) {
177 SET_VECTOR_ELT( y, i, VECTOR_ELT( x, i));
178 SET_STRING_ELT(ny, i, STRING_ELT(nx, i));
179 }
180 UNPROTECT(1);
181 }
182 SET_VECTOR_ELT( y, n, val);
183 SET_STRING_ELT(ny, n, nval);
184 setAttrib(y, R_NamesSymbol, ny);
185 UNPROTECT(4);
186 return y;
187}
188
189SEXP get_factor(SEXP obj, const char *nm)
190{
191 SEXP factors = PROTECT(GET_SLOT(obj, Matrix_factorsSym)), val = R_NilValue;
192 if (LENGTH(factors) > 0) {
193 SEXP valid = PROTECT(getAttrib(factors, R_NamesSymbol));
194 int i = strmatch(nm, valid);
195 if (i >= 0)
196 val = VECTOR_ELT(factors, i);
197 UNPROTECT(1);
198 }
199 UNPROTECT(1);
200 return val;
201}
202
203void set_factor(SEXP obj, const char *nm, SEXP val)
204{
205 PROTECT(val);
206 SEXP factors;
207 PROTECT_INDEX pid;
208 PROTECT_WITH_INDEX(factors = GET_SLOT(obj, Matrix_factorsSym), &pid);
209 if (LENGTH(factors) > 0) {
210 SEXP valid = PROTECT(getAttrib(factors, R_NamesSymbol));
211 int i = strmatch(nm, valid);
212 UNPROTECT(1);
213 if (i >= 0) {
214 SET_VECTOR_ELT(factors, i, val);
215 UNPROTECT(2);
216 return;
217 }
218 }
219 REPROTECT(factors = append_to_named_list(factors, nm, val), pid);
220 SET_SLOT(obj, Matrix_factorsSym, factors);
221 UNPROTECT(2);
222 return;
223}
224
225SEXP R_set_factor(SEXP obj, SEXP nm, SEXP val, SEXP warn)
226{
227 if (TYPEOF(nm) != STRSXP || LENGTH(nm) < 1 ||
228 (nm = STRING_ELT(nm, 0)) == NA_STRING)
229 error(_("invalid factor name"));
230 else if (TYPEOF(getAttrib(obj, Matrix_factorsSym)) == VECSXP)
231 set_factor(obj, CHAR(nm), val);
232 else if (asLogical(warn) != 0)
233 warning(_("attempt to set factor on %s without '%s' slot"),
234 "Matrix", "factors");
235 return val;
236}
#define _(String)
Definition Mdefines.h:44
#define SET_SLOT(x, what, value)
Definition Mdefines.h:86
#define GET_SLOT(x, what)
Definition Mdefines.h:85
SEXP Matrix_factorsSym
Definition Msymbols.h:12
SEXP Matrix_DimNamesSym
Definition Msymbols.h:2
SEXP R_symDN(SEXP dn)
Definition attrib.c:88
SEXP R_revDN(SEXP dn)
Definition attrib.c:98
void revDN(SEXP dest, SEXP src)
Definition attrib.c:68
SEXP get_symmetrized_DimNames(SEXP obj, int J)
Definition attrib.c:108
static SEXP append_to_named_list(SEXP x, const char *nm, SEXP val)
Definition attrib.c:166
int DimNames_is_symmetric(SEXP dn)
Definition attrib.c:14
SEXP R_DimNames_is_symmetric(SEXP dn)
Definition attrib.c:32
SEXP R_set_factor(SEXP obj, SEXP nm, SEXP val, SEXP warn)
Definition attrib.c:225
int DimNames_is_trivial(SEXP dn)
Definition attrib.c:6
void symDN(SEXP dest, SEXP src, int J)
Definition attrib.c:37
SEXP get_reversed_DimNames(SEXP obj)
Definition attrib.c:120
SEXP get_factor(SEXP obj, const char *nm)
Definition attrib.c:189
void set_factor(SEXP obj, const char *nm, SEXP val)
Definition attrib.c:203
void set_reversed_DimNames(SEXP obj, SEXP dn)
Definition attrib.c:142
static int strmatch(const char *x, SEXP valid)
Definition attrib.c:156
void set_symmetrized_DimNames(SEXP obj, SEXP dn, int J)
Definition attrib.c:132
static const char * valid[]
Definition bind.c:5
int equal_character_vectors(SEXP s1, SEXP s2, int n)
Definition utils.c:143