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

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