From 7dca6209a26cef8a4095e3837921da561d35ff4a Mon Sep 17 00:00:00 2001 From: hrbrmstr Date: Sun, 24 Jan 2021 07:17:57 -0500 Subject: [PATCH] initial commit --- .Rbuildignore | 1 + DESCRIPTION | 12 +++--- LICENSE | 2 + LICENSE.md | 21 ++++++++++ NAMESPACE | 4 +- R/add-reg-glue.R | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ R/swiftr-package.R | 7 ++-- man/swiftr.Rd | 4 +- 8 files changed, 154 insertions(+), 14 deletions(-) create mode 100644 LICENSE create mode 100644 LICENSE.md create mode 100644 R/add-reg-glue.R diff --git a/.Rbuildignore b/.Rbuildignore index c9a5c92..19cdbd8 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -19,3 +19,4 @@ ^CRAN-RELEASE$ ^appveyor\.yml$ ^tools$ +^LICENSE\.md$ diff --git a/DESCRIPTION b/DESCRIPTION index 8b66d65..2676bb7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: swiftr Type: Package -Title: swiftr title goes here otherwise CRAN checks fail +Title: Seamless R and Swift Integration Version: 0.1.0 Date: 2021-01-24 Authors@R: c( @@ -8,17 +8,17 @@ Authors@R: c( comment = c(ORCID = "0000-0001-5670-2640")) ) Maintainer: Bob Rudis -Description: A good description goes here otherwise CRAN checks fail. +Description: eamless R and Swift Integration URL: https://git.rud.is/hrbrmstr/swiftr BugReports: https://git.rud.is/hrbrmstr/swiftr/issues Encoding: UTF-8 -License: AGPL +License: MIT + file LICENSE Suggests: covr, tinytest Depends: - R (>= 3.5.0) + R (>= 3.6.0) Imports: - httr, - jsonlite + rprojroot, + stringi Roxygen: list(markdown = TRUE) RoxygenNote: 7.1.1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f51d1b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,2 @@ +YEAR: 2021 +COPYRIGHT HOLDER: Bob Rudis diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..c2304a0 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2021 Bob Rudis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/NAMESPACE b/NAMESPACE index 5b4b9ae..47df11e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,4 +1,4 @@ # Generated by roxygen2: do not edit by hand -import(httr) -importFrom(jsonlite,fromJSON) +export(add_registration_glue) +import(rprojroot) diff --git a/R/add-reg-glue.R b/R/add-reg-glue.R new file mode 100644 index 0000000..5ce2498 --- /dev/null +++ b/R/add-reg-glue.R @@ -0,0 +1,117 @@ +auto_gen_note <- "// Generated by swiftr: do not edit by hand" + +preamble <- '#include +#include +#include +#include +' + +extern_template <- "extern SEXP %s(%s);" + +method_template <- ' {"%s", (DL_FUNC) &%s, %s},' + +postamble_template <- ' +static const R_CallMethodDef CallEntries[] = { +%s + {NULL, NULL, 0} +}; + +void R_init_daybreak(DllInfo *dll) { + R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); + R_useDynamicSymbols(dll, FALSE); +} +' + +populate_template <- function(src_dir, swift_src, glue_src) { + + wd <- getwd() + on.exit(setwd(wd)) + + setwd(src_dir) + + gsub( + "^import ", "", + grep("^import", readLines(file.path(src_dir, swift_src), warn=FALSE), value=TRUE) + ) -> imports + + if (length(imports) >= 1) { + imports <- sprintf("-framework %s", imports) + } + + system2( + command = Sys.which("swiftc"), + args = c( + "-I /Library/Frameworks/R.framework/Headers", + "-F/Library/Frameworks", + "-framework R", + imports, + "-print-ast", + sprintf("-import-objc-header %s", glue_src), + swift_src + ), + stdout = TRUE, + stderr = TRUE + ) -> ast + + func_lines <- which(grepl("@_cdec", ast)) + + funcs <- gsub('@_cdecl\\("|"\\)', "", ast[func_lines]) + sexp_cts <- stringi::stri_count_fixed(ast[func_lines+1], "SEXP")-1 + + paste0( + mapply(function(func, sexp_ct) { + sprintf(extern_template, func, paste0(rep("SEXP", sexp_ct), collapse = ", ")) + }, funcs, sexp_cts, SIMPLIFY = TRUE, USE.NAMES = FALSE), + collapse = "\n" + ) -> externs + + paste0( + mapply(function(func, sexp_ct) { + sprintf(method_template, func, func, sexp_ct) + }, funcs, sexp_cts, SIMPLIFY = TRUE, USE.NAMES = FALSE), + collapse = "\n" + ) -> methods + + paste( + auto_gen_note, + preamble, + externs, + sprintf(postamble_template, methods), + sep = "\n" + ) + +} + +init_file_auto_generated <- function(src_dir) { + + init_file <- file.path(src_dir, "init.c") + + if (file.exists(init_file)) { + grepl(sprintf("^%s", auto_gen_note), readLines(init_file)[1]) + } else { + TRUE + } + +} + +#' @export +add_registration_glue <- function(package = ".") { + + makevars <- rprojroot::find_package_root_file("src/Makevars") + + src_dir <- dirname(makevars) + + if (init_file_auto_generated(src_dir)) { + + swift_src <- list.files(src_dir, pattern = "swift$") + glue_src <- list.files(src_dir, pattern = "h$") + + tmpl <- populate_template(src_dir, swift_src, glue_src) + + writeLines(tmpl, file.path(src_dir, "init.c")) + + } else { + stop("init.c was not auto-generated. Aborting.") + } + +} diff --git a/R/swiftr-package.R b/R/swiftr-package.R index 55255b2..f10968f 100644 --- a/R/swiftr-package.R +++ b/R/swiftr-package.R @@ -1,9 +1,8 @@ -#' ... -#' +#' Seamless R and Swift Integration +#' #' @md #' @name swiftr #' @keywords internal #' @author Bob Rudis (bob@@rud.is) -#' @import httr -#' @importFrom jsonlite fromJSON +#' @import rprojroot stringi "_PACKAGE" diff --git a/man/swiftr.Rd b/man/swiftr.Rd index 70c4150..f85c6ad 100644 --- a/man/swiftr.Rd +++ b/man/swiftr.Rd @@ -4,9 +4,9 @@ \name{swiftr} \alias{swiftr} \alias{swiftr-package} -\title{...} +\title{Seamless R and Swift Integration} \description{ -A good description goes here otherwise CRAN checks fail. +eamless R and Swift Integration } \seealso{ Useful links: