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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 968 - (hide annotations) (download) (as text)
Mon Dec 18 05:49:00 2006 UTC (13 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 johnpye 862 /* 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 johnpye 864 #include <utilities/ascDynaLoad.h>
31     #include <utilities/ascPanic.h>
32     #include <utilities/ascEnvVar.h>
33 johnpye 869 #include <general/table.h>
34 johnpye 862 #include "importhandler.h"
35    
36 johnpye 912 /* #define IMPORTHANDLER_VERBOSE */
37    
38 johnpye 862 /*
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 johnpye 869 /**
51     Table of registered pointers for use in passing GUI data out to external scripts.
52     */
53     struct Table *importhandler_sharedpointers=NULL;
54    
55 johnpye 862 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 johnpye 931 ERROR_REPORTER_HERE(ASC_USER_NOTE,"Handler already loaded");
68 johnpye 862 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 johnpye 931 ERROR_REPORTER_HERE(ASC_USER_NOTE,"New import hander '%s' added",handler->name);
77 johnpye 862 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 johnpye 866 snprintf(buffer,PATH_MAX,"%s.dll",partialname);
121 johnpye 862 # 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 johnpye 866
134 johnpye 862 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 johnpye 864 @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 johnpye 862 @return 0 on success
145     */
146 johnpye 864 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 johnpye 895 /* CONSOLE_DEBUG("Created auto-initfunc name '%s'",auto_initfunc); */
169 johnpye 864 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 johnpye 866 return result;
186 johnpye 862 }
187    
188     /*------------------------------------------------------------------------------
189     LIST-BASED FUNCTIONS related to IMPORT handler 'library'
190     */
191    
192     int importhandler_createlibrary(){
193     int i;
194 johnpye 864 struct ImportHandler *extlib_handler;
195    
196 johnpye 862 if(importhandler_library!=NULL){
197 johnpye 865 /* ERROR_REPORTER_HERE(ASC_PROG_ERR,"Already created"); */
198     return 0;
199 johnpye 862 };
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 johnpye 897 /* CONSOLE_DEBUG("ImportHandler library created"); */
205 johnpye 864
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 johnpye 866
215 johnpye 862 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 johnpye 864 /*------------------------------------------------------------------------------
247     PATH SEARCH ROUTINES
248     */
249 johnpye 862
250 johnpye 864 /**
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 johnpye 866 This test function will return a match when an importable file having the
267 johnpye 864 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 johnpye 968 /* char *pathcomponent;
287     pathcomponent = ospath_str(path); //eg '/home/john'
288     CONSOLE_DEBUG("In directory '%s'...",pathcomponent);
289     ASC_FREE(pathcomponent); */
290 johnpye 864
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 johnpye 881 /* CONSOLE_DEBUG("Filename '%s'",filename); */
301 johnpye 864 fp = ospath_new_noclean(filename); /* eg 'libmyext.so' */
302     ASC_FREE(filename);
303     asc_assert(fp!=NULL);
304    
305 johnpye 968 /* fullpath = ospath_str(searchdata->relativedir);
306     CONSOLE_DEBUG("Relative dir is '%s'",fullpath);
307     ASC_FREE(fullpath); */
308 johnpye 864
309     fp1 = ospath_concat(path,searchdata->relativedir); /* eg '/home/john/path/to' */
310     asc_assert(fp1!=NULL);
311    
312 johnpye 968 /*fullpath = ospath_str(fp1);
313     CONSOLE_DEBUG("Path is '%s'",fullpath);
314     ASC_FREE(fullpath);*/
315 johnpye 864
316 johnpye 968 /*fullpath = ospath_str(fp);
317     CONSOLE_DEBUG("Filename is '%s'",fullpath);
318     ASC_FREE(fullpath);*/
319 johnpye 865
320 johnpye 864 fp2 = ospath_concat(fp1,fp); /* eg '/home/john/path/to/libmyext.so' */
321     asc_assert(fp2!=NULL);
322     ospath_free(fp1);
323 johnpye 865 ospath_free(fp);
324 johnpye 864
325 johnpye 968 /* fullpath = ospath_str(fp2);
326     CONSOLE_DEBUG("Checking for readable '%s'",fullpath);
327     ASC_FREE(fullpath); */
328 johnpye 864
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 johnpye 895 /* CONSOLE_DEBUG("SEARCHPATH IS %s",path); */
383 johnpye 864 sp = ospath_searchpath_new(path);
384    
385     if(NULL==ospath_searchpath_iterate(sp,&importhandler_search_test,&searchdata)){
386     ospath_free(searchdata.relativedir);
387 johnpye 866 ASC_FREE(searchdata.partialname);
388 johnpye 864 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 johnpye 869
399     /*------------------------------------------------------------------------------
400     SHARED POINTER TABLE
401     */
402    
403     int importhandler_createsharedpointertable(){
404     if(importhandler_sharedpointers==NULL){
405 johnpye 897 /* CONSOLE_DEBUG("CREATED SHARED POINTER TABLE"); */
406 johnpye 869 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 johnpye 912 #ifdef IMPORTHANDLER_VERBOSE
419 johnpye 900 CONSOLE_DEBUG("Set shared pointer '%s' to %p",key, ptr);
420 johnpye 912 #endif
421 johnpye 869 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 johnpye 895 return NULL;
429 johnpye 869 }
430     return LookupTableData(importhandler_sharedpointers,key);
431     }

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