/* * R.app : a Cocoa front end to: "R A Computer Language for Statistical Data Analysis" * * R.app Copyright notes: * Copyright (C) 2004-5 The R Foundation * written by Stefano M. Iacus and Simon Urbanek * * * R Copyright notes: * Copyright (C) 1995-1996 Robert Gentleman and Ross Ihaka * Copyright (C) 1998-2001 The R Development Core Team * Copyright (C) 2002-2004 The R Foundation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * A copy of the GNU General Public License is available via WWW at * http://www.gnu.org/copyleft/gpl.html. You can also obtain it by * writing to the Free Software Foundation, Inc., 59 Temple Place, * Suite 330, Boston, MA 02111-1307 USA. * * Created by Simon Urbanek on Wed Dec 10 2003. * */ #import #include "Rinit.h" #include #include #include #include #import "REngine.h" #define RS_ParseVector(A,B,C) R_ParseVector(A,B,C,R_NilValue) /* we should move this to another callback at some point ... it's a bad, bad hack for now */ #define DO_RENG_EVAL_STATUS(S) #define DONE_RENG_EVAL_STATUS() /* this is also provided in RGUI.h, but we want to be independent */ #ifndef SLog #if 1 || defined DEBUG_RGUI && defined PLAIN_STDERR #define SLog(X,...) NSLog(X, ## __VA_ARGS__) #else #define SLog(X,...) #endif #endif static REngine* mainRengine=nil; // this flag causes some parts of the code to not use REngine if that would cause re-entrance // it is meant for the user-level code, not for REngine itself - such that the UI can react and display appropriate warnings BOOL preventReentrance = NO; @implementation REngine + (REngine*) mainEngine { if (mainRengine==nil) mainRengine=[[REngine alloc] init]; return mainRengine; } + (id ) mainHandler { return [mainRengine handler]; } + (id ) cocoaHandler { return [mainRengine cocoaHandler]; } - (id) init { return [self initWithHandler:nil]; } - (id) initWithHandler: (id ) hand { char *args[4]={ "R", "--no-save", "--gui=cocoa", 0 }; return [self initWithHandler: hand arguments: args]; } - (id) initWithHandler: (id ) hand arguments: (char**) args { int i=0; argc=0; while (args[argc]) argc++; argv = (char**) malloc(sizeof(char*) * (argc+1)); while (i) handler { return replHandler; } - (id ) cocoaHandler { return cocoaHandler; } - (void) setCocoaHandler: (id ) ch { cocoaHandler=ch; } - (void) setSaveAction: (NSString*) action { saveAction = action?action:@"ask"; } - (NSString*) saveAction { return saveAction; } - (void) disableRSignalHandlers: (BOOL) disable { setRSignalHandlers(disable?0:1); } - (void) begin { // FIXME: we should set a lock here [replHandler handleBusy:YES]; if (insideR) SLog(@"***********> REngine.begin: expected insideR to be 0, but it's %d", insideR); if (insideR < 0) insideR = 0; // this can happen insideR++; } - (void) end { // FIXME: we should release a lock here insideR--; if (insideR) SLog(@"***********> REngine.end: expected insideR to be 0, but it's %d", insideR); [replHandler handleBusy:NO]; } - (RSEXP*) parse: (NSString*) str { return [self parse: str withParts: 1]; } - (RSEXP*) parse: (NSString*) str withParts: (int) count { ParseStatus ps; SEXP pstr, cv; if (!active) return nil; RENGINE_BEGIN; PROTECT(cv=allocVector(STRSXP, 1)); SET_STRING_ELT(cv, 0, mkChar([str UTF8String])); pstr=RS_ParseVector(cv, count, &ps); UNPROTECT(1); RENGINE_END; //NSLog(@"parse status: %d, SEXP: %x, type: %d\n", ps, pstr, TYPEOF(pstr)); return pstr?[[RSEXP alloc] initWithSEXP: pstr]:nil; } - (RSEXP*) evaluateExpressions: (RSEXP*) expr { SEXP es=0; int er=0; int i=0,l; //NSLog(@"evaluateExpressions: %@", expr); if (!active) return nil; RENGINE_BEGIN; // if we have an entire expression list, evaluate its contents one-by-one and return only the last one if ([expr type]==EXPRSXP) { l=[expr length]; while (i