The R Project SVN R

Rev

Rev 5731 | Rev 6195 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5731 Rev 6098
Line 1... Line 1...
1
/*
1
/*
2
 *  R : A Computer Langage for Statistical Data Analysis
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  Copyright (C) 1995  Robert Gentleman and Ross Ihaka
3
 *  Copyright (C) 1995-1996 Robert Gentleman and Ross Ihaka
4
 *  Copyright (C) 1997  The R Core Team
4
 *  Copyright (C) 1997-1999 The R Development Core Team
5
 *
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
9
 *  (at your option) any later version.
Line 48... Line 48...
48
 *
48
 *
49
 *
49
 *
50
 *  2. The dlopen interface is not available.
50
 *  2. The dlopen interface is not available.
51
 *
51
 *
52
 *  In this case we use the table "CFunTabEntry" to locate functions
52
 *  In this case we use the table "CFunTabEntry" to locate functions
53
 *  in the executable.  We do this by straight linear search through
53
 *  in the executable.	We do this by straight linear search through
54
 *  the table.  Note that the content of the table is created at
54
 *  the table.	Note that the content of the table is created at
55
 *  system build time from the list in ../appl/ROUTINES.
55
 *  system build time from the list in ../appl/ROUTINES.
56
 */
56
 */
57
 
57
 
58
#ifdef HAVE_CONFIG_H
58
#ifdef HAVE_CONFIG_H
59
#include <Rconfig.h>
59
#include <Rconfig.h>
Line 68... Line 68...
68
 
68
 
69
typedef int (*DL_FUNC) ();
69
typedef int (*DL_FUNC) ();
70
typedef struct {
70
typedef struct {
71
    char *name;
71
    char *name;
72
    DL_FUNC func;
72
    DL_FUNC func;
73
}     CFunTabEntry;
73
} CFunTabEntry;
74
 
74
 
75
#include "FFDecl.h"
75
#include "FFDecl.h"
76
#include "FFDecl.h"
-
 
77
 
76
 
78
        /* This provides a table of built-in C and Fortran functions */
77
/* This provides a table of built-in C and Fortran functions.
79
        /* We include this table, even when we have dlopen and friends */
78
   We include this table, even when we have dlopen and friends.
80
        /* This is so that the functions are actually loaded at link time */
79
   This is so that the functions are actually loaded at link time. */
81
 
80
 
82
static CFunTabEntry CFunTab[] =
81
static CFunTabEntry CFunTab[] =
83
{
82
{
84
#include "FFTab.h"
83
#include "FFTab.h"
85
    {NULL, NULL}
84
    {NULL, NULL}
Line 94... Line 93...
94
#define MAX_NUM_DLLS    30
93
#define MAX_NUM_DLLS    30
95
 
94
 
96
static int CountDLL = 0;
95
static int CountDLL = 0;
97
 
96
 
98
static struct {
97
static struct {
99
    char  path[MAX_PATH + 1];
98
    char  *path;
-
 
99
    char  *name;
100
    HINSTANCE dlh;
100
    HINSTANCE dlh;
101
}
101
}
102
 
102
 
103
LoadedDLL[MAX_NUM_DLLS];
103
LoadedDLL[MAX_NUM_DLLS];
104
 
104
 
105
        /* Remove the specified DLL from the current DLL list */
105
	/* Remove the specified DLL from the current DLL list */
106
        /* Returns 1 if the DLL was found and removed from */
106
	/* Returns 1 if the DLL was found and removed from */
107
        /* the list and returns 0 otherwise. */
107
	/* the list and returns 0 otherwise. */
108
 
108
 
109
static int DeleteDLL(char *path)
109
static int DeleteDLL(char *path)
110
{
110
{
111
    int   i, loc;
111
    int   i, loc;
112
 
112
 
Line 116... Line 116...
116
	    goto found;
116
	    goto found;
117
	}
117
	}
118
    }
118
    }
119
    return 0;
119
    return 0;
120
found:
120
found:
-
 
121
    free(LoadedDLL[i].name);
-
 
122
    free(LoadedDLL[i].path);
121
    FreeLibrary(LoadedDLL[i].dlh);
123
    FreeLibrary(LoadedDLL[i].dlh);
