/[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 900 - (hide 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 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     /*
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 johnpye 869 /**
49     Table of registered pointers for use in passing GUI data out to external scripts.
50     */
51     struct Table *importhandler_sharedpointers=NULL;
52    
53 johnpye 862 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 johnpye 865 ERROR_REPORTER_HERE(ASC_PROG_NOTE,"New import hander '%s' added",handler->name);
75 johnpye 862 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 johnpye 866 snprintf(buffer,PATH_MAX,"%s.dll",partialname);
119 johnpye 862 # 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 johnpye 866
132 johnpye 862 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 johnpye 864 @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 johnpye 862 @return 0 on success
143     */
144 johnpye 864 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 johnpye 895 /* CONSOLE_DEBUG("Created auto-initfunc name '%s'",auto_initfunc); */
167 johnpye 864 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 johnpye 866 return result;
184 johnpye 862 }
185    
186     /*------------------------------------------------------------------------------
187     LIST-BASED FUNCTIONS related to IMPORT handler 'library'
188     */
189    
190     int importhandler_createlibrary(){
191     int i;
192 johnpye 864 struct ImportHandler *extlib_handler;
193    
194 johnpye 862 if(importhandler_library!=NULL){
195 johnpye 865 /* ERROR_REPORTER_HERE(ASC_PROG_ERR,"Already created"); */
196     return 0;
197 johnpye 862 };
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 johnpye 897 /* CONSOLE_DEBUG("ImportHandler library created"); */
203 johnpye 864
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 johnpye 866
213 johnpye 862 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 johnpye 864 /*------------------------------------------------------------------------------
245     PATH SEARCH ROUTINES
246     */
247 johnpye 862
248 johnpye 864 /**
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 johnpye 866 This test function will return a match when an importable file having the
265 johnpye 864 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 johnpye 888 /* CONSOLE_DEBUG("In directory '%s'...",pathcomponent); */
287 johnpye 864 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 johnpye 881 /* CONSOLE_DEBUG("Filename '%s'",filename); */
299 johnpye 864 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 johnpye 881 /* CONSOLE_DEBUG("Relative dir is '%s'",fullpath); */
305 johnpye 864 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 johnpye 881 /* CONSOLE_DEBUG("Path is '%s'",fullpath); */
312 johnpye 864 ASC_FREE(fullpath);
313    
314 johnpye 865 fullpath = ospath_str(fp);
315 johnpye 881 /* CONSOLE_DEBUG("Filename is '%s'",fullpath); */
316 johnpye 865 ASC_FREE(fullpath);
317    
318 johnpye 864 fp2 = ospath_concat(fp1,fp); /* eg '/home/john/path/to/libmyext.so' */
319     asc_assert(fp2!=NULL);
320     ospath_free(fp1);
321 johnpye 865 ospath_free(fp);
322 johnpye 864
323     fullpath = ospath_str(fp2);
324 johnpye 881 /* CONSOLE_DEBUG("Checking for readable '%s'",fullpath); */
325 johnpye 864 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 johnpye 895 /* CONSOLE_DEBUG("SEARCHPATH IS %s",path); */
381 johnpye 864 sp = ospath_searchpath_new(path);
382    
383     if(NULL==ospath_searchpath_iterate(sp,&importhandler_search_test,&searchdata)){
384     ospath_free(searchdata.relativedir);
385 johnpye 866 ASC_FREE(searchdata.partialname);
386 johnpye 864 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 johnpye 869
397     /*------------------------------------------------------------------------------
398     SHARED POINTER TABLE
399     */
400    
401     int importhandler_createsharedpointertable(){
402     if(importhandler_sharedpointers==NULL){
403 johnpye 897 /* CONSOLE_DEBUG("CREATED SHARED POINTER TABLE"); */
404 johnpye 869 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 johnpye 900 CONSOLE_DEBUG("Set shared pointer '%s' to %p",key, ptr);
417 johnpye 869 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 johnpye 895 return NULL;
425 johnpye 869 }
426     return LookupTableData(importhandler_sharedpointers,key);
427     }

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