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

📄 gbi.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
字号:
/***************************************************************************  gbi.c  component informer  (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.***************************************************************************/#include <config.h>#include "gb_limit.h"#include "gb_common.h"#include "gb_alloc.h"#ifdef __GNU_LIBRARY__#define _GNU_SOURCE#include <getopt.h>#endif#include <stdlib.h>#include <string.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/time.h>#include <dirent.h>#include <dlfcn.h>#include <ltdl.h>#include <ctype.h>#include "gb_component.h"#include "gb_file.h"#include "gb_str.h"#include "gambas.h"static char _root[MAX_PATH + 1] = { 0 };static char _lib_path[MAX_PATH + 1];static char _info_path[MAX_PATH + 1];static char _buffer[MAX_PATH + 1];static FILE *out_info;static FILE *out_list;static bool _verbose = FALSE;static bool _format = FALSE;static bool _nopreload = FALSE;#ifdef __GNU_LIBRARY__static struct option LongOptions[] ={  { "version", 0, NULL, 'V' },  { "verbose", 0, NULL, 'v' },  { "format", 0, NULL, 'f' },  { "help", 0, NULL, 'h' },  { "all", 0, NULL, 'a' },  { "root", 1, NULL, 'r' },  { 0 }};#endifstatic void print(const char *fmt, ...){  va_list args;  va_start(args, fmt);  vfprintf(out_info, fmt, args);}static void error(const char *msg){  fprintf(stderr, "%s\n", msg);  exit(1);}static void error2(const char *msg, const char *msg2){  fprintf(stderr, "%s: %s\n", msg, msg2);  exit(1);}static void init(char *exec){  const char *path;  /* chemin d'installation de Gambas */  if (!_root[0])  {    path = FILE_find_gambas(exec);    strncpy(_root, FILE_get_dir(FILE_get_dir(path)), MAX_PATH);  }    strcpy(_lib_path, FILE_cat(_root, "lib/gambas", NULL));  strcpy(_info_path, FILE_cat(_root, "share/gambas/info", NULL));  if (lt_dlinit())    error2("Cannot initialize plug-in management", lt_dlerror());  /*if (putenv("LD_BIND_NOW=true"))    error2("Cannot set LD_BIND_NOW", strerror(errno));  if (putenv("KDE_MALLOC=0"))    error2("Cannot set KDE_MALLOC", strerror(errno));*/}static void newline(){  print("\n");}static bool print_type(const char *type){  switch (*type)  {    case 'b': print("Boolean"); break;    case 'i': print("Integer"); break;    case 's': print("String"); break;    case 'd': print("Date"); break;    case 'f': print("Float"); break;    case 'v': print("Variant"); break;    case 'o': print("Object"); break;    default:      while (*type && *type != ';')      {        print("%c", *type);        type++;      }      return TRUE;  }  return FALSE;}static void dump_value(const char *type, long value){  char *p;  switch(*type)  {    case 'i':      print("%ld", value, value);      break;    case 'f':      print("%s", (char *)value);      break;    case 's':      p = (char *)value;      while (*p)      {        if (*p == '\n')          print("\\n");        else if (*p == '\t')          print("\\t");        else          print("%c", *p);        p++;      }      break;    default:      print("?");      break;  }}static void print_value(const char *type, long value){  char *p;  switch(*type)  {    case 'i':      print("%ld ( &H%lX )", value, value);      break;    case 'f':      print("\"%s\"", (char *)value);      break;    case 's':      p = (char *)value;      print("\"");      while (*p)      {        if (*p == '\n')          print("\\n");        else if (*p == '\t')          print("\\t");        else          print("%c", *p);        p++;      }      print("\"");      break;    default:      print("?");      break;  }}static void print_signature(const char *sign){  char mode = 0;  char c;  bool comma = FALSE;  if (!sign)    return;  while ((c = *sign))  {    if (!mode)    {      if (c == '(')      {        if (comma)          print(" ,");        print(_format ? " <i>" : " ");        mode = ')';      }      else if (c == '<')        mode = '>';      else if (c == '[')        print(_format ? " <b>[</b>" : " [");      else if (c == ']')        print(_format ? " <b>]</b>" : " ]");      else if (c == '.')        print(" ...");      else      {        print(" AS ");        if (print_type(sign))          mode = ';';        comma = TRUE;      }    }    else if (c == mode)    {      if (mode == ')' && _format)        print("</i>");      mode = 0;    }    else if (mode == ')')    {      print("%c", c);    }    sign++;  }}void analyze_symbol(GB_DESC *desc){  char type;  char *name;  type = *desc->name;  name = &desc->name[1];  print("%s\n", name);  if (isupper(type))  {    if (type != 'C') print("STATIC ");    type = tolower(type);  }  if (type == ':')    name++;  switch (type)  {    case 'c':      print(_format ? "CONST <b>%s</b> AS " : "CONST %s AS ", name);      print_type((char *)desc->val1);      print(" = ");      print_value((char *)desc->val1, desc->val2);      newline();      break;    case 'p':      print(_format ? "PROPERTY <b>%s</b> AS " : "PROPERTY %s AS ", name);      print_type((char *)desc->val1);      newline();      break;    case 'r':      print(_format ? "PROPERTY READ <b>%s</b> AS " : "PROPERTY READ %s AS ", name);      print_type((char *)desc->val1);      newline();      break;    case 'm': case ':':      if (type == ':')        print(_format ? "EVENT <b>%s</b> (" : "EVENT %s (", name);      else        print(_format ? "%s <b>%s</b> (" : "%s %s (", desc->val1 ? "FUNCTION" : "SUB", name);      print_signature((char *)desc->val3);      print(" )");      if (desc->val1)      {        print(" AS ");        print_type((char *)desc->val1);      }      newline();      break;  }}void dump_symbol(GB_DESC *desc){  char *name;  name = &desc->name[1];  print("%s\n", name);  print("%c\n", *desc->name);  if (desc->val1)    print("%s", desc->val1);  newline();  if (*desc->name == 'C')    dump_value((char *)desc->val1, desc->val2);  else if (desc->val3)    print("%s", (char *)desc->val3);  newline();}void analyze_class(GB_DESC *desc){  char *name = desc->name;  char *parent = NULL;  bool nonew = FALSE;  bool autocreate = FALSE;  ulong hook;  if (out_list && name[0] != '.')    fprintf(out_list, "%s\n", name);    desc++;  while (desc->name)  {    hook = (ulong)desc->name;    if (hook == (ulong)GB_INHERITS_ID)      parent = (char *)desc->val1;    else if ((hook == (ulong)GB_HOOK_NEW_ID) && desc->val1 == 0)      nonew = TRUE;    else if (hook == (ulong)GB_AUTO_CREATABLE_ID)      autocreate = TRUE;    else if (hook > 16)      break;    desc++;  }  if (_format)  {    print("CLASS %s\n", name);    if (parent) print("INHERITS %s\n", parent);    if (!nonew) print("CREATABLE\n");    if (autocreate) print("AUTOCREATABLE\n");  }  else  {    print("#%s\n", name);    if (parent)      print("%s", parent);    newline();    if (!nonew)      print("C");    if (autocreate)      print("A");    newline();  }  while (desc->name)  {    if (_format)      analyze_symbol(desc);    else      dump_symbol(desc);    desc++;  }  if (_format)    newline();}bool analyze(const char *path){  lt_dlhandle lib;  /*void *dlib;*/  GB_DESC **desc;  bool ret = FALSE;  /*  if (strcmp(name, "gb") == 0)  {    sprintf(path, LIB_PATTERN, _lib_path, name);    dlib = dlopen("/usr/bin/gbx", RTLD_NOW);    if (!dlib)      error2("Cannot open component:", dlerror());    desc = dlsym(lib, LIB_CLASS);    if (!desc)      error("Cannot find symbol " LIB_CLASS);  }  else  */  if (_verbose)    fprintf(stderr, "Loading: %s\n", path);  lt_dlopen_flag = RTLD_LAZY; /* | RTLD_GLOBAL;*/  if (access(path, F_OK))    error2(path, "not found");    lib = lt_dlopenext(path);  if (!lib)    error2(path, lt_dlerror());  desc = lt_dlsym(lib, LIB_CLASS);  if (desc)  {    while (*desc)    {      analyze_class(*desc);      desc++;    }  }  else    ret = TRUE;  lt_dlclose(lib);  return ret;}void preload(char **argv, char *lib){#if DO_PRELOADING  char buf[256];  if (_nopreload || getenv("GAMBAS_PRELOAD"))    return;  sprintf(buf, "LD_PRELOAD=%s", lib);  putenv(buf);  putenv("GAMBAS_PRELOAD=1");  execv("/usr/bin/gbi", argv);#endif}int main(int argc, char **argv){  DIR *dir;  struct dirent *dirent;  char *name;  char *path_list;  char *path_info;  int all = FALSE;  int opt;  int save_fd;  bool res;  #ifdef __GNU_LIBRARY__  int ind = 0;  #endif  /*#ifdef __FreeBSD__  optind = 1;  #else  optind = 0;  #endif*/  for(;;)  {    #ifdef __GNU_LIBRARY__      opt = getopt_long(argc, argv, "vVhafpr:", LongOptions, &ind);    #else      opt = getopt(argc, argv, "vVhafpr:");    #endif    if (opt < 0) break;    switch (opt)    {      case 'V':        printf("gbi-" VERSION "\n");        exit(0);      case 'a':        all = TRUE;        break;      case 'v':        _verbose = TRUE;        break;      case 'f':        _format = TRUE;        break;      case 'p':        _nopreload = TRUE;        break;              case 'r':        strncpy(_root, optarg, MAX_PATH);        break;      case 'h':        printf(          "\n"          "GAMBAS Component Informer version " VERSION " " __DATE__ " " __TIME__ "\n"          COPYRIGHT          "Usage: gbi [options] <component name>\n"          "       gbi -a\n\n"          "Options:"          #ifdef __GNU_LIBRARY__          "\n"          "  -V  --version              display version\n"          "  -h  --help                 display this help\n"          "  -f  --format               format output in HTML\n"          "  -p                         disable preloading\n"          "  -a  --all                  generate info for every component\n"          "  -r  --root <directory>     gives the gambas installation directory\n"          #else          " (no long options on this system)\n"          "  -V                         display version\n"          "  -h                         display this help\n"          "  -f                         format output in HTML\n"          "  -p                         disable preloading\n"          "  -a                         generate info for every component\n"          "  -r  --root <directory>     gives the gambas installation directory\n"          #endif          "\n"          );        exit(0);    }  }  init(argv[0]);  if (!all)  {    if (optind == argc    #ifdef __sun__  /* solaris bug ? */        || optind == 0    #endif       )      error("gbi: no component specified.");    if (strncasecmp(argv[optind], "gb.qt", 5) == 0)      preload(argv, "libqt-mt.so.3");    else if (strncasecmp(argv[optind], "gb.qt.kde", 9) == 0)      preload(argv, "libkdecore.so.4");    sprintf(_buffer, LIB_PATTERN, _lib_path, argv[optind]);    out_info = stdout;    out_list = NULL;    analyze(_buffer);  }  else  {    preload(argv,      "libqt-mt.so.3 "      #if HAVE_KDE_COMPONENT      "libkdecore.so.4 "      #endif      );    dir = opendir(_lib_path);    if (dir == NULL)      error2("Cannot read directory", _lib_path);    save_fd = dup(STDOUT_FILENO);    while ((dirent = readdir(dir)) != NULL)    {      name = dirent->d_name;      if (strcmp(FILE_get_ext(name), "component"))        continue;      path_info = STR_copy(FILE_set_ext(FILE_cat(_info_path, &name[4], NULL), "info"));      out_info = fopen(path_info, "w");      if (!out_info)        error2("Cannot write file", path_info);      path_list = STR_copy(FILE_set_ext(FILE_cat(_info_path, &name[4], NULL), "list"));      out_list = fopen(path_list, "w");      if (!out_list)        error2("Cannot write file", path_list);      name = STR_copy(FILE_get_basename(&name[4]));      sprintf(_buffer, LIB_PATTERN, _lib_path, name);      res = analyze(_buffer);      fclose(out_info);      fclose(out_list);      if (res)      {        unlink(path_info);        unlink(path_list);      }      else        puts(path_info);      STR_free(path_info);      STR_free(path_list);      STR_free(name);    }    closedir(dir);  }  exit(0);}

⌨️ 快捷键说明

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