Skip to content

Commit 7e4bda7

Browse files
author
Pavel Marek
committed
Add strings test to testrffi
(cherry picked from commit 3bf81b1)
1 parent b30e0d3 commit 7e4bda7

File tree

4 files changed

+202
-0
lines changed

4 files changed

+202
-0
lines changed

com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <R_ext/Rdynload.h>
2727
#include "testrffi.h"
2828
#include "serialization.h"
29+
#include "strings.h"
2930
#include "rapi_helpers.h"
3031
#include "rffiwrappers.h"
3132

@@ -127,6 +128,10 @@ static const R_CallMethodDef CallEntries[] = {
127128
CALLDEF(testPRIMFUN, 2),
128129
CALLDEF(serialize, 1),
129130
CALLDEF(testInstallTrChar, 2),
131+
CALLDEF(replace_nth_str, 3),
132+
CALLDEF(nth_str, 2),
133+
CALLDEF(create_empty_str, 1),
134+
CALLDEF(str_tests, 0),
130135
#include "init_api.h"
131136
{NULL, NULL, 0}
132137
};
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 3 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 3 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 3 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
#include "strings.h"
25+
26+
/**
27+
* Replaces an n-th string in place from given character vector with `replacement`.
28+
* Is a wrapper for SET_STRING_ELT
29+
* @param n Index of the string to replace.
30+
* @param replacement Replacement for the string.
31+
* @returns New string vector with the replacement.
32+
*/
33+
SEXP replace_nth_str(SEXP str, SEXP n, SEXP replacement) {
34+
if (TYPEOF(str) != STRSXP || LENGTH(str) == 0) {
35+
error("`str` expected STRSXP type with length greater than zero");
36+
}
37+
if (TYPEOF(n) != INTSXP || LENGTH(n) != 1) {
38+
error("`n` expected integer of length 1");
39+
}
40+
if (TYPEOF(replacement) != STRSXP || LENGTH(replacement) != 1) {
41+
error("`replacement` expected STRSXP of length 1");
42+
}
43+
const char *replacement_char = CHAR(STRING_ELT(replacement, 0));
44+
int idx = INTEGER_ELT(n, 0);
45+
if (LENGTH(str) < idx) {
46+
error("Trying to replace a string outside of bounds");
47+
}
48+
for (int i = 0; i < LENGTH(str); i++) {
49+
if (i == idx) {
50+
SET_STRING_ELT(str, i, mkChar(replacement_char));
51+
}
52+
}
53+
return str;
54+
}
55+
56+
/**
57+
* A wrapper for STRING_ELT.
58+
*/
59+
SEXP nth_str(SEXP str, SEXP n) {
60+
int idx = INTEGER_ELT(n, 0);
61+
return ScalarString(STRING_ELT(str, idx));
62+
}
63+
64+
/**
65+
* Creates a native empty character vector. For the purpose of demonstration that we
66+
* can create a native character vector, and then modify it in R code.
67+
*/
68+
SEXP create_empty_str(SEXP n) {
69+
int n_int = INTEGER_ELT(n, 0);
70+
SEXP str = PROTECT(allocVector(STRSXP, n_int));
71+
for (int i = 0; i < n_int; i++) {
72+
SET_STRING_ELT(str, i, mkChar(""));
73+
}
74+
UNPROTECT(1);
75+
return str;
76+
}
77+
78+
/**
79+
* Runs all other native tests
80+
*/
81+
SEXP str_tests() {
82+
SEXP str = PROTECT(allocVector(STRSXP, 1));
83+
SEXP elem = mkChar("Hello");
84+
SET_STRING_ELT(str, 0, elem);
85+
SEXP elem_from_elt = STRING_ELT(str, 0);
86+
if (elem != elem_from_elt) {
87+
error("elem != elem_from_elt");
88+
}
89+
// TODO: Add some more tests?
90+
// ...
91+
92+
UNPROTECT(1);
93+
return R_NilValue;
94+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 3 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 3 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 3 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
#include <Rinternals.h>
24+
25+
SEXP replace_nth_str(SEXP str, SEXP n, SEXP replacement);
26+
SEXP nth_str(SEXP str, SEXP n);
27+
SEXP create_empty_str(SEXP n);
28+
SEXP str_tests();
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# This code is free software; you can redistribute it and/or modify it
5+
# under the terms of the GNU General Public License version 3 only, as
6+
# published by the Free Software Foundation.
7+
#
8+
# This code is distributed in the hope that it will be useful, but WITHOUT
9+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11+
# version 3 for more details (a copy is included in the LICENSE file that
12+
# accompanied this code).
13+
#
14+
# You should have received a copy of the GNU General Public License version
15+
# 3 along with this work; if not, write to the Free Software Foundation,
16+
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17+
#
18+
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19+
# or visit www.oracle.com if you need additional information or have any
20+
# questions.
21+
22+
library(testrffi)
23+
24+
# Replace n-th string from `str` character vector with `replacement`.
25+
# `n` is zero-based
26+
replace_nth_str <- function(str, i, replacement) {
27+
stopifnot(is.character(str) && length(str) > 0)
28+
stopifnot(is.integer(i) && length(i) == 1)
29+
stopifnot(is.character(replacement) && length(replacement) == 1)
30+
.Call("replace_nth_str", str, i, replacement)
31+
}
32+
33+
# Returns n-th element from `str`.
34+
nth_str <- function(str, i) {
35+
stopifnot(is.character(str) && length(str) > 0)
36+
stopifnot(is.integer(i) && length(i) == 1)
37+
.Call("nth_str", str, i)
38+
}
39+
40+
create_empty_str <- function(i) {
41+
stopifnot(is.integer(i) && length(i) == 1)
42+
.Call("create_empty_str", i)
43+
}
44+
45+
# Rest of the native tests
46+
run_all_native_tests <- function() {
47+
.Call("str_tests")
48+
}
49+
50+
s <- c("a", "b", "c")
51+
stopifnot(nth_str(s, 0L) == "a")
52+
stopifnot(nth_str(s, 1L) == "b")
53+
stopifnot(nth_str(s, 2L) == "c")
54+
55+
# Replace some elements of a character vector in place with wrapper functions.
56+
stopifnot( replace_nth_str(c("a", "b"), 0L, "foo") == c("foo", "b"))
57+
stopifnot( replace_nth_str(c("a", "b"), 1L, "foo") == c("a", "foo"))
58+
59+
s <- c("a", "b", "c")
60+
replace_nth_str(s, 0L, "X")
61+
stopifnot(s == c("X", "b", "c"))
62+
replace_nth_str(s, 2L, "Y")
63+
stopifnot(s == c("X", "b", "Y"))
64+
65+
# Create a vector in native and manipulate with it in R.
66+
s <- create_empty_str(3L)
67+
s[1] <- "X"
68+
stopifnot(s == c("X", "", ""))
69+
replace_nth_str(s, 1L, "Y")
70+
stopifnot(s == c("X", "Y", ""))
71+
s[3] <- "Z"
72+
stopifnot(s == c("X", "Y", "Z"))
73+
74+
# Run rest of the native tests
75+
run_all_native_tests()

0 commit comments

Comments
 (0)