⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gbx_library.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
字号:
/***************************************************************************  library.c  GAMBAS plug-in management routines  (c) 2000-2004 Beno顃 Minisini <gambas@users.sourceforge.net>  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 1, or (at your option)  any later version.  This program 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 General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __GBX_LIBRARY_C#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "gb_common.h"#include "gb_common_buffer.h"#include "gb_common_case.h"#include "gb_error.h"#include "gb_alloc.h"#include "gbx_list.h"#include "gb_replace.h"#include <fcntl.h>#include <stdlib.h>#include <stdarg.h>#include <time.h>#include <ctype.h>#include "gb_error.h"#include "gbx_class.h"#include "gbx_exec.h"#include "gbx_event.h"#include "gbx_stack.h"#include "gb_file.h"#include "gbx_archive.h"#include "gbx_project.h"#include "gbx_api.h"#include "gbx_string.h"#include "gbx_object.h"#include "gbx_library.h"/*#define DEBUG*//*#define DEBUG_PRELOAD*/PUBLIC LIBRARY *LIBRARY_Current;PUBLIC int LIBRARY_count = 0;PRIVATE LIBRARY *_library_list = NULL;#if 0PRIVATE lt_ptr library_malloc(size_t size){  lt_ptr ptr;  ALLOC(&ptr, size, "library_malloc");  printf("library_malloc: %d -> %p\n", size, ptr);  return ptr;}PRIVATE void library_free(lt_ptr ptr){  printf("library_free -> %p\n", ptr);  FREE(&ptr, "library_free");}#endifPRIVATE void *get_symbol(LIBRARY *lib, const char *symbol, bool err){  void *sym;  sym = lt_dlsym(lib->handle, symbol);  if (sym == NULL && err)  {    strcpy(COMMON_buffer, lt_dlerror());    lt_dlclose(lib->handle);    lib->handle = NULL;    THROW(E_LIBRARY, lib->path, COMMON_buffer);  }  return sym;}PRIVATE void copy_interface(long *src, long *dst){  for(;;)  {    if (*src == 0)      return;    *dst++ = *src++;  }}PUBLIC void LIBRARY_load_all(void){  LIBRARY *lib;  if (EXEC_debug)    LIBRARY_create("gb.eval");  for (lib = _library_list; lib; lib = (LIBRARY *)lib->list.next)  {    lib->preload = TRUE;    LIBRARY_load(lib);  }}PRIVATE bool read_line(int fd, char *dir, int max){  char *p;  char c;  ssize_t r;  p = dir;  for(;;)  {    max--;    for (;;)    {      r = read(fd, &c, 1);      if (r == 1)        break;      if (errno != EINTR)        return TRUE;    }    if (c == '\n' || max == 0)    {      *p = 0;      return FALSE;    }    *p++ = c;  }}#if 0PRIVATE void add_preload(char **env, const char *libdir, const char *lib){  if (*env == COMMON_buffer)    *env += sprintf(*env, "LD_PRELOAD=");  *env += sprintf(*env, "%s/lib/lib.%s.so.0", libdir, lib);}#endifPRIVATE void add_preload(char **env, const char *lib){  char *org;  if (*env == COMMON_buffer)  {    org = getenv("LD_PRELOAD");    if (org && *org)      *env += sprintf(*env, "%s ", org);  }  *env += sprintf(*env, "%s ", lib);}PUBLIC void LIBRARY_preload(const char *file, char **argv){#if DO_PRELOADING  const char *path;  char dir[MAX_PATH];  /*char libdir[MAX_PATH];*/  int fd;  char *p;  char *env;  bool preload;  bool stop;  env = getenv("GAMBAS_PRELOAD");  if (env)  {    #ifdef DEBUG_PRELOAD    fprintf(stderr, "Preloading done.\nLD_PRELOAD=%s\nGAMBAS_PRELOAD=%s\n", getenv("LD_PRELOAD"), getenv("GAMBAS_PRELOAD"));    #endif    if (*env)      setenv("LD_PRELOAD", env, TRUE);    else      unsetenv("LD_PRELOAD");    unsetenv("GAMBAS_PRELOAD");    return;  }  preload = FALSE;  /*  path = FILE_readlink("/usr/bin/gbx");  if (!path)    goto _PANIC;  path = FILE_get_dir(FILE_get_dir(path));  strcpy(libdir, path);  */  if (!EXEC_arch)  {    if (file == NULL)      file = ".";    if (*file == '/')    {      strcpy(dir, file);    }    else    {      if (*file == '.' && file[1] == '/')        file += 2;      path = FILE_getcwd(file);      if (path == NULL)        goto _PANIC;      chdir(path);      path = FILE_getcwd(NULL);      if (path == NULL)        goto _PANIC;      strcpy(dir, path);    }    file = FILE_cat(dir, ".project", NULL);  }  fd = open(file, O_RDONLY);  /* Silently ignored */  if (fd < 0)    return;  if (EXEC_arch)    lseek(fd, 32 + sizeof(ARCH_HEADER), SEEK_SET);  read_line(fd, dir, MAX_PATH);  if (strcasecmp(dir, "# Gambas Project File 1.0"))  {    fprintf(stderr, "Syntax error in project file.\n");    goto _PANIC;  }  env = COMMON_buffer;  stop = FALSE;  for(;;)  {    if (read_line(fd, dir, MAX_PATH))      break;    if (strncasecmp(dir, "library=", 8) == 0)    {      stop = TRUE;      p = &dir[8];      if (strcasecmp(p, "gb.qt") == 0)      {        add_preload(&env, "libqt-mt.so.3");        preload = TRUE;      }      #if HAVE_KDE_COMPONENT      else if (strcasecmp(p, "gb.qt.kde") == 0)      {        /*add_preload(&env, libdir, p);*/        add_preload(&env, "libkdecore.so.4");        add_preload(&env, "libkdeui.so.4");        add_preload(&env, "libDCOP.so.4");        add_preload(&env, "libkio.so.4");        /*fprintf(stderr, "Warning: preloading KDE libraries\n");*/        preload = TRUE;      }      #endif    }    else    {      if (stop)        break;    }  }  close(fd);  if (preload)  {    env = getenv("LD_PRELOAD");    if (env && *env)      setenv("GAMBAS_PRELOAD", env, TRUE);    else      setenv("GAMBAS_PRELOAD", "", TRUE);    setenv("LD_PRELOAD", COMMON_buffer, TRUE);    #ifdef DEBUG_PRELOAD    fprintf(stderr, "Preloading...\nLD_PRELOAD=%s\nGAMBAS_PRELOAD=%s\n", getenv("LD_PRELOAD"), getenv("GAMBAS_PRELOAD"));    #endif    execv("/usr/bin/gbx", argv);  }  return;_PANIC:  fprintf(stderr, "Cannot preload libraries: %s\n", strerror(errno));#endif}PUBLIC void LIBRARY_init(void){  /*if (putenv("LD_BIND_NOW=true"))    ERROR_panic("Cannot set LD_BIND_NOW: &1", strerror(errno));  if (putenv("KDE_MALLOC=0"))    ERROR_panic("Cannot set KDE_MALLOC: &1", strerror(errno));*/  /*lt_dlmalloc = library_malloc;  lt_dlfree = library_free;*/  #ifdef USE_LTDL  if (lt_dlinit())    ERROR_panic("Cannot initialize plug-in management: %s", lt_dlerror());  #endif}PUBLIC void LIBRARY_exit(void){  LIBRARY *lib;  /*for (lib = _library_list; lib; lib = (LIBRARY *)lib->list.next)*/  LIST_for_each(lib, _library_list)    LIBRARY_unload(lib);  while (_library_list)    LIBRARY_delete(_library_list);  #ifdef USE_LTDL  lt_dlexit();  #endif}PUBLIC LIBRARY *LIBRARY_find(const char *name){  LIBRARY *lib;  /*for (lib = _library_list; lib; lib = (LIBRARY *)lib->list.next)*/  LIST_for_each(lib, _library_list)  {    if (strcmp(lib->name, name) == 0)      return lib;  }  return NULL;}PUBLIC void LIBRARY_get_interface(LIBRARY *lib, long version, void *iface){  char symbol[32];  int i, len;  char c;  len = strlen(lib->name);  for (i = 0; i < len; i++)  {    c = toupper(lib->name[i]);    if (!isalnum(c))      c = '_';    symbol[i] = c;  }  sprintf(&symbol[len], "_%ld", version);  copy_interface((long *)get_symbol(lib, symbol, TRUE), (long *)iface);}PUBLIC boolean LIBRARY_get_interface_by_name(const char *name, long version, void *iface){  LIBRARY *lib;  lib = LIBRARY_find(name);  if (lib == NULL)    return TRUE;  LIBRARY_get_interface(lib, version, iface);  return FALSE;}PUBLIC LIBRARY *LIBRARY_create(const char *path){  LIBRARY *lib;  int len;  lib = LIBRARY_find(path);  if (lib)    return lib;  ALLOC_ZERO(&lib, sizeof(LIBRARY), "LIBRARY_create");  lib->class = CLASS_Library;  lib->ref = 1;  lib->handle = NULL;  if (path)  {    STRING_new(&lib->name, FILE_get_name(path), 0);    lib->free_name = TRUE;    if (!FILE_is_relative(path))      ERROR_panic("Absolute path are not allowed in libraries: %s", path);    len = strlen(path) + strlen(PROJECT_lib_path) + 8;    STRING_new(&lib->path, NULL, len);    sprintf(lib->path, LIB_PATTERN, PROJECT_lib_path, path);    lib->persistent = FALSE;    lib->preload = FALSE;  }  else  {    lib->name = "gb";    lib->free_name = FALSE;    lib->path = NULL;    lib->persistent = TRUE;    lib->preload = TRUE;  }  LIST_insert((void **)&_library_list, lib, &lib->list);  LIBRARY_count++;  return lib;}PUBLIC void LIBRARY_delete(LIBRARY *lib){  LIBRARY_unload(lib);  LIST_remove((void **)&_library_list, lib, &lib->list);  LIBRARY_count--;  if (lib->free_name)    STRING_free(&lib->name);  FREE(&lib, "LIBRARY_delete");}PUBLIC void LIBRARY_load(LIBRARY *lib){  int (*func)();  GB_INTERFACE *iface;  GB_DESC **desc;#ifdef DEBUG  clock_t t = clock();  fprintf(stderr, "Loading library %s\n", lib->path);#endif  if (lib->path == NULL)    return;  if (lib->handle)    return;  #ifdef USE_LTDL    lt_dlopen_flag = RTLD_LAZY;    lib->handle = lt_dlopenext(lib->path);  #else    lib->handle = dlopen(lib->path, RTLD_LAZY);  #endif  if (lib->handle == NULL)    THROW(E_LIBRARY, lib->path, lt_dlerror());  func = get_symbol(lib, LIB_INIT, TRUE);  /* Interface de Gambas */  iface = get_symbol(lib, LIB_GAMBAS, TRUE);  copy_interface((long *)GAMBAS_Api, (long *)iface);  /* Initialisation */  LIBRARY_Current = lib;  lib->persistent = (boolean)(*func)();  /* D閏laration des classes */  desc = get_symbol(lib, LIB_CLASS, FALSE);  if (desc)    LIBRARY_declare(desc);#ifdef DEBUG  fprintf(stderr, "Library %s loaded ", lib->path);  fprintf(stderr, "in %g s\n", ((double)(clock() - t) / CLOCKS_PER_SEC));#endif}PUBLIC void LIBRARY_declare(GB_DESC **desc){  while (*desc != NULL)  {    if (CLASS_register(*desc) == NULL)      THROW(E_REGISTER, *((char **)desc));    desc++;  }}PUBLIC void LIBRARY_unload(LIBRARY *lib){  void (*gambas_exit)();  if (lib->path == NULL)    return;  STRING_free(&lib->path);  if (lib->handle == NULL)    return;  /* Pas de lib閞ation des classes pr閏harg閑 ! */  /* V閞ification qu'aucune classe de la librairie n'est instanci閑 ! */  gambas_exit = lt_dlsym(lib->handle, LIB_EXIT);  if (gambas_exit != NULL)    (*gambas_exit)();  if (lib->persistent)  {    gambas_exit = lt_dlsym(lib->handle, "_fini");    if (gambas_exit != NULL)      (*gambas_exit)();  }  else    lt_dlclose(lib->handle);  lib->handle = NULL;#ifdef DEBUG  printf("Unloading library %s\n", lib->name);#endif}PUBLIC LIBRARY *LIBRARY_next(LIBRARY *lib){  if (lib)    return (LIBRARY *)(lib->list.next);  else    return _library_list;}#if 0PUBLIC const char *LIBRARY_get_control_list(LIBRARY *lib){  void (*gambas_info)();  const char *result = NULL;  gambas_info = lt_dlsym(lib->handle, LIB_INFO);  if (gambas_info == NULL)    return NULL;  (*gambas_info)(GB_INFO_CONTROL, &result);  return result;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -