Changeset: 8bb048b3486b for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8bb048b3486b
Modified Files:
        monetdb5/extras/rapi/rapi.c
Branch: Oct2014
Log Message:

Rintegration and Windows?


Unterschiede (gekürzt von 321 auf 300 Zeilen):

diff --git a/monetdb5/extras/rapi/rapi.c b/monetdb5/extras/rapi/rapi.c
--- a/monetdb5/extras/rapi/rapi.c
+++ b/monetdb5/extras/rapi/rapi.c
@@ -37,7 +37,6 @@
 
 #include <Rembedded.h>
 #include <Rdefines.h>
-#include <Rinterface.h>
 #include <Rinternals.h>
 #include <R_ext/Parse.h>
 
@@ -155,6 +154,15 @@ void clearRErrConsole(void) {
        // Do nothing?
 }
 
+int RAPIinstalladdons(void);
+
+/* UNIX-like initialization */
+#ifndef Win32
+
+#define R_INTERFACE_PTRS 1
+#define CSTACK_DEFNS 1
+#include <Rinterface.h>
+
 static int RAPIinitialize(void) {
 
 #ifdef RIF_HAS_RSIGHAND
@@ -201,44 +209,9 @@ static int RAPIinitialize(void) {
 
        // big boy here
        setup_Rmainloop();
-       {
-               int evalErr;
-               ParseStatus status;
-               char rlibs[BUFSIZ];
-               char rapiinclude[BUFSIZ];
-               SEXP librisexp;
-               struct stat sb;
 
-               // r library folder, create if not exists
-               snprintf(rlibs, BUFSIZ, "%s%c%s", GDKgetenv("gdk_dbpath"), 
DIR_SEP,
-                               "rapi_packages");
-
-               if (stat(rlibs, &sb) != 0) {
-                       if (mkdir(rlibs, S_IRWXU) != 0) {
-                               return 4;
-                       }
-               }
-#ifdef _RAPI_DEBUG_
-               printf("# R libraries installed in %s\n",rlibs);
-#endif
-
-               PROTECT(librisexp = allocVector(STRSXP, 1));
-               SET_STRING_ELT(librisexp, 0, mkChar(rlibs));
-               Rf_defineVar(Rf_install(".rapi.libdir"), librisexp, 
R_GlobalEnv);
-               UNPROTECT(1);
-
-               // run rapi.R environment setup script
-               snprintf(rapiinclude, BUFSIZ, "source(\"%s\")",
-                               locate_file("rapi", ".R", 0));
-               R_tryEvalSilent(
-                               VECTOR_ELT(
-                                               
R_ParseVector(mkString(rapiinclude), 1, &status,
-                                                               R_NilValue), 
0), R_GlobalEnv, &evalErr);
-
-               // of course the script may contain errors as well
-               if (evalErr != FALSE) {
-                       return 5;
-               }
+       if (RAPIinstalladdons() != 0) {
+               return 3;
        }
        // patch R internals to disallow quit and system. Setting them to NULL 
produces an error.
        SET_INTERNAL(install("quit"), R_NilValue);
@@ -248,6 +221,246 @@ static int RAPIinitialize(void) {
        rapiInitialized++;
        return 0;
 }
+#else
+/* Completely different Windows initialization */
+/* Gratefully lifted from the JRI code by Simon Urbanek (LGPL)  */
+
+
+#define NONAMELESSUNION
+#include <windows.h>
+#include <winreg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* before we include RStatup.h we need to work around a bug in it for Win64:
+   it defines wrong R_size_t if R_SIZE_T_DEFINED is not set */
+#if defined(WIN64) && ! defined(R_SIZE_T_DEFINED)
+#include <stdint.h>
+#define R_size_t uintptr_t
+#define R_SIZE_T_DEFINED 1
+#endif
+
+#include "R_ext/RStartup.h"
+
+#ifndef WIN64
+/* according to fixed/config.h Windows has uintptr_t, my windows hasn't */
+#if !defined(HAVE_UINTPTR_T) && !defined(uintptr_t) && !defined(_STDINT_H)
+typedef unsigned uintptr_t;
+#endif
+#endif
+extern __declspec(dllimport) uintptr_t R_CStackLimit; /* C stack limit */
+extern __declspec(dllimport) uintptr_t R_CStackStart; /* Initial stack address 
*/
+
+/* for signal-handling code */
+/* #include "psignal.h" - it's not included, so just get SIGBREAK */
+#define        SIGBREAK 21     /* to readers pgrp upon background tty read */
+
+/* one way to allow user interrupts: called in ProcessEvents */
+#ifdef _MSC_VER
+__declspec(dllimport) int UserBreak;
+#else
+#ifndef WIN64
+#define UserBreak     (*_imp__UserBreak)
+#endif
+extern int UserBreak;
+#endif
+
+/* calls into the R DLL */
+extern char *getDLLVersion();
+extern void R_DefParams(Rstart);
+extern void R_SetParams(Rstart);
+extern void setup_term_ui(void);
+extern void ProcessEvents(void);
+extern void end_Rmainloop(void), R_ReplDLLinit(void);
+extern int R_ReplDLLdo1();
+extern void run_Rmainloop(void);
+
+void myCallBack()
+{
+    /* called during i/o, eval, graphics in ProcessEvents */
+}
+
+#ifndef YES
+#define YES    1
+#endif
+#ifndef NO
+#define NO    -1
+#endif
+#ifndef CANCEL
+#define CANCEL 0
+#endif
+
+int myYesNoCancel(char *s)
+{
+    char  ss[128];
+    unsigned char a[3];
+
+    sprintf(ss, "%s [y/n/c]: ", s);
+    Re_ReadConsole(ss, a, 3, 0);
+    switch (a[0]) {
+    case 'y':
+    case 'Y':
+       return YES;
+    case 'n':
+    case 'N':
+       return NO;
+    default:
+       return CANCEL;
+    }
+}
+
+static void my_onintr(int sig)
+{
+    UserBreak = 1;
+}
+
+static char Rversion[25], RUser[MAX_PATH], RHome[MAX_PATH];
+
+int RAPIinitialize(void)
+{
+    structRstart rp;
+    Rstart Rp = &rp;
+    char *p;
+    char rhb[MAX_PATH+10];
+    DWORD t, s = MAX_PATH;
+    HKEY k;
+    int cvl;
+
+    sprintf(Rversion, "%s.%s", R_MAJOR, R_MINOR);
+    cvl=strlen(R_MAJOR)+2;
+    if(strncmp(getDLLVersion(), Rversion, cvl) != 0) {
+        char msg[512];
+       sprintf(msg, "Error: R.DLL version does not match (DLL: %s, expecting: 
%s)\n", getDLLVersion(), Rversion);
+       fprintf(stderr, msg);
+       MessageBox(0, msg, "Version mismatch", MB_OK|MB_ICONERROR);
+       return -1;
+    }
+
+    R_DefParams(Rp);
+    if(getenv("R_HOME")) {
+       strcpy(RHome, getenv("R_HOME"));
+    } else { /* fetch R_HOME from the registry - try preferred architecture 
first */
+#ifdef WIN64
+      const char *pref_path = "SOFTWARE\\R-core\\R64";
+#else
+      const char *pref_path = "SOFTWARE\\R-core\\R32";
+#endif
+      if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE, pref_path, 0, KEY_QUERY_VALUE, &k) 
!= ERROR_SUCCESS ||
+          RegQueryValueEx(k, "InstallPath", 0, &t, (LPBYTE) RHome, &s) != 
ERROR_SUCCESS) &&
+         (RegOpenKeyEx(HKEY_CURRENT_USER, pref_path, 0, KEY_QUERY_VALUE, &k) 
!= ERROR_SUCCESS ||
+           RegQueryValueEx(k, "InstallPath", 0, &t, (LPBYTE) RHome, &s) != 
ERROR_SUCCESS) &&
+         (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\R-core\\R", 0, 
KEY_QUERY_VALUE, &k) != ERROR_SUCCESS ||
+          RegQueryValueEx(k, "InstallPath", 0, &t, (LPBYTE) RHome, &s) != 
ERROR_SUCCESS) &&
+         (RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\R-core\\R", 0, 
KEY_QUERY_VALUE, &k) != ERROR_SUCCESS ||
+           RegQueryValueEx(k, "InstallPath", 0, &t, (LPBYTE) RHome, &s) != 
ERROR_SUCCESS)) {
+       fprintf(stderr, "R_HOME must be set or R properly installed 
(\\Software\\R-core\\R\\InstallPath registry entry must exist).\n");
+       MessageBox(0, "R_HOME must be set or R properly installed 
(\\Software\\R-core\\R\\InstallPath registry entry must exist).\n", "Can't find 
R home", MB_OK|MB_ICONERROR);
+       return -2;
+      }
+      sprintf(rhb,"R_HOME=%s",RHome);
+      putenv(rhb);
+    }
+    /* on Win32 this should set R_Home (in R_SetParams) as well */
+    Rp->rhome = RHome;
+    /*
+     * try R_USER then HOME then working directory
+     */
+    if (getenv("R_USER")) {
+       strcpy(RUser, getenv("R_USER"));
+    } else if (getenv("HOME")) {
+       strcpy(RUser, getenv("HOME"));
+    } else if (getenv("HOMEDIR")) {
+       strcpy(RUser, getenv("HOMEDIR"));
+       strcat(RUser, getenv("HOMEPATH"));
+    } else
+       GetCurrentDirectory(MAX_PATH, RUser);
+    p = RUser + (strlen(RUser) - 1);
+    if (*p == '/' || *p == '\\') *p = '\0';
+    Rp->home = RUser;
+    Rp->ReadConsole = Re_ReadConsole;
+    Rp->WriteConsole = NULL;
+    Rp->WriteConsoleEx = Re_WriteConsoleEx;
+
+    Rp->Busy = Re_Busy;
+    Rp->ShowMessage = Re_ShowMessage;
+    Rp->YesNoCancel = myYesNoCancel;
+    Rp->CallBack = myCallBack;
+    Rp->CharacterMode = LinkDLL;
+
+    Rp->R_Quiet = FALSE;
+    Rp->R_Interactive = TRUE;
+    Rp->RestoreAction = SA_RESTORE;
+    Rp->SaveAction = SA_SAVEASK;
+    /* process common command line options */
+    R_common_command_line(&argc, argv, Rp);
+    /* what is left should be assigned to args */
+    R_set_command_line_arguments(argc, argv);
+
+    R_SetParams(Rp); /* so R_ShowMessage is set */
+    R_SizeFromEnv(Rp);
+    R_SetParams(Rp);
+
+    /* R_SetParams implicitly calls R_SetWin32 which sets the
+       stack start/limit which we need to override */
+    R_CStackLimit = (uintptr_t) -1;
+
+    FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
+
+    signal(SIGBREAK, my_onintr);
+    setup_term_ui();
+    setup_Rmainloop();
+
+    return RAPIinstalladdons();
+}
+
+void initRinside() {
+    /* disable stack checking, because threads will thow it off */
+    R_CStackLimit = (uintptr_t) -1;
+}
+
+#endif
+
+
+int RAPIinstalladdons(void) {
+       int evalErr;
+       ParseStatus status;
+       char rlibs[BUFSIZ];
+       char rapiinclude[BUFSIZ];
+       SEXP librisexp;
+       struct stat sb;
+
+       // r library folder, create if not exists
+       snprintf(rlibs, BUFSIZ, "%s%c%s", GDKgetenv("gdk_dbpath"), DIR_SEP,
+                       "rapi_packages");
+
+       if (stat(rlibs, &sb) != 0) {
+               if (mkdir(rlibs, S_IRWXU) != 0) {
+                       return 4;
+               }
+       }
+#ifdef _RAPI_DEBUG_
+       printf("# R libraries installed in %s\n",rlibs);
+#endif
+
+       PROTECT(librisexp = allocVector(STRSXP, 1));
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to