122
    for (i = loc + 1; i < CountDLL; i++) {
124
    for (i = loc + 1; i < CountDLL; i++) {
123
	strcpy(LoadedDLL[i - 1].path, LoadedDLL[i].path);
125
	LoadedDLL[i - 1].path = LoadedDLL[i].path;
-
 
126
	LoadedDLL[i - 1].name = LoadedDLL[i].name;
124
	LoadedDLL[i - 1].dlh = LoadedDLL[i].dlh;
127
	LoadedDLL[i - 1].dlh = LoadedDLL[i].dlh;
125
    }
128
    }
126
    CountDLL--;
129
    CountDLL--;
127
    return 1;
130
    return 1;
128
}
131
}
Line 136... Line 139...
136
        /* All the other entries are "moved down" by one. */
139
        /* All the other entries are "moved down" by one. */
137
        /* Returns 1 if the library was successfully added */
140
        /* Returns 1 if the library was successfully added */
138
        /* and returns 0 if there library table is full or */
141
        /* and returns 0 if there library table is full or */
139
        /* or if LoadLibrary fails for some reason. */
142
        /* or if LoadLibrary fails for some reason. */
140
 
143
 
-
 
144
/*
-
 
145
  The arguments asLocal and now are unused in this version.
-
 
146
  They are here for consistency with the UNIX code.
-
 
147
 */
141
static int AddDLL(char *path)
148
static int AddDLL(char *path, int asLocal, int now)
142
{
149
{
143
    HINSTANCE tdlh;
150
    HINSTANCE tdlh;
-
 
151
    char *dpath, *name, DLLname[MAX_PATH], *p, *st;
-
 
152
    /* int i; */
144
 
153
 
-
 
154
    DeleteDLL(path);
145
    if (CountDLL == MAX_NUM_DLLS) {
155
    if (CountDLL == MAX_NUM_DLLS) {
146
	strcpy(DLLerror, "Maximal number of DLLs reached...");
156
	strcpy(DLLerror, "Maximal number of DLLs reached...");
147
	return 0;
157
	return 0;
148
    }
158
    }
149
    tdlh = LoadLibrary(path);
159
    tdlh = LoadLibrary(path);
150
    if (tdlh == NULL) {
160
    if (tdlh == NULL) {
151
	strcpy(DLLerror, "LoadLibrary failure");
161
	strcpy(DLLerror, "LoadLibrary failure");
152
	return 0;
162
	return 0;
153
    }
163
    }
-
 
164
 
-
 
165
    dpath = malloc(strlen(path)+1);
-
 
166
    if(dpath == NULL) {
-
 
167
	strcpy(DLLerror,"Couldn't allocate space for 'path'");
-
 
168
	FreeLibrary(tdlh);	
-
 
169
	return 0;
-
 
170
    }
-
 
171
    strcpy(dpath, path);
-
 
172
 
-
 
173
    strcpy(DLLname, path);
-
 
174
    for(p = DLLname; *p != '\0'; p++) if(*p == '\\') *p = '/';
-
 
175
    p = strrchr(path, '/'); 
-
 
176
    if(!p) p = DLLname; else p++;
-
 
177
    st = strchr(p, '.');
-
 
178
    if(st) *st = '\0';
-
 
179
    name = malloc(strlen(p)+1);
-
 
180
    if(name == NULL) {
-
 
181
	strcpy(DLLerror,"Couldn't allocate space for 'name'");
-
 
182
	FreeLibrary(tdlh);
-
 
183
	free(dpath);
-
 
184
	return 0;
-
 
185
    }
-
 
186
    strcpy(name, p);
-
 
187
 
154
    strcpy(LoadedDLL[CountDLL].path, path);
188
    LoadedDLL[CountDLL].path = dpath;
-
 
189
    LoadedDLL[CountDLL].name = name;
155
    LoadedDLL[CountDLL].dlh = tdlh;
190
    LoadedDLL[CountDLL].dlh = tdlh;
156
    CountDLL++;
191
    CountDLL++;
157
    return 1;
192
    return 1;
158
}
193
}
159
 
194
 
160
 
195
 
161
        /* R_FindSymbol checks whether one of the libraries */
196
        /* R_FindSymbol checks whether one of the libraries */
162
        /* that have been loaded contains the symbol name and */
197
        /* that have been loaded contains the symbol name and */
163
        /* returns a pointer to that symbol upon success. */
198
        /* returns a pointer to that symbol upon success. */
164
 
199
 
