diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2007-10-01 08:01:00 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2007-10-01 08:01:00 -0700 |
commit | 4812c90424dfc40d26725244723887a2d16ddfd9 (patch) | |
tree | b32ace96e7e2d84d586e09ba605463b6f49c3271 /src/base/main/libSupport.c | |
parent | e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7 (diff) | |
download | abc-4812c90424dfc40d26725244723887a2d16ddfd9.tar.gz abc-4812c90424dfc40d26725244723887a2d16ddfd9.tar.bz2 abc-4812c90424dfc40d26725244723887a2d16ddfd9.zip |
Version abc71001
Diffstat (limited to 'src/base/main/libSupport.c')
-rw-r--r-- | src/base/main/libSupport.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/base/main/libSupport.c b/src/base/main/libSupport.c new file mode 100644 index 00000000..471ea09e --- /dev/null +++ b/src/base/main/libSupport.c @@ -0,0 +1,193 @@ +/**CFile**************************************************************** + + FileName [libSupport.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [The main package.] + + Synopsis [Support for external libaries.] + + Author [Mike Case] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: libSupport.c,v 1.1 2005/09/06 19:59:51 casem Exp $] + +***********************************************************************/ + +#include "mainInt.h" +#include <stdio.h> +#include <string.h> + +#ifndef WIN32 +# include <sys/types.h> +# include <dirent.h> +# include <dlfcn.h> +#endif + +#define MAX_LIBS 256 +static void* libHandles[MAX_LIBS+1]; // will be null terminated + +typedef void (*lib_init_end_func) (Abc_Frame_t * pAbc); + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This will find all the ABC library extensions in the current directory and load them all. +//////////////////////////////////////////////////////////////////////////////////////////////////// +void open_libs() { + int curr_lib = 0; + +#ifdef WIN32 +// printf("Warning: open_libs WIN32 not implemented.\n"); +#else + DIR* dirp; + struct dirent* dp; + char *env, *init_p, *p; + int done; + + env = getenv ("ABC_LIB_PATH"); + if (env == NULL) { +// printf("Warning: ABC_LIB_PATH not defined. Looking into the current directory.\n"); + init_p = malloc (2*sizeof(char)); + init_p[0]='.'; init_p[1] = 0; + } else { + init_p = malloc ((strlen(env)+1)*sizeof(char)); + strcpy (init_p, env); + } + + // Extract directories and read libraries + done = 0; + p = init_p; + while (!done) { + char *endp = strchr (p,':'); + if (endp == NULL) done = 1; // last directory in the list + else *endp = 0; // end of string + + dirp = opendir(p); + if (dirp == NULL) { +// printf("Warning: directory in ABC_LIB_PATH does not exist (%s).\n", p); + continue; + } + + while ((dp = readdir(dirp)) != NULL) { + if ((strncmp("libabc_", dp->d_name, 7) == 0) && + (strcmp(".so", dp->d_name + strlen(dp->d_name) - 3) == 0)) { + + // make sure we don't overflow the handle array + if (curr_lib >= MAX_LIBS) { + printf("Warning: maximum number of ABC libraries (%d) exceeded. Not loading %s.\n", + MAX_LIBS, + dp->d_name); + } + + // attempt to load it + else { + char* szPrefixed = malloc((strlen(dp->d_name) + strlen(p) + 2) * + sizeof(char)); + sprintf(szPrefixed, "%s/", p); + strcat(szPrefixed, dp->d_name); + libHandles[curr_lib] = dlopen(szPrefixed, RTLD_NOW | RTLD_LOCAL); + + // did the load succeed? + if (libHandles[curr_lib] != 0) { + printf("Loaded ABC library: %s (Abc library extension #%d)\n", szPrefixed, curr_lib); + curr_lib++; + } else { + printf("Warning: failed to load ABC library %s:\n\t%s\n", szPrefixed, dlerror()); + } + + free(szPrefixed); + } + } + } + closedir(dirp); + p = endp+1; + } + + free(init_p); +#endif + + // null terminate the list of handles + libHandles[curr_lib] = 0; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This will close all open ABC library extensions +//////////////////////////////////////////////////////////////////////////////////////////////////// +void close_libs() { +#ifdef WIN32 + printf("Warning: close_libs WIN32 not implemented.\n"); +#else + int i; + for (i = 0; libHandles[i] != 0; i++) { + if (dlclose(libHandles[i]) != 0) { + printf("Warning: failed to close library %d\n", i); + } + libHandles[i] = 0; + } +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This will get a pointer to a function inside of an open library +//////////////////////////////////////////////////////////////////////////////////////////////////// +void* get_fnct_ptr(int lib_num, char* sym_name) { +#ifdef WIN32 + printf("Warning: get_fnct_ptr WIN32 not implemented.\n"); + return 0; +#else + return dlsym(libHandles[lib_num], sym_name); +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This will call an initialization function in every open library. +//////////////////////////////////////////////////////////////////////////////////////////////////// +void call_inits(Abc_Frame_t* pAbc) { + int i; + lib_init_end_func init_func; + for (i = 0; libHandles[i] != 0; i++) { + init_func = (lib_init_end_func) get_fnct_ptr(i, "abc_init"); + if (init_func == 0) { + printf("Warning: Failed to initialize library %d.\n", i); + } else { + (*init_func)(pAbc); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This will call a shutdown function in every open library. +//////////////////////////////////////////////////////////////////////////////////////////////////// +void call_ends(Abc_Frame_t* pAbc) { + int i; + lib_init_end_func end_func; + for (i = 0; libHandles[i] != 0; i++) { + end_func = (lib_init_end_func) get_fnct_ptr(i, "abc_end"); + if (end_func == 0) { + printf("Warning: Failed to end library %d.\n", i); + } else { + (*end_func)(pAbc); + } + } +} + +void Libs_Init(Abc_Frame_t * pAbc) +{ + open_libs(); + call_inits(pAbc); +} + +void Libs_End(Abc_Frame_t * pAbc) +{ + call_ends(pAbc); + + // It's good practice to close our libraries at this point, but this can mess up any backtrace printed by Valgind. + // close_libs(); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// |