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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 862 by johnpye, Tue Sep 26 13:47:27 2006 UTC revision 864 by johnpye, Thu Sep 28 13:39:16 2006 UTC
# Line 27  Line 27 
27  #include <utilities/ascConfig.h>  #include <utilities/ascConfig.h>
28  #include <utilities/config.h>  #include <utilities/config.h>
29  #include <utilities/error.h>  #include <utilities/error.h>
30    #include <utilities/ascDynaLoad.h>
31    #include <utilities/ascPanic.h>
32    #include <utilities/ascEnvVar.h>
33  #include "importhandler.h"  #include "importhandler.h"
34    
35  /*  /*
# Line 127  char *importhandler_extlib_filename(cons Line 130  char *importhandler_extlib_filename(cons
130      that the file exists and is readable.      that the file exists and is readable.
131    
132      @param fp Location of DLL/SO file      @param fp Location of DLL/SO file
133        @param initfunc Name of registration function, preferably NULL (so that ASCEND automatically determines it)
134        @param partialpath as specified in 'IMPORT' statement, for creation of auto_initfunc name
135      @return 0 on success      @return 0 on success
136  */  */
137  int importhandler_extlib_import(struct FilePath *fp,void *user_data){  int importhandler_extlib_import(const struct FilePath *fp,const char *initfunc,const char *partialpath){
138      return 1;  
139        struct FilePath *fp1;
140        char *stem;
141        char *path;
142        char auto_initfunc[PATH_MAX];
143        int result;
144    
145        path = ospath_str(fp);
146        if(path==NULL){
147            ERROR_REPORTER_HERE(ASC_PROG_ERR,"File path is NULL");
148            return 1;
149        }
150    
151        if(initfunc==NULL){
152            fp1 = ospath_new(partialpath);
153            stem = ospath_getbasefilename(fp1);
154            strncpy(auto_initfunc,stem,PATH_MAX);
155            ospath_free(fp1);
156            ASC_FREE(stem);
157    
158            strncat(auto_initfunc,"_register",PATH_MAX-strlen(auto_initfunc));
159            CONSOLE_DEBUG("Created auto-initfunc name '%s'",auto_initfunc);
160            result = Asc_DynamicLoad(path,auto_initfunc);
161        }else{
162            result = Asc_DynamicLoad(path,initfunc);
163        }
164    
165        if(result){
166            CONSOLE_DEBUG("FAILED TO IMPORT '%s' (error %d)",partialpath,result);
167        }else{
168            if(initfunc==NULL){
169                CONSOLE_DEBUG("Successfully ran '%s' (automatically named) from dynamic package '%s'",auto_initfunc,path);
170            }else{
171                CONSOLE_DEBUG("Successfully ran '%s' from dynamic package '%s'",initfunc,path);
172            }
173        }
174    
175        ASC_FREE(path);
176        return result;  
177  }  }
178    
179  /*------------------------------------------------------------------------------  /*------------------------------------------------------------------------------
# Line 139  int importhandler_extlib_import(struct F Line 182  int importhandler_extlib_import(struct F
182    
183  int importhandler_createlibrary(){  int importhandler_createlibrary(){
184      int i;      int i;
185        struct ImportHandler *extlib_handler;
186    
187      if(importhandler_library!=NULL){      if(importhandler_library!=NULL){
188          ERROR_REPORTER_HERE(ASC_PROG_ERR,"Already created");          ERROR_REPORTER_HERE(ASC_PROG_ERR,"Already created");
189          return 1;          return 1;
# Line 148  int importhandler_createlibrary(){ Line 193  int importhandler_createlibrary(){
193          importhandler_library[i] = NULL;          importhandler_library[i] = NULL;
194      }      }
195      ERROR_REPORTER_HERE(ASC_PROG_NOTE,"ImportHandler library created");      ERROR_REPORTER_HERE(ASC_PROG_NOTE,"ImportHandler library created");
196    
197        extlib_handler = ASC_NEW(struct ImportHandler);
198        extlib_handler->name ="extlib";
199        extlib_handler->filenamefn = &importhandler_extlib_filename;
200        extlib_handler->importfn = &importhandler_extlib_import;
201        if(importhandler_add(extlib_handler)){
202            ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed to create 'extlib' import handler");
203            return 1;
204        }
205        
206      return 0;      return 0;
207  }  }
208    
# Line 179  int importhandler_printhandler(FILE *fp, Line 234  int importhandler_printhandler(FILE *fp,
234      return 1;      return 1;
235  }  }
236    
237    /*------------------------------------------------------------------------------
238      PATH SEARCH ROUTINES
239    */
240    
241    /**
242        A little structure to help with searching for import files
243    
244        @see test_importsearch
245    */
246    struct ImportHandlerSearch{
247        char *partialname; /**< for example 'myext' */
248        struct FilePath *relativedir; /**< for example 'path/to' */
249        struct FilePath *foundpath; /**< the complete filepath located, for example '/home/john/path/to/libmyext.so' */
250        struct ImportHandler *handler; /**< pointer to the import handler identified for this file */
251    };
252    
253    FilePathTestFn importhandler_search_test;
254    
255    /**
256        A FilePath 'test' function for passing to the ospath_searchpath_iterate function.
257        This test function will return a match when an importable file having the
258        required name is present in the fully resolved path.
259    
260        @param path the search path component
261        @param userdata will be an ImportHandlerSearch object
262        @return 1 if found
263    */
264    int importhandler_search_test(struct FilePath *path, void *userdata){
265        /*  user data = the relative path, plus a place
266            to store the full path when found */
267        FILE *f;
268        char *filename;
269        char *fullpath;
270        struct ImportHandlerSearch *searchdata;
271        struct FilePath *fp, *fp1, *fp2;
272        int i;
273        ospath_stat_t buf;
274    
275        searchdata = (struct ImportHandlerSearch *)userdata;
276    
277        char *pathcomponent;
278        pathcomponent = ospath_str(path); /* eg '/home/john' */
279        CONSOLE_DEBUG("In directory '%s'...",pathcomponent);
280        ASC_FREE(pathcomponent);
281    
282        asc_assert(importhandler_library!=NULL);
283    
284        for(i=0; i<IMPORTHANDLER_MAX && importhandler_library[i]!=NULL; ++i){
285    
286            filename = (*(importhandler_library[i]->filenamefn))(searchdata->partialname); /* eg 'myext' -> 'libmyext.so' */
287            if(filename==NULL){
288                CONSOLE_DEBUG("Unable to create filename from partialname '%s'",searchdata->partialname);
289                continue;
290            }
291            CONSOLE_DEBUG("Filename '%s'",filename);
292            fp = ospath_new_noclean(filename); /* eg 'libmyext.so' */
293            ASC_FREE(filename);
294            asc_assert(fp!=NULL);
295    
296            fullpath = ospath_str(searchdata->relativedir);
297            CONSOLE_DEBUG("Relative dir is '%s'",fullpath);
298            ASC_FREE(fullpath);
299    
300            fp1 = ospath_concat(path,searchdata->relativedir); /* eg '/home/john/path/to' */
301            asc_assert(fp1!=NULL);
302            ospath_free(fp);
303    
304            fullpath = ospath_str(fp1);
305            CONSOLE_DEBUG("Path is '%s'",fullpath);
306            ASC_FREE(fullpath);
307    
308            fp2 = ospath_concat(fp1,fp); /* eg '/home/john/path/to/libmyext.so' */
309            asc_assert(fp2!=NULL);
310            ospath_free(fp1);
311    
312            fullpath = ospath_str(fp2);
313            CONSOLE_DEBUG("Checking for readable '%s'",fullpath);
314            ASC_FREE(fullpath);
315    
316            if(0==ospath_stat(fp2,&buf) && NULL!=(f = ospath_fopen(fp2,"r"))){
317                fclose(f);
318                searchdata->foundpath = fp2;
319                searchdata->handler = importhandler_library[i];
320                return 1; /* success */
321            }
322    
323            ospath_free(fp2);
324        }
325        return 0; /* failed */
326    }
327    
328    struct FilePath *importhandler_findinpath(const char *partialname
329            , char *defaultpath, char *envv, struct ImportHandler **handler
330    ){
331        struct FilePath *fp1; /* relative path */
332        struct ImportHandlerSearch searchdata;
333        char *path;
334        struct FilePath **sp;
335    
336        fp1 = ospath_new_noclean(partialname); /* eg 'path/to/myext' */
337        if(fp1==NULL){
338            ERROR_REPORTER_HERE(ASC_USER_ERROR,"Invalid partial path '%s'",partialname);
339            return NULL;
340        }
341    
342        searchdata.partialname = ospath_getbasefilename(fp1);
343        if(searchdata.partialname==NULL){
344            CONSOLE_DEBUG("Not a filename");
345            ospath_free(fp1);
346            return NULL;
347        }
348        
349    
350        searchdata.relativedir = ospath_getdir(fp1);
351        if(searchdata.relativedir ==NULL){
352            ERROR_REPORTER_HERE(ASC_PROG_ERR,"unable to retrieve file dir");
353            ospath_free(fp1);
354            ASC_FREE(searchdata.partialname);
355            return NULL;
356        }
357        ospath_free(fp1);
358    
359        searchdata.foundpath = NULL;
360        searchdata.handler = NULL;
361    
362        /** @TODO first, attempt to open without searching in path */
363    
364        path=Asc_GetEnv(envv);
365        if(path==NULL){
366            CONSOLE_DEBUG("ENV VAR NOT FOUND, FALLING BACK TO DEFAULT SEARCH PATH = '%s'",defaultpath);
367            path=defaultpath;
368        }
369    
370        CONSOLE_DEBUG("SEARCHPATH IS %s",path);
371        sp = ospath_searchpath_new(path);
372    
373        if(NULL==ospath_searchpath_iterate(sp,&importhandler_search_test,&searchdata)){
374            ospath_free(searchdata.relativedir);
375            ASC_FREE(searchdata.partialname);      
376            ospath_searchpath_free(sp);
377            return NULL;
378        }
379    
380        ospath_searchpath_free(sp);
381        ASC_FREE(searchdata.partialname);
382        ospath_free(searchdata.relativedir);
383        *handler = searchdata.handler;
384        return searchdata.foundpath;
385    }

Legend:
Removed from v.862  
changed lines
  Added in v.864

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