/[ascend]/trunk/base/generic/compiler/importhandler.c
ViewVC logotype

Contents of /trunk/base/generic/compiler/importhandler.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 900 - (show annotations) (download) (as text)
Wed Oct 25 06:03:04 2006 UTC (13 years, 11 months ago) by johnpye
File MIME type: text/x-csrc
File size: 12845 byte(s)
The 'sim' object is correctly accessible from script methods now, even if run during on_load.
Added 'getSimulation' to registry.cpp, added 'runDefaultMethod' to Simulation, added 'getMethod' to Type.
Running of 'on_load' is instigated at the Python level now, so that relevent python variables are set at simulations are built, etc. This appears to have cause some changes to the way the solver behaves, possibly.
Added SearchProcList to exports in libascend.

1 /* ASCEND modelling environment
2 Copyright (C) 2006 Carnegie Mellon University
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18 *//**
19 @file
20 Handle the Import Handler library, which is a hash table of additional
21 handlers for external scripts in the IMPORT statement.
22 *//*
23 by John Pye
24 Created Sept 26, 2006
25 */
26
27 #include <utilities/ascConfig.h>
28 #include <utilities/config.h>
29 #include <utilities/error.h>
30 #include <utilities/ascDynaLoad.h>
31 #include <utilities/ascPanic.h>
32 #include <utilities/ascEnvVar.h>
33 #include <general/table.h>
34 #include "importhandler.h"
35
36 /*
37 Maximum number of importhandlers possible in one session. Hard to imagine
38 that you would want more than this.
39 */
40 #define IMPORTHANDLER_MAX 10
41
42 /**
43 List of import handlers currently in effect. @TODO this shouldn't be a global,
44 but unfortunately such globals are 'The ASCEND Way'.
45 */
46 struct ImportHandler **importhandler_library=NULL;
47
48 /**
49 Table of registered pointers for use in passing GUI data out to external scripts.
50 */
51 struct Table *importhandler_sharedpointers=NULL;
52
53 ASC_DLLSPEC(int) importhandler_add(struct ImportHandler *handler){
54 int i;
55 if(handler==NULL){
56 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Handler is NULL");
57 return 2;
58 }
59 if(importhandler_library == NULL){
60 importhandler_createlibrary();
61 }
62 for(i=0; i< IMPORTHANDLER_MAX; ++i){
63 if(importhandler_library[i] == NULL)break;
64 if(importhandler_library[i]->name == handler->name){
65 ERROR_REPORTER_HERE(ASC_PROG_NOTE,"Handler already loaded");
66 return 0;
67 }
68 }
69 if(i==IMPORTHANDLER_MAX){
70 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Too many import handlers register (IMPORTHANDLER_MAX=%d)",IMPORTHANDLER_MAX);
71 return 1;
72 }
73 importhandler_library[i] = handler;
74 ERROR_REPORTER_HERE(ASC_PROG_NOTE,"New import hander '%s' added",handler->name);
75 return 0;
76 }
77
78 /* Function to attempt import of an external script
79 @param partialname Name of the external script (without extension), relative to PATH.
80 @param defaultpath Default value of file search PATH. Is trumped by value of pathenvvar if present in environment.
81 @param pathenvvar Environment variable containing the user's preferred file search path value.
82 @return 0 on success
83 */
84 int importhandler_attemptimport(const char *partialname,const char *defaultpath, const char *pathenvvar){
85 ERROR_REPORTER_HERE(ASC_PROG_ERR,"%s not implemented",__FUNCTION__);
86 return 1;
87 }
88
89 /*------------------------------------------------------------------------------
90 DEFAULT IMPORT HANDLER FOR DLL/SO FILES
91 */
92
93 /**
94 Create a filename for an external library (DLL/SO) based on a
95 partial filename.
96
97 @param partialname The partial filename (eg 'mylib')
98 @return Complete filename (eg 'libmylib.so' or 'mylib.dlll', etc)
99 */
100 char *importhandler_extlib_filename(const char *partialname){
101 char *buffer;
102 buffer = ASC_NEW_ARRAY(char,PATH_MAX);
103
104 #if defined(ASC_SHLIBSUFFIX) && defined(ASC_SHLIBPREFIX)
105 /*
106 this is the preferred operation: SCons reports what the local system
107 uses as its shared library file extension.
108 */
109 snprintf(buffer,PATH_MAX,"%s%s%s",ASC_SHLIBPREFIX,s1,ASC_SHLIBSUFFIX);
110 #else
111 /**
112 @DEPRECATED
113
114 If we don't have ASC_SHLIB-SUFFIX and -PREFIX then we can do some
115 system-specific stuff here, but it's not as general.
116 */
117 # ifdef __WIN32__
118 snprintf(buffer,PATH_MAX,"%s.dll",partialname);
119 # elif defined(linux)
120 snprintf(buffer,PATH_MAX,"lib%s.so",partialname); /* changed from .o to .so -- JP */
121 # elif defined(sun) || defined(solaris)
122 snprintf(buffer,PATH_MAX,"%s.so.1.0",partialname);
123 # elif defined(__hpux)
124 snprintf(buffer,PATH_MAX,"%s.sl",partialname);
125 # elif defined(_SGI_SOURCE)
126 snprintf(buffer,PATH_MAX,"%s.so",partialname);
127 # else
128 # error "Unknown system type (please define ASC_SHLIBSUFFIX and ASC_SHLIBPREFIX)"
129 # endif
130 #endif
131
132 return buffer;
133 }
134
135 /**
136 Perform the actual importing of an external DLL/SO in to ASCEND. Can assume
137 that the file exists and is readable.
138
139 @param fp Location of DLL/SO file
140 @param initfunc Name of registration function, preferably NULL (so that ASCEND automatically determines it)
141 @param partialpath as specified in 'IMPORT' statement, for creation of auto_initfunc name
142 @return 0 on success
143 */
144 int importhandler_extlib_import(const struct FilePath *fp,const char *initfunc,const char *partialpath){
145
146 struct FilePath *fp1;
147 char *stem;
148 char *path;
149 char auto_initfunc[PATH_MAX];
150 int result;
151
152 path = ospath_str(fp);
153 if(path==NULL){
154 ERROR_REPORTER_HERE(ASC_PROG_ERR,"File path is NULL");
155 return 1;
156 }
157
158 if(initfunc==NULL){
159 fp1 = ospath_new(partialpath);
160 stem = ospath_getbasefilename(fp1);
161 strncpy(auto_initfunc,stem,PATH_MAX);
162 ospath_free(fp1);
163 ASC_FREE(stem);
164
165 strncat(auto_initfunc,"_register",PATH_MAX-strlen(auto_initfunc));
166 /* CONSOLE_DEBUG("Created auto-initfunc name '%s'",auto_initfunc); */
167 result = Asc_DynamicLoad(path,auto_initfunc);
168 }else{
169 result = Asc_DynamicLoad(path,initfunc);
170 }
171
172 if(result){
173 CONSOLE_DEBUG("FAILED TO IMPORT '%s' (error %d)",partialpath,result);
174 }else{
175 if(initfunc==NULL){
176 CONSOLE_DEBUG("Successfully ran '%s' (automatically named) from dynamic package '%s'",auto_initfunc,path);
177 }else{
178 CONSOLE_DEBUG("Successfully ran '%s' from dynamic package '%s'",initfunc,path);
179 }
180 }
181
182 ASC_FREE(path);
183 return result;
184 }
185
186 /*------------------------------------------------------------------------------
187 LIST-BASED FUNCTIONS related to IMPORT handler 'library'
188 */
189
190 int importhandler_createlibrary(){
191 int i;
192 struct ImportHandler *extlib_handler;
193
194 if(importhandler_library!=NULL){
195 /* ERROR_REPORTER_HERE(ASC_PROG_ERR,"Already created"); */
196 return 0;
197 };
198 importhandler_library=ASC_NEW_ARRAY(struct ImportHandler *,IMPORTHANDLER_MAX);
199 for(i=0; i < IMPORTHANDLER_MAX; ++i){
200 importhandler_library[i] = NULL;
201 }
202 /* CONSOLE_DEBUG("ImportHandler library created"); */
203
204 extlib_handler = ASC_NEW(struct ImportHandler);
205 extlib_handler->name ="extlib";
206 extlib_handler->filenamefn = &importhandler_extlib_filename;
207 extlib_handler->importfn = &importhandler_extlib_import;
208 if(importhandler_add(extlib_handler)){
209 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed to create 'extlib' import handler");
210 return 1;
211 }
212
213 return 0;
214 }
215
216 int importhandler_remove(const char *name){
217 ERROR_REPORTER_HERE(ASC_PROG_ERR,"%s not implemented",__FUNCTION__);
218 return 1;
219 }
220
221 struct ImportHandler *importhandler_lookup(const char *name){
222 ERROR_REPORTER_HERE(ASC_PROG_ERR,"%s not implemented",__FUNCTION__);
223 return NULL;
224 }
225
226 int importhandler_destroylibrary(){
227 ERROR_REPORTER_HERE(ASC_PROG_ERR,"%s not implemented",__FUNCTION__);
228 CONSOLE_DEBUG("NOT IMPLEMENTED");
229 return 1;
230 }
231
232
233 int importhandler_printlibrary(FILE *fp){
234 CONSOLE_DEBUG("NOT IMPLEMENTED");
235 return 1;
236 }
237
238 int importhandler_printhandler(FILE *fp, struct ImportHandler *handler){
239 ERROR_REPORTER_HERE(ASC_PROG_ERR,"%s not implemented",__FUNCTION__);
240 CONSOLE_DEBUG("NOT IMPLEMENTED");
241 return 1;
242 }
243
244 /*------------------------------------------------------------------------------
245 PATH SEARCH ROUTINES
246 */
247
248 /**
249 A little structure to help with searching for import files
250
251 @see test_importsearch
252 */
253 struct ImportHandlerSearch{
254 char *partialname; /**< for example 'myext' */
255 struct FilePath *relativedir; /**< for example 'path/to' */
256 struct FilePath *foundpath; /**< the complete filepath located, for example '/home/john/path/to/libmyext.so' */
257 struct ImportHandler *handler; /**< pointer to the import handler identified for this file */
258 };
259
260 FilePathTestFn importhandler_search_test;
261
262 /**
263 A FilePath 'test' function for passing to the ospath_searchpath_iterate function.
264 This test function will return a match when an importable file having the
265 required name is present in the fully resolved path.
266
267 @param path the search path component
268 @param userdata will be an ImportHandlerSearch object
269 @return 1 if found
270 */
271 int importhandler_search_test(struct FilePath *path, void *userdata){
272 /* user data = the relative path, plus a place
273 to store the full path when found */
274 FILE *f;
275 char *filename;
276 char *fullpath;
277 struct ImportHandlerSearch *searchdata;
278 struct FilePath *fp, *fp1, *fp2;
279 int i;
280 ospath_stat_t buf;
281
282 searchdata = (struct ImportHandlerSearch *)userdata;
283
284 char *pathcomponent;
285 pathcomponent = ospath_str(path); /* eg '/home/john' */
286 /* CONSOLE_DEBUG("In directory '%s'...",pathcomponent); */
287 ASC_FREE(pathcomponent);
288
289 asc_assert(importhandler_library!=NULL);
290
291 for(i=0; i<IMPORTHANDLER_MAX && importhandler_library[i]!=NULL; ++i){
292
293 filename = (*(importhandler_library[i]->filenamefn))(searchdata->partialname); /* eg 'myext' -> 'libmyext.so' */
294 if(filename==NULL){
295 CONSOLE_DEBUG("Unable to create filename from partialname '%s'",searchdata->partialname);
296 continue;
297 }
298 /* CONSOLE_DEBUG("Filename '%s'",filename); */
299 fp = ospath_new_noclean(filename); /* eg 'libmyext.so' */
300 ASC_FREE(filename);
301 asc_assert(fp!=NULL);
302
303 fullpath = ospath_str(searchdata->relativedir);
304 /* CONSOLE_DEBUG("Relative dir is '%s'",fullpath); */
305 ASC_FREE(fullpath);
306
307 fp1 = ospath_concat(path,searchdata->relativedir); /* eg '/home/john/path/to' */
308 asc_assert(fp1!=NULL);
309
310 fullpath = ospath_str(fp1);
311 /* CONSOLE_DEBUG("Path is '%s'",fullpath); */
312 ASC_FREE(fullpath);
313
314 fullpath = ospath_str(fp);
315 /* CONSOLE_DEBUG("Filename is '%s'",fullpath); */
316 ASC_FREE(fullpath);
317
318 fp2 = ospath_concat(fp1,fp); /* eg '/home/john/path/to/libmyext.so' */
319 asc_assert(fp2!=NULL);
320 ospath_free(fp1);
321 ospath_free(fp);
322
323 fullpath = ospath_str(fp2);
324 /* CONSOLE_DEBUG("Checking for readable '%s'",fullpath); */
325 ASC_FREE(fullpath);
326
327 if(0==ospath_stat(fp2,&buf) && NULL!=(f = ospath_fopen(fp2,"r"))){
328 fclose(f);
329 searchdata->foundpath = fp2;
330 searchdata->handler = importhandler_library[i];
331 return 1; /* success */
332 }
333
334 ospath_free(fp2);
335 }
336 return 0; /* failed */
337 }
338
339 struct FilePath *importhandler_findinpath(const char *partialname
340 , char *defaultpath, char *envv, struct ImportHandler **handler
341 ){
342 struct FilePath *fp1; /* relative path */
343 struct ImportHandlerSearch searchdata;
344 char *path;
345 struct FilePath **sp;
346
347 fp1 = ospath_new_noclean(partialname); /* eg 'path/to/myext' */
348 if(fp1==NULL){
349 ERROR_REPORTER_HERE(ASC_USER_ERROR,"Invalid partial path '%s'",partialname);
350 return NULL;
351 }
352
353 searchdata.partialname = ospath_getbasefilename(fp1);
354 if(searchdata.partialname==NULL){
355 CONSOLE_DEBUG("Not a filename");
356 ospath_free(fp1);
357 return NULL;
358 }
359
360 searchdata.relativedir = ospath_getdir(fp1);
361 if(searchdata.relativedir ==NULL){
362 ERROR_REPORTER_HERE(ASC_PROG_ERR,"unable to retrieve file dir");
363 ospath_free(fp1);
364 ASC_FREE(searchdata.partialname);
365 return NULL;
366 }
367 ospath_free(fp1);
368
369 searchdata.foundpath = NULL;
370 searchdata.handler = NULL;
371
372 /** @TODO first, attempt to open without searching in path */
373
374 path=Asc_GetEnv(envv);
375 if(path==NULL){
376 CONSOLE_DEBUG("ENV VAR NOT FOUND, FALLING BACK TO DEFAULT SEARCH PATH = '%s'",defaultpath);
377 path=defaultpath;
378 }
379
380 /* CONSOLE_DEBUG("SEARCHPATH IS %s",path); */
381 sp = ospath_searchpath_new(path);
382
383 if(NULL==ospath_searchpath_iterate(sp,&importhandler_search_test,&searchdata)){
384 ospath_free(searchdata.relativedir);
385 ASC_FREE(searchdata.partialname);
386 ospath_searchpath_free(sp);
387 return NULL;
388 }
389
390 ospath_searchpath_free(sp);
391 ASC_FREE(searchdata.partialname);
392 ospath_free(searchdata.relativedir);
393 *handler = searchdata.handler;
394 return searchdata.foundpath;
395 }
396
397 /*------------------------------------------------------------------------------
398 SHARED POINTER TABLE
399 */
400
401 int importhandler_createsharedpointertable(){
402 if(importhandler_sharedpointers==NULL){
403 /* CONSOLE_DEBUG("CREATED SHARED POINTER TABLE"); */
404 importhandler_sharedpointers = CreateTable(31);
405 }
406 return 0;
407 }
408
409 int importhandler_setsharedpointer(const char *key, void *ptr){
410 importhandler_createsharedpointertable();
411 if(key==NULL){
412 ERROR_REPORTER_HERE(ASC_PROG_ERR,"key is NULL");
413 return 1;
414 }
415 AddTableData(importhandler_sharedpointers,ptr,key);
416 CONSOLE_DEBUG("Set shared pointer '%s' to %p",key, ptr);
417 return 0;
418 }
419
420 void *importhandler_getsharedpointer(const char *key){
421 importhandler_createsharedpointertable();
422 if(key==NULL){
423 ERROR_REPORTER_HERE(ASC_PROG_ERR,"key is NULL");
424 return NULL;
425 }
426 return LookupTableData(importhandler_sharedpointers,key);
427 }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22