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

📄 gbx_c_settings.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
字号:
/***************************************************************************  gbx_c_settings.c  (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_C_SETTINGS_C#include "gb_common.h"#include <pwd.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>#include "gb_common_case.h"#include "gb_error.h"#include "gb_buffer.h"#include "gb_file.h"#include "gbx_api.h"#include "gbx_project.h"#include "gbx_local.h"#include "gbx_number.h"#include "gbx_exec.h"#include "gbx_c_collection.h"#include "gbx_c_settings.h"/*#define DEBUG*/static char *_data;static long _ptr;static long _len;static char get_next_char(void){  if (_ptr >= _len)    return 0;  else    return _data[_ptr++];}static void next_line(void){  char c;    for(;;)  {    c = get_next_char();    if (c == '\n' || c == 0)      break;  }}static void unquote_string(VALUE *result, char *str, long len){  int i, j;  char c;    j = 0;  for (i = 0; i < len; i++)  {    c = str[i];    if (c == '\\')    {      i++;      c = str[i];      if (c == 'n')        c = '\n';    }        str[j++] = c;  }    if (len > 0)  {    result->type = T_STRING;    STRING_new_temp(&result->_string.addr, str, j);    result->_string.start = 0;    result->_string.len = j;  }  else  {    result->type = T_NULL;  }}static void from_string(VALUE *value, const char *addr, long len){  if (!DATE_from_string(addr, len, value, FALSE))    return;      if (!NUMBER_from_string(NB_READ_BOTH | NB_READ_HEX_BIN, addr, len, value))    return;      if (len == 0)  {    value->type = T_NULL;    return;  }    value->type = T_BOOLEAN;  value->_boolean.value = strchr("0FfNn", *addr) == NULL;}static bool check_key(const char *key, long len){  int i;  char c;    for (i = 0; i < len; i++)  {    c = key[i];    if (c <= ' ' || c == '=')    {          GB_Error("Bad key");      return TRUE;    }  }    return FALSE;}static void read_line(CSETTINGS *_object){  long p;  char c;  char *key;  long key_len;  char *val;  long val_len;  VALUE result;  p = _ptr;    for(;;)  {    c = get_next_char();    if (c < ' ' || c == '=')      break;  }    key = &_data[p];  key_len = _ptr - p - 1;    for(;;)  {    c = get_next_char();    if ((c > ' ' && c != '=') || c == 0 || c == '\n')      break;  }    p = _ptr - 1;  next_line();    val = &_data[p];  val_len = _ptr - p - 1;    #ifdef DEBUG  fprintf(stderr, "%.*s = %.*s\n", (int)key_len, key, (int)val_len, val);  #endif    result.type = T_NULL;    if (*val == '"')  {    val++;    val_len--;        if (val[val_len - 1] == '"')      val_len--;          unquote_string(&result, val, val_len);  }  else  {    result.type = T_CSTRING;    result._string.addr = val;    result._string.start = 0;    result._string.len = val_len;        from_string(&result, val, val_len);  }  if (result.type != T_NULL)  {      VALUE_conv(&result, T_VARIANT);    GB_CollectionSet(THIS->table, key, key_len, (GB_VARIANT *)&result);  }}static void load_config(CSETTINGS *_object){  char c;    #ifdef DEBUG  fprintf(stderr, "load_config: %s\n", THIS->path);  #endif  BUFFER_load_file(&_data, THIS->path);  if (!_data)    return;      _ptr = 0;  _len = BUFFER_length(_data);    for(;;)  {    c = get_next_char();        if (c == 0)      break;    if (c <= ' ')      continue;    if (c == '#')    {      next_line();      continue;    }        _ptr--;        read_line(THIS);  }    BUFFER_delete(&_data);}static void save_config(CSETTINGS *_object){  FILE *f;  HASH_ENUM iter;  HASH_TABLE *hash;  void *value;  char *str;  long len;  VALUE res;  int i;  char c;  if (!THIS->modified)    return;      #ifdef DEBUG  fprintf(stderr, "save_config: %s\n", THIS->path);  #endif    f = fopen(THIS->path, "w");  if (!f)  {    GB_Error((char *)E_OPEN, THIS->path, strerror(errno));    return;  }      fprintf(f, "# Gambas configuration file 1.0\n");  fprintf(f, "# for %s\n", PROJECT_name);    hash = ((CCOLLECTION *)THIS->table)->hash_table;    CLEAR(&iter);    for(;;)  {    value = HASH_TABLE_next(hash, &iter);    if (!value)      break;          HASH_TABLE_get_last_key(hash, &str, &len);    /*for (i = 0; i < len; i++)      fputc(tolower(str[i]), f);*/    fprintf(f, "%.*s=", (int)len, str);              #ifdef DEBUG    fprintf(stderr, "%.*s\n", (int)len, str);    #endif          VALUE_read(&res, value, T_VARIANT);    VARIANT_undo(&res);        if (TYPE_is_string(res.type))    {      VALUE_get_string(&res, &str, &len);      fputc('"', f);      for (i = 0; i < len; i++)      {        c = str[i];        if (c == '\n')          fprintf(f, "\\n");        else if (c == '\\' || c == '"')        {          fputc('\\', f);          fputc(c, f);        }        else          fputc(c, f);      }      fputc('"', f);    }    else if (res.type == T_BOOLEAN)    {      fputc(res._boolean.value ? '1' : '0', f);    }    else    {      VALUE_conv(&res, T_STRING);      VALUE_get_string(&res, &str, &len);      fprintf(f, "%.*s", (int)len, str);      RELEASE(&res);    }          fputc('\n', f);  }    fclose(f);    THIS->modified = FALSE;}BEGIN_METHOD(CSETTINGS_new, GB_STRING path)  char *path;  struct passwd *info;    if (MISSING(path))  {    info = getpwuid(getuid());    if (!info)    {      GB_Error((char *)E_MEMORY);      return;    }        mkdir(FILE_cat(info->pw_dir, ".gambas", NULL), S_IRWXU);      STRING_new(&path, FILE_cat(info->pw_dir, ".gambas", PROJECT_name, NULL), 0);    STRING_add(&path, ".conf", 0);  }  else  {    STRING_new(&path, STRING(path), LENGTH(path));  }    THIS->path = path;  /*HASH_TABLE_create(&THIS->table, TYPE_sizeof(T_VARIANT), GB_COMP_TEXT);*/  GB_CollectionNew(&THIS->table, GB_COMP_TEXT);  GB_Ref(THIS->table);    load_config(THIS);END_METHODBEGIN_METHOD_VOID(CSETTINGS_free)  save_config(THIS);  STRING_free(&THIS->path);  GB_Unref((void **)&THIS->table);END_METHODBEGIN_METHOD_VOID(CSETTINGS_save)  save_config(THIS);END_METHODBEGIN_METHOD(CSETTINGS_get, GB_STRING key; GB_VALUE def)  GB_VARIANT value;  if (GB_CollectionGet(THIS->table, STRING(key), LENGTH(key), &value))  {    if (MISSING(def))      GB_ReturnNull();    else      TEMP = *((VALUE *)ARG(def));  }  else      GB_ReturnPtr(T_VARIANT, &value.value);  END_METHODBEGIN_METHOD(CSETTINGS_put, GB_VARIANT value; GB_STRING key)  VALUE *val;  if (check_key(STRING(key), LENGTH(key)))    return;  val = (VALUE *)ARG(value);  if (TYPE_is_object(val->type)      || (TYPE_is_variant(val->type) && TYPE_is_object(val->_variant.vtype)))  {    GB_Error("Bad setting");    return;  }      GB_CollectionSet(THIS->table, STRING(key), LENGTH(key), ARG(value));  THIS->modified = TRUE;END_METHODPUBLIC GB_DESC NATIVE_Settings[] ={  GB_DECLARE("Settings", sizeof(CSETTINGS)),   GB_AUTO_CREATABLE(),  GB_METHOD("_new", NULL, CSETTINGS_new, "[(Path)s]"),  GB_METHOD("_free", NULL, CSETTINGS_free, NULL),  GB_METHOD("Save", NULL, CSETTINGS_save, NULL),  GB_METHOD("_get", "v", CSETTINGS_get, "(Key)s[(Default)v]"),  GB_METHOD("_put", NULL, CSETTINGS_put, "(Value)v(Key)s"),  GB_END_DECLARE};

⌨️ 快捷键说明

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