165
DL_FUNC R_FindSymbol(char const *name)
200
DL_FUNC R_FindSymbol(char const *name, char const *pkg)
166
{
201
{
167
    char  buf[MAXIDSIZE + 1];
-
 
168
    DL_FUNC fcnptr;
202
    DL_FUNC fcnptr;
169
    int   i, j;
203
    int   i, j, all=(strlen(pkg) == 0), doit;
170
    static int NumStatic = 0;
204
    static int NumStatic = 0;
171
    int   mid, high, low, cmp;
205
    int   mid, high, low, cmp;
172
 
206
 
173
#ifdef HAVE_NO_SYMBOL_UNDERSCORE
-
 
174
    sprintf(buf, "%s", name);
207
    /* Rprintf("name = %s pkg = %s\n", name, pkg); */
175
#else
208
 
176
    sprintf(buf, "_%s", name);
-
 
177
#endif
-
 
178
    sprintf(buf, "%s", name);
-
 
179
    for (i = CountDLL - 1; i >= 0; i--) {
209
    for (i = CountDLL - 1; i >= 0; i--) {
-
 
210
	doit = all;
180
	fcnptr = (DL_FUNC) GetProcAddress(LoadedDLL[i].dlh, buf);
211
	if(!doit && !strcmp(pkg, LoadedDLL[i].name)) doit = 2;
181
	if (fcnptr != NULL)
212
	if(doit) {	    
-
 
213
	    /* Rprintf("name = %s\n", LoadedDLL[i].name); */
-
 
214
	    fcnptr = (DL_FUNC) GetProcAddress(LoadedDLL[i].dlh, name);
182
	    return fcnptr;
215
	    if (fcnptr != (DL_FUNC)0) return fcnptr;
-
 
216
	}
-
 
217
	if(doit > 1) return (DL_FUNC)0;/* Only look in the first-matching DLL*/
183
    }
218
    }
184
    if (!NumStatic) {
219
    if (!NumStatic && (all || !strcmp(pkg, "base"))) {
185
	char *tname;
220
	char *tname;
186
	DL_FUNC tfunc;
221
	DL_FUNC tfunc;
187
 
222
 
188
	NumStatic = (sizeof(CFunTab) / sizeof(CFunTabEntry)) - 1;
223
	NumStatic = (sizeof(CFunTab) / sizeof(CFunTabEntry)) - 1;
189
	for (i = 0; i < NumStatic; i++)
224
	for (i = 0; i < NumStatic; i++)
Line 230... Line 265...
230
	strcpy(buf, path);
265
	strcpy(buf, path);
231
}
266
}
232
 
267
 
233
        /* do_dynload implements the R-Interface for the */
268
        /* do_dynload implements the R-Interface for the */
234
        /* loading of shared libraries */
269
        /* loading of shared libraries */
-
 
270
/* This looks very close the version in unix.
-
 
271
   Is the only reason it is not shared due to 
-
 
272
    a) 2*PATH_MAX v's PATH_MAX for sizeof(buf)
-
 
273
    b) static routines in this file.
235
 
274
*/
236
SEXP do_dynload(SEXP call, SEXP op, SEXP args, SEXP env)
275
SEXP do_dynload(SEXP call, SEXP op, SEXP args, SEXP env)
237
{
276
{
238
    char  buf[MAX_PATH];
277
    char  buf[MAX_PATH];
239
 
278
 
240
    checkArity(op, args);
279
    checkArity(op, args);
241
    if (!isString(CAR(args)) || length(CAR(args)) != 1)
280
    if (!isString(CAR(args)) || length(CAR(args)) != 1)
242
	errorcall(call, "character argument expected");
281
	errorcall(call, "character argument expected");
243
    GetFullDLLPath(call, buf, CHAR(STRING(CAR(args))[0]));
282
    GetFullDLLPath(call, buf, CHAR(STRING(CAR(args))[0]));
244
    DeleteDLL(buf);
283
    DeleteDLL(buf);
245
    if (!AddDLL(buf))
284
    if (!AddDLL(buf,LOGICAL(CADR(args))[0],LOGICAL(CADDR(args))[0]))
246
	errorcall(call, "unable to load shared library \"%s\":\n  %s",
285
	errorcall(call, "unable to load shared library \"%s\":\n  %s\n",
247
		  buf, DLLerror);
286
		  buf, DLLerror);
248
    return R_NilValue;
287
    return R_NilValue;
249
}
288
}
250
 
289
 
251
SEXP do_dynunload(SEXP call, SEXP op, SEXP args, SEXP env)
290
SEXP do_dynunload(SEXP call, SEXP op, SEXP args, SEXP env)