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

📄 gbx_api.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
字号:
/***************************************************************************  gambas_api.c  Gambas API for external libraries  (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_API_C#include "gb_common.h"#include "gb_common_case.h"#include "gb_error.h"#include "gb_alloc.h"#include <stdarg.h>#include "gbx_class.h"#include "gbx_exec.h"#include "gbx_event.h"#include "gbx_stack.h"#include "gbx_stream.h"#include "gbx_library.h"#include "gbx_watch.h"#include "gbx_project.h"#include "gbx_eval.h"#include "gbx_local.h"#include "gbx_hash.h"#include "gb_file.h"#include "gbx_number.h"#include "gbx_object.h"#include "gbx_string.h"#include "gbx_date.h"#include "gambas.h"#include "gbx_api.h"typedef  struct {    OBJECT *object;    CLASS_DESC_METHOD *desc;    }  GB_API_FUNCTION;PUBLIC void *GAMBAS_Api[] ={  (void *)GB_VERSION,  (void *)GB_GetInterface,  (void *)GB_Hook,  (void *)GB_LoadComponent,  (void *)GB_Push,  (void *)GB_GetFunction,  (void *)GB_Call,  (void *)GB_Raise,  (void *)GB_Post,  (void *)EVENT_check_post,  (void *)GB_CanRaise,  (void *)GB_GetEvent,  (void *)GB_NParam,  (void *)GB_Conv,  (void *)GB_GetUnknown,  (void *)GB_IsProperty,  (void *)GB_Error,  (void *)PROPAGATE,  (void *)GB_GetClass,  (void *)GB_GetClassName,  (void *)CLASS_look,  (void *)CLASS_find,  (void *)GB_Is,  (void *)GB_Ref,  (void *)GB_Unref,  (void *)GB_UnrefKeep,  (void *)GB_Detach,  (void *)GB_Attach,  (void *)GB_New,  (void *)CLASS_auto_create,  (void *)GB_CheckObject,  (void *)GB_GetEnum,  (void *)GB_StopEnum,  (void *)GB_Return,  (void *)GB_ReturnInt,  (void *)GB_ReturnBoolean,  (void *)GB_ReturnDate,  (void *)GB_ReturnObject,  (void *)GB_ReturnNull,  (void *)GB_ReturnFloat,  (void *)GB_ReturnPtr,  (void *)GB_ReturnString,  (void *)GB_ReturnConstString,  (void *)GB_ReturnConstZeroString,  (void *)GB_ReturnNewString,  (void *)GB_ReturnNewZeroString,  (void *)STRING_new,  (void *)GB_FreeString,  (void *)STRING_extend,  (void *)STRING_add,  (void *)GB_StringLength,  (void *)GB_ToZeroString,  (void *)NUMBER_from_string,  (void *)GB_NumberToString,  (void *)STRING_subst,  (void *)SUBST_add,  (void *)GB_ConvString,  (void *)STRING_conv_file_name,  (void *)GB_LoadFile,  (void *)GB_ReleaseFile,  (void *)FILE_exist,  (void *)GB_GetTempDir,  (void *)GB_Store,  (void *)GB_StoreString,  (void *)GB_StoreObject,  (void *)GB_StoreVariant,  (void *)DATE_split,  (void *)DATE_make,  (void *)DATE_from_time,  (void *)DATE_timer,  (void *)GB_Watch,  (void *)GB_Eval,  (void *)GB_Alloc,  (void *)GB_Free,  (void *)GB_Realloc,  (void *)GB_NewArray,  (void *)ARRAY_delete,  (void *)ARRAY_count,  (void *)GB_Add,    (void *)GB_SubCollectionNew,  (void *)GB_SubCollectionAdd,  (void *)GB_SubCollectionRemove,  (void *)GB_SubCollectionGet,  (void *)GB_SubCollectionContainer,    (void *)GB_tolower,  (void *)GB_toupper,  (void *)strcasecmp,  (void *)strncasecmp,  (void *)GB_AppName,  (void *)GB_AppTitle,  (void *)GB_AppVersion,  (void *)GB_AppPath,  (void *)GB_SystemCharset,  (void *)LOCAL_get_lang,  (void *)GB_ArrayNew,  (void *)GB_ArrayCount,  (void *)GB_ArrayAdd,  (void *)GB_ArrayGet,  (void *)GB_CollectionNew,  (void *)GB_CollectionCount,  (void *)GB_CollectionSet,  (void *)GB_CollectionGet,  (void *)GB_HashTableNew,  (void *)HASH_TABLE_delete,  (void *)HASH_TABLE_size,  (void *)GB_HashTableAdd,  (void *)GB_HashTableRemove,  (void *)GB_HashTableGet,  (void *)GB_HashTableEnum,  (void *)GB_StreamInit,  NULL};PUBLIC TYPE GAMBAS_ReturnType;PUBLIC bool GAMBAS_Error = FALSE;PUBLIC bool GAMBAS_DoNotRaiseEvent = FALSE;PUBLIC bool GAMBAS_StopEvent = FALSE;PUBLIC int GB_GetInterface(const char *name, long version, void *iface){  if (LIBRARY_get_interface_by_name(name, version, iface))    ERROR_panic("Cannot find interface of library '%s'", name);  return FALSE;}PUBLIC void *GB_Hook(int type, void *hook){  void *old_hook;  if ((type < GB_HOOK_MAIN) || (type > GB_HOOK_ERROR))    return NULL;  type--;  old_hook = ((void **)&EXEC_Hook)[type];  ((void **)&EXEC_Hook)[type] = hook;  return old_hook;}PUBLIC int GB_LoadComponent(const char *name){  int ret = 0;  TRY  {    LIBRARY *lib = LIBRARY_create(name);    LIBRARY_load(lib);  }  CATCH  {    ret = 1;    GAMBAS_Error = TRUE;  }  END_TRY  return ret;}PRIVATE void push(int nval, va_list args){  TYPE type;  STACK_check(nval);  while (nval)  {    type = va_arg(args, TYPE);    switch(type)    {      case T_INTEGER:      case T_BOOLEAN:        SP->type = type;        SP->_integer.value = va_arg(args, long);        break;      case T_STRING:        SP->type = T_CSTRING;        SP->_string.addr = va_arg(args, char *);        SP->_string.start = 0;        SP->_string.len = va_arg(args, long);        if (SP->_string.len <= 0 && SP->_string.addr)          SP->_string.len = strlen(SP->_string.addr);        break;      case T_FLOAT:        SP->type = type;        SP->_float.value = va_arg(args, double);        break;              case T_OBJECT:        SP->type = type;        SP->_object.object = va_arg(args, void *);        OBJECT_REF(SP->_object.object, "push");        break;      default:        ERROR_panic("GB.Push: unknown datatype = &1", type);        break;    }    SP++;    nval--;  }}PUBLIC void GB_Push(int nval, ...){  va_list args;  va_start(args, nval);  push(nval, args);  va_end(args);}PRIVATE void call_method(void *object, CLASS_DESC_METHOD *desc, int nparam){  if (OBJECT_is_class(object))  {    EXEC.object = NULL;    //EXEC.class = (CLASS *)object;  }  else  {    EXEC.object = object;    //EXEC.class = OBJECT_class(object);  }  EXEC.class = desc->class;  EXEC.nparam = nparam; /*desc->npmin;*/  EXEC.drop = FALSE;  if (FUNCTION_is_native(desc))  {    EXEC.native = TRUE;    EXEC.use_stack = FALSE;    EXEC.desc = desc;    EXEC_native();    SP--;    *RP = *SP;    SP->type = T_VOID;  }  else  {    EXEC.native = FALSE;    EXEC.index = (long)desc->exec;    //EXEC.func = &class->load->func[(long)desc->exec];    EXEC_function_keep();  }}PUBLIC int GB_CanRaise(void *object, int event_id){  OBJECT *parent;  ushort *event_tab;  int func_id;  if (object == NULL)    return FALSE;  event_tab = OBJECT_event(object)->event;  parent = OBJECT_event(object)->parent;  if (parent == NULL)    return FALSE;  func_id = event_tab[event_id];  if (func_id == 0)    return FALSE;  return TRUE;}PUBLIC int GB_Raise(void *object, int event_id, int nparam, ...){  OBJECT *parent;  CLASS *class;  int func_id;  CLASS_DESC_METHOD *desc;  ushort *event_tab;  int result;  va_list args;  void *old_last;  /*MEMORY_check_ptr(object);*/  if (GAMBAS_DoNotRaiseEvent)    return FALSE;  if (object == NULL)    return FALSE;  parent = OBJECT_event(object)->parent;  if (parent == NULL || OBJECT_is_locked(object))    return FALSE;      event_tab = OBJECT_event(object)->event;  func_id = event_tab[event_id];    if (!func_id)    return FALSE;    class = OBJECT_class(object);#if DEBUG_EVENT    printf("GB_Raise(%p, %d, %s, %p)\n", object, event_id, class->event[event_id].name, param);    printf("func_id = %d  parent = %p  parent class = %p\n", func_id, parent, parent->class);    fflush(NULL);#endif  if ((*parent->class->check)(parent))  {    OBJECT_detach(object);    return FALSE;  }    func_id--;  if (OBJECT_is_class(parent))    desc = &(((CLASS *)parent)->table[func_id].desc->method);  else    desc = &(parent->class->table[func_id].desc->method);  old_last = EVENT_Last;  EVENT_Last = object;  OBJECT_REF(object, "GB_Raise");  va_start(args, nparam);  push(nparam, args);  va_end(args);  call_method(parent, desc, nparam);  if (RP->type == T_VOID)    result = 0;  else    result = (RP->_boolean.value != 0 ? 1 : 0);  if (GAMBAS_StopEvent)  {    GAMBAS_StopEvent = FALSE;    result = 1;  }  EXEC_release_return_value();    OBJECT_UNREF(&object, "GB_Raise");  EVENT_Last = old_last;    return result;}PUBLIC long GB_GetEvent(void *class, char *name){  CLASS_DESC_EVENT *cd;  cd = CLASS_get_event_desc((CLASS *)class, name);  if (!cd)    return (-1);  else    return *cd->index;}PUBLIC void GB_Post(void (*func)(), long param){  EVENT_post(func, param);}PUBLIC int GB_NParam(void){  return EXEC.nparvar;}PUBLIC int GB_IsProperty(void){  return EXEC.property;}PUBLIC const char *GB_GetUnknown(void){  return CP->load->unknown[EXEC.index];}PUBLIC void GB_Error(const char *error, ...){  va_list args;  char *arg[8];  int i;  if (!error)  {    GAMBAS_Error = FALSE;    return;  }  va_start(args, error);  for (i = 0; i < 8; i++)    arg[i] = va_arg(args, char *);  ERROR_define(error, arg);  GAMBAS_Error = TRUE;}PUBLIC void GB_Ref(void *object){  #if TRACE_MEMORY  CLASS *save = CP;  CP = NULL;  #endif  if (object)    OBJECT_REF(object, "GB_Ref");  #if TRACE_MEMORY  CP = save;  #endif}PUBLIC void GB_Unref(void **object){  #if TRACE_MEMORY  CLASS *save = CP;  CP = NULL;  #endif  if (*object)    OBJECT_UNREF(object, "GB_Unref");  #if TRACE_MEMORY  CP = save;  #endif}PUBLIC void GB_UnrefKeep(void **object, int delete){  #if TRACE_MEMORY  CLASS *save = CP;  CP = NULL;  #endif  if (*object != NULL)  {    if (delete)    {      OBJECT_UNREF(object, "GB_UnrefKeep");    }    else    {      OBJECT_UNREF_KEEP(object, "GB_UnrefKeep");    }  }  #if TRACE_MEMORY  CP = save;  #endif}PUBLIC void GB_Detach(void *object){  if (object)    OBJECT_detach(object);}PUBLIC void GB_Attach(void *object, void *parent, const char *name){  if (object)    OBJECT_attach(object, parent, name);}PUBLIC void GB_StopEnum(void){  EXEC_enum_stop = TRUE;  VALUE_default(&TEMP, GAMBAS_ReturnType);}PUBLIC void *GB_GetEnum(void){  return (void *)EXEC_enum_data;}PUBLIC void GB_Return(ulong type, ...){  static void *jump[16] = {    &&__VOID, &&__BOOLEAN, &&__BYTE, &&__SHORT, &&__INTEGER, &&__LONG, &&__FLOAT, &&__DATE,    &&__STRING, &&__STRING, &&__VARIANT, &&__ARRAY, &&__STRUCT, &&__FUNCTION, &&__CLASS, &&__NULL    };  VALUE *ret = &TEMP;  va_list args;  va_start(args, type);  ret->type = type;  if (TYPE_is_object(type))    goto __OBJECT;  else    goto *jump[type];__BOOLEAN:  ret->_integer.value = va_arg(args, int) ? (-1) : 0;  goto __CONV;__BYTE:  ret->_integer.value = va_arg(args, int);  goto __CONV;__SHORT:  ret->_integer.value = va_arg(args, int);  goto __CONV;__INTEGER:  ret->_integer.value = va_arg(args, long);  goto __CONV;__FLOAT:  ret->_float.value = va_arg(args, double);  goto __CONV;__DATE:  ret->_date.date = va_arg(args, long);  ret->_date.time = va_arg(args, long);  goto __CONV;__OBJECT:  ret->_object.object = va_arg(args, void *);  goto __CONV;__CLASS:  ret->_class.class = va_arg(args, CLASS *);  goto __CONV;__CONV:  /*VALUE_conv(ret, GAMBAS_ReturnType);   Laisser l'appelant faire la conversion */__STRING:__VOID:__LONG:__VARIANT:__ARRAY:__STRUCT:__FUNCTION:__NULL:  return;}PUBLIC void GB_ReturnInt(long val){  GB_Return(T_INTEGER, val);}PUBLIC void GB_ReturnFloat(double val){  GB_Return(T_FLOAT, val);}PUBLIC void GB_ReturnDate(GB_DATE *date){  TEMP = *((VALUE *)date);  TEMP.type = T_DATE;}PUBLIC void GB_ReturnBoolean(int val){  GB_Return(T_BOOLEAN, val);}PUBLIC void GB_ReturnObject(void *val){  if (val == NULL)    GB_ReturnNull();  else if (GAMBAS_ReturnType == T_VARIANT)    GB_Return(T_OBJECT, val);  else    GB_Return(GAMBAS_ReturnType, val);}PUBLIC void GB_ReturnPtr(ulong type, void *value){  if (type == T_VOID)    return;  VALUE_read(&TEMP, value, type);  /*VALUE_conv(&TEMP, GAMBAS_ReturnType);*/}PUBLIC char *GB_ToZeroString(GB_STRING *src){  char *str;  STRING_new_temp(&str, src->value.addr + src->value.start, src->value.len);  if (str == NULL)    return "";  else    return str;}PUBLIC void GB_ReturnString(char *str){  TEMP.type = T_STRING;  TEMP._string.addr = str;  TEMP._string.start = 0;  TEMP._string.len = STRING_length(str);  if (TEMP._string.len == 0)    TEMP._string.addr = 0;}PUBLIC void GB_ReturnConstString(const char *str, long len){  TEMP.type = T_CSTRING;  TEMP._string.addr = (char *)str;  TEMP._string.start = 0;  TEMP._string.len = len;  if (TEMP._string.len == 0)    TEMP._string.addr = 0;}PUBLIC void GB_ReturnConstZeroString(const char *str){  long len;  if (str)    len = strlen(str);  else    len = 0;  GB_ReturnConstString(str, len);}PUBLIC void GB_ReturnNewString(const char *src, long len){  char *str;  STRING_new_temp(&str, src, len);  GB_ReturnString(str);}PUBLIC void GB_ReturnNewZeroString(const char *src){  GB_ReturnNewString(src, 0);}PUBLIC void GB_ReturnNull(void){  TEMP.type = T_NULL;}PUBLIC void *GB_GetClass(void *object){  if (object)    return OBJECT_class(object);  else    return EXEC.class;}PUBLIC char *GB_GetClassName(void *object){  CLASS *class = GB_GetClass(object);  return class->name;}PUBLIC int GB_Is(void *object, void *class){  CLASS *ob_class;  if (!object)    return FALSE;  ob_class = OBJECT_class(object);  return ((ob_class == class) || CLASS_inherits(ob_class, class));}PUBLIC int GB_LoadFile(const char *path, long lenp, char **addr, long *len){  int ret = 0;  TRY  {    *addr = 0;    STREAM_load(STRING_conv_file_name(path, lenp), addr, len);  }  CATCH  {    if (*addr)      GB_ReleaseFile(addr, *len);    GAMBAS_Error = TRUE;    ret = 1;  }  END_TRY  return ret;}PUBLIC void GB_ReleaseFile(char **addr, long len){  FREE(addr, "GB_ReleaseFile");}PUBLIC void GB_Store(GB_TYPE type, GB_VALUE *src, void *dst){  if (src != NULL)  {    /* Ne marche que parce que value->type == type apr鑣 un VALUE_read()       Sinon il y'aurait des probl鑝es de r閒閞ences - VALUE_write faisant       appel 

⌨️ 快捷键说明

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