data-raw/make-callentries.R

library(tidyverse)

src_files <- list.files("src", "\\.c$", full.names = TRUE)
src_sources <- src_files %>% set_names() %>% map_chr(readr::read_file)

defs <- tibble(
  def = src_sources %>%
    str_extract_all(regex("SEXP pkd_c_[^\\)]+\\)\\s+", multiline = TRUE)) %>%
    unlist() %>%
    str_replace_all("\\s+", " ") %>%
    str_trim(),
  name = def %>% str_extract("pkd_c_[^\\(]+"),
  return_type = "SEXP",
  args = def %>%
    str_remove("SEXP pkd_c_[^\\(]+\\(") %>%
    str_remove("\\)$") %>%
    str_split("\\s*,\\s*") %>%
    map(~{if(identical(.x, "")) character(0) else .x}),
  n_args = map(args, length)
)

call_headers <- paste0(
  "extern ", defs$def, ";",
  collapse = "\n"
)
call_entries <- paste0(
  '  {"', defs$name, '", (DL_FUNC) &', defs$name, ', ', defs$n_args, "},",
  collapse = "\n"
)

header <- glue::glue('

/* generated by data-raw/make-callentries.R */
{call_headers}

static const R_CallMethodDef CallEntries[] = {{
  {call_entries}
  {{NULL, NULL, 0}}
}};
/* end generated by data-raw/make-callentries.R */
')

# rewrite relevant portion of init.c
init <- read_file("src/init.c")
pattern <- regex(
  "\n/\\* generated by data-raw/make-callentries\\.R \\*/.*?/\\* end generated by data-raw/make-callentries\\.R \\*/",
  multiline = TRUE,
  dotall = TRUE
)

stopifnot(str_detect(init, pattern))
init %>%
  str_replace(pattern, header) %>%
  write_file("src/init.c")
paleolimbot/pkd documentation built on Sept. 25, 2020, 12:58 a.m.