 80a8257302
			
		
	
	80a8257302
	
	
	
		
			
			Make gtk-reftest consult the REFTEST_MODULE_DIR environment variable to find out where to look for modules, and fix the libtool hack to construct the .libs subdirectory correctly.
		
			
				
	
	
		
			173 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* GTK - The GIMP Toolkit
 | |
|  * Copyright (C) 2014 Red Hat, Inc.
 | |
|  *
 | |
|  * This library is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU Lesser General Public
 | |
|  * License as published by the Free Software Foundation; either
 | |
|  * version 2 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  * This library is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  * Lesser General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU Lesser General Public
 | |
|  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| #include "config.h"
 | |
| 
 | |
| #include "reftest-module.h"
 | |
| 
 | |
| struct _ReftestModule {
 | |
|   int      refcount;
 | |
|   char    *filename;
 | |
|   GModule *module;
 | |
| };
 | |
| 
 | |
| 
 | |
| static GHashTable *all_modules = NULL;
 | |
| 
 | |
| static ReftestModule *
 | |
| reftest_module_find_existing (const char *filename)
 | |
| {
 | |
|   if (all_modules == NULL)
 | |
|     return NULL;
 | |
| 
 | |
|   return g_hash_table_lookup (all_modules, filename ? filename : "");
 | |
| }
 | |
| 
 | |
| static ReftestModule *
 | |
| reftest_module_new_take (GModule *module,
 | |
|                          char    *filename)
 | |
| {
 | |
|   ReftestModule *result;
 | |
| 
 | |
|   g_return_val_if_fail (module != NULL, NULL);
 | |
| 
 | |
|   result = g_slice_new0 (ReftestModule);
 | |
| 
 | |
|   result->refcount = 1;
 | |
|   result->filename = filename;
 | |
|   result->module = module;
 | |
| 
 | |
|   if (all_modules == NULL)
 | |
|     all_modules = g_hash_table_new (g_str_hash, g_str_equal);
 | |
| 
 | |
|   g_hash_table_insert (all_modules, filename ? filename : "", result);
 | |
| 
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| ReftestModule *
 | |
| reftest_module_new_self (void)
 | |
| {
 | |
|   ReftestModule *result;
 | |
|   GModule *module;
 | |
| 
 | |
|   result = reftest_module_find_existing (NULL);
 | |
|   if (result)
 | |
|     return reftest_module_ref (result);
 | |
| 
 | |
|   module = g_module_open (NULL, G_MODULE_BIND_LAZY);
 | |
|   if (module == NULL)
 | |
|     return NULL;
 | |
| 
 | |
|   return reftest_module_new_take (module, NULL);
 | |
| }
 | |
| 
 | |
| ReftestModule *
 | |
| reftest_module_new (const char *directory,
 | |
|                     const char *module_name)
 | |
| {
 | |
|   ReftestModule *result;
 | |
|   char *full_path;
 | |
|   GModule *module;
 | |
| 
 | |
|   g_return_val_if_fail (module_name != NULL, NULL);
 | |
| 
 | |
|   full_path = g_module_build_path (directory, module_name);
 | |
| 
 | |
|   result = reftest_module_find_existing (full_path);
 | |
|   if (result)
 | |
|     {
 | |
|       g_free (full_path);
 | |
|       return reftest_module_ref (result);
 | |
|     }
 | |
| 
 | |
|   module = g_module_open (full_path, G_MODULE_BIND_LOCAL | G_MODULE_BIND_LAZY);
 | |
|   if (module == NULL)
 | |
|     {
 | |
|       /* libtool hack */
 | |
|       char *libtool_dir = g_build_filename (directory, ".libs", NULL);
 | |
| 
 | |
|       g_free (full_path);
 | |
|       full_path = g_module_build_path (libtool_dir, module_name);
 | |
| 
 | |
|       result = reftest_module_find_existing (full_path);
 | |
|       if (result)
 | |
|         {
 | |
|           g_free (full_path);
 | |
|           return reftest_module_ref (result);
 | |
|         }
 | |
| 
 | |
|       module = g_module_open (full_path, G_MODULE_BIND_LOCAL | G_MODULE_BIND_LAZY);
 | |
|       if (module == NULL)
 | |
|         {
 | |
|           g_free (full_path);
 | |
|           return NULL;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|   return reftest_module_new_take (module, full_path);
 | |
| }
 | |
| 
 | |
| ReftestModule *
 | |
| reftest_module_ref (ReftestModule *module)
 | |
| {
 | |
|   g_return_val_if_fail (module != NULL, NULL);
 | |
| 
 | |
|   module->refcount++;
 | |
| 
 | |
|   return module;
 | |
| }
 | |
| 
 | |
| void
 | |
| reftest_module_unref (ReftestModule *module)
 | |
| {
 | |
|   g_return_if_fail (module != NULL);
 | |
| 
 | |
|   module->refcount--;
 | |
|   if (module->refcount > 0)
 | |
|     return;
 | |
| 
 | |
|   if (!g_module_close (module->module))
 | |
|     {
 | |
|       g_assert_not_reached ();
 | |
|     }
 | |
| 
 | |
|   if (!g_hash_table_remove (all_modules, module->filename ? module->filename : ""))
 | |
|     {
 | |
|       g_assert_not_reached ();
 | |
|     }
 | |
| 
 | |
|   g_free (module->filename);
 | |
|   g_slice_free (ReftestModule, module);
 | |
| }
 | |
| 
 | |
| GCallback
 | |
| reftest_module_lookup (ReftestModule *module,
 | |
|                        const char    *function_name)
 | |
| {
 | |
|   gpointer result;
 | |
| 
 | |
|   g_return_val_if_fail (module != NULL, NULL);
 | |
|   g_return_val_if_fail (function_name != NULL, NULL);
 | |
| 
 | |
|   if (!g_module_symbol (module->module, function_name, &result))
 | |
|     return NULL;
 | |
| 
 | |
|   return result;
 | |
| }
 | |
| 
 |