1import sys
2import typing
3from rpy2.rinterface_lib import embedded
4from rpy2.rinterface_lib import callbacks
5from rpy2.rinterface_lib import openrlib
6
7ffi = openrlib.ffi
8
9# These constants are default values from R sources
10_DEFAULT_VSIZE = 67108864  # vector heap size
11_DEFAULT_NSIZE = 350000  # language heap size
12_DEFAULT_MAX_VSIZE = sys.maxsize  # max vector heap size
13_DEFAULT_MAX_NSIZE = 50000000  # max language heap size
14_DEFAULT_PPSIZE = 50000  # stack size
15_DEFAULT_C_STACK_LIMIT = -1
16
17
18def _initr_win32(
19        interactive: bool = True,
20        _want_setcallbacks: bool = True,
21        _c_stack_limit: int = _DEFAULT_C_STACK_LIMIT
22
23) -> typing.Optional[int]:
24    with openrlib.rlock:
25        if embedded.isinitialized():
26            return None
27
28        options_c = [ffi.new('char[]', o.encode('ASCII'))
29                     for o in embedded._options]
30        n_options = len(options_c)
31        n_options_c = ffi.cast('int', n_options)
32        status = openrlib.rlib.Rf_initEmbeddedR(n_options_c, options_c)
33        embedded._setinitialized()
34
35        embedded.rstart = ffi.new('Rstart')
36        rstart = embedded.rstart
37        rhome = openrlib.rlib.get_R_HOME()
38        rstart.rhome = rhome
39        rstart.home = openrlib.rlib.getRUser()
40        rstart.CharacterMode = openrlib.rlib.LinkDLL
41        if _want_setcallbacks:
42            rstart.ReadConsole = callbacks._consoleread
43            rstart.WriteConsoleEx = callbacks._consolewrite_ex
44            rstart.CallBack = callbacks._callback
45            rstart.ShowMessage = callbacks._showmessage
46            rstart.YesNoCancel = callbacks._yesnocancel
47            rstart.Busy = callbacks._busy
48
49        rstart.R_Quiet = True
50        rstart.R_Interactive = interactive
51        rstart.RestoreAction = openrlib.rlib.SA_RESTORE
52        rstart.SaveAction = openrlib.rlib.SA_NOSAVE
53
54        rstart.vsize = ffi.cast('size_t', _DEFAULT_VSIZE)
55        rstart.nsize = ffi.cast('size_t', _DEFAULT_NSIZE)
56        rstart.max_vsize = ffi.cast('size_t', _DEFAULT_MAX_VSIZE)
57        rstart.max_nsize = ffi.cast('size_t', _DEFAULT_MAX_NSIZE)
58        rstart.ppsize = ffi.cast('size_t', _DEFAULT_PPSIZE)
59
60        openrlib.rlib.R_SetParams(rstart)
61
62        # TODO: still needed ?
63        openrlib.rlib.R_CStackLimit = ffi.cast('uintptr_t', _c_stack_limit)
64
65        return status
66