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

📄 gbx_string.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
字号:
/***************************************************************************  String.c  The String 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 __STRING_C#include "gb_common.h"#include "gb_common_buffer.h"#include "gb_error.h"#include "gbx_value.h"#include "gbx_debug.h"#include "gbx_local.h"#include <ctype.h>#include <iconv.h>#include "gbx_string.h"#if DEBUG_STRING#define DEBUG_ME#endif#define STRING_last_count 32PRIVATE char *STRING_last[STRING_last_count] = { 0 };PRIVATE char _char_string[512] = { 0 };PRIVATE int _index = 0;void STRING_new(char **ptr, const char *src, int len){  STRING *str;  if (len <= 0 && src != NULL)    len = strlen(src);  if (len <= 0)  {    *ptr = NULL;    return;  }  ALLOC(&str, len + 1 + sizeof(STRING), "STRING_new");  str->len = len;  str->ref = 1;  if (src != NULL)    memcpy(str->data, src, len);  str->data[len] = 0;  *ptr = str->data;  #ifdef DEBUG_ME  TRACE_where();  printf("STRING_new %p ( 0 ) \"%.*s\"\n", *ptr, len, src);  fflush(NULL);  #endif}PRIVATE void post_free(char *ptr){  /*if (NLast >= MAX_LAST_STRING)    THROW(E_STRING);*/  #ifdef DEBUG_ME  if (STRING_last[_index])  {    TRACE_where();    printf("STRING: release temp: %p '%s'\n", STRING_last[_index], STRING_last[_index]);    fflush(NULL);  }  #endif  STRING_unref(&STRING_last[_index]);  #ifdef DEBUG_ME  printf("STRING: post temp: %p '%s'\n", ptr, ptr);  fflush(NULL);  #endif  STRING_last[_index] = ptr;  _index++;  if (_index >= STRING_last_count)    _index = 0;}PUBLIC long STRING_get_free_index(void){  return _index;}void STRING_new_temp(char **ptr, const char *src, int len){  STRING_new(ptr, src, len);  if (*ptr)    post_free(*ptr);}void STRING_exit(void){  int i;  for (i = 0; i < STRING_last_count; i++)  {    /*if (STRING_last[i])      printf("release temp %p '%s'\n", STRING_last[i], STRING_last[i]);*/    STRING_unref(&STRING_last[i]);    STRING_last[i] = NULL;  }  _index = 0;}void STRING_extend(char **ptr, int new_len){  STRING *str;  long len = STRING_length(*ptr);  if (new_len == len)    return;  if (new_len == 0)  {    STRING_free(ptr);    return;  }  if (len == 0)  {    ALLOC(&str, new_len + 1 + sizeof(STRING), "STRING_extend");    str->ref = 1;  }  else  {    str = STRING_from_ptr(*ptr);    REALLOC(&str, new_len + 1 + sizeof(STRING), "STRING_extend");  }  str->len = new_len;  *ptr = str->data;}void STRING_extend_end(char **ptr){  if (*ptr)  {    (*ptr)[STRING_length(*ptr)] = 0;    post_free(*ptr);  }}void STRING_copy_from_value_temp(char **ptr, VALUE *value){  if (value->_string.len == 0)    *ptr = NULL;  else if (value->type == T_STRING && value->_string.start == 0 && value->_string.len == STRING_length(value->_string.addr))    *ptr = value->_string.addr;  else    STRING_new_temp(ptr, &value->_string.addr[value->_string.start], value->_string.len);}/* Attention ! Contrairement �STRING_new, STRING_new_temp_value cr� des   cha�es temporaires.*/void STRING_new_temp_value(VALUE *value, const char *src, int len){  STRING_new_temp(&(value->_string.addr), src, len);  value->_string.len = STRING_length(value->_string.addr);  value->_string.start = 0;  value->type = T_STRING;}void STRING_new_constant_value(VALUE *value, const char *src, int len){  value->_string.addr = (char *)src;  value->_string.len = ((len < 0) ? strlen(src) : len);  value->_string.start = 0;  value->type = T_CSTRING;}void STRING_void_value(VALUE *value){  value->type = T_CSTRING;  value->_string.addr = NULL;  value->_string.start = 0;  value->_string.len = 0;}void STRING_char_value(VALUE *value, uchar car){  char *addr = &_char_string[(int)car * 2];  value->type = T_CSTRING;  value->_string.addr = addr;  value->_string.start = 0;  value->_string.len = 1;  *addr = car;}void STRING_free(char **ptr){  STRING *str;  if (*ptr == NULL)    return;  str = STRING_from_ptr(*ptr);  #ifdef DEBUG_ME  TRACE_where();  printf("STRING_free %p %p\n", *ptr, ptr);  fflush(NULL);  #endif  str->ref = 1000000000L;  FREE(&str, "STRING_free");  *ptr = NULL;  #ifdef DEBUG_ME  printf("OK\n");  #endif}int STRING_comp_value(VALUE *str1, VALUE *str2){  long i;  long len = Min(str1->_string.len, str2->_string.len);  long diff = str1->_string.len - str2->_string.len;  const char *s1;  const char *s2;  s1 = str1->_string.addr + str1->_string.start;  s2 = str2->_string.addr + str2->_string.start;  for (i = 0; i < len; i++)  {    if (*s1 > *s2) return 1;    if (*s1 < *s2) return -1;    s1++; s2++;  }  return (diff < 0) ? (-1) : (diff > 0) ? 1 : 0;}void STRING_ref(char *ptr){  STRING *str;  if (ptr == NULL)    return;  str = STRING_from_ptr(ptr);  #ifdef DEBUG_ME  TRACE_where();  printf("STRING_ref %p ( %ld -> %ld )\n", ptr, str->ref, str->ref + 1);  if (str->ref < 0 || str->ref > 10000)    printf("*** BAD\n");  fflush(NULL);  #endif  str->ref++;}void STRING_unref(char **ptr){  STRING *str;  if (*ptr == NULL)    return;  str = STRING_from_ptr(*ptr);  #ifdef DEBUG_ME  TRACE_where();  printf("STRING_unref %p ( %ld -> %ld )\n", *ptr, str->ref, str->ref - 1);  if (str->ref < 1 || str->ref > 10000)    printf("*** BAD\n");  fflush(NULL);  #endif  if ((--str->ref) <= 0)    STRING_free(ptr);}void STRING_unref_keep(char **ptr){  STRING *str;  if (*ptr == NULL)    return;  str = STRING_from_ptr(*ptr);  if (str->ref > 1)    str->ref--;  else    post_free(*ptr);}PUBLIC char *STRING_subst(const char *string, long len, SUBST_FUNC get_param){  const char *add;  long len_add;  unsigned char c;  int np;  char *par;  long len_par;  unsigned char next_char(void) { len--; return (unsigned char)*string++; }  if (!string)    return NULL;  SUBST_init();  if (len <= 0)    len = strlen(string);  if (len > 0)  {    add = string;    len_add = 0;    for(;;)    {      if (len == 0)      {        SUBST_add(add, len_add);        break;      }      c = next_char();      if (c != '&')      {        len_add++;        continue;      }    	SUBST_add(add, len_add);      add = string;      len_add = 0;      c = next_char();      if (!isdigit(c))      {      	if (c == '&')      	{      		add++;      		len_add++;				}				else        	len_add += 2;        continue;      }      np = (c - '0');      c = *string;      if (isdigit(c))      {        np = np * 10 + c - '0';        next_char();      }      par = NULL;      len_par = 0;      (*get_param)(np, &par, &len_par);      if (par)        SUBST_add(par, len_par);      add = string;    }  }  /* Avant, les release de SUBR_subst s'effectuaient ici... */  SUBST_exit();  return SUBST_buffer();}PUBLIC void STRING_add(char **ptr, const char *src, int len){  int old_len;  if (len <= 0 && src != NULL)    len = strlen(src);  if (len <= 0)    return;  old_len = STRING_length(*ptr);  STRING_extend(ptr, old_len + len);  memcpy(&((*ptr)[old_len]), src, len);  (*ptr)[old_len + len] = 0;}PUBLIC void STRING_conv(char **result, const char *str, long len, const char *src, const char *dst){  iconv_t handle;  bool err;  const char *in;  char *out;  size_t in_len;  size_t out_len;  int ret;  *result = NULL;  in = str;  in_len = len;  if (len == 0)    return;  if (!dst || *dst == 0)    dst = "ASCII";  if (!src || *src == 0)    src = "ASCII";  handle = iconv_open(dst, src);  if (handle == (iconv_t)(-1))  {    if (errno == EINVAL)      THROW(E_UCONV);    else      THROW(E_CONV);  }  err = FALSE;  for(;;)  {    out = COMMON_buffer;    out_len = COMMON_BUF_MAX;    #ifdef __sun__    ret = iconv(handle, &in, &in_len, &out, &out_len);    #else    ret = iconv(handle, (char **)&in, &in_len, &out, &out_len);    #endif    if (ret != (size_t)(-1 ) || errno == E2BIG)      STRING_add(result, COMMON_buffer, COMMON_BUF_MAX - out_len);    if (ret != (size_t)(-1))      break;    if (errno != E2BIG)    {      err = TRUE;      break;    }  }  iconv_close(handle);  STRING_extend_end(result);  if (err)    THROW(E_CONV);}PUBLIC char *STRING_conv_file_name(const char *name, long len){  char *result = NULL;  if (!name)    return "";  if (len <= 0)    len = strlen(name);  if (LOCAL_is_UTF8)    STRING_new_temp(&result, name, len);  else    STRING_conv(&result, name, len, "UTF-8", LOCAL_encoding);  if (result)    return result;  else    return "";}

⌨️ 快捷键说明

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