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

📄 gbx_subr_string.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
字号:
/***************************************************************************  subr_string.c  The String management subroutines  (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 "gb_common.h"#include "gb_common_buffer.h"#include "gb_common_case.h"#include <ctype.h>#include <regex.h>#include "gb_pcode.h"#include "gbx_value.h"#include "gbx_subr.h"#include "gbx_regexp.h"#include "gbx_class.h"#include "gbx_string.h"#include "gbx_c_array.h"PUBLIC void SUBR_cat(void){  int i;  long len, len_cat;  char *str, *ptr;  SUBR_ENTER();  len_cat = 0;  for (i = 0; i < NPARAM; i++)  {    VALUE_conv(&PARAM[i], T_STRING);    /*BORROW(&PARAM[i]);*/    len_cat += PARAM[i]._string.len;  }  STRING_new_temp(&str, NULL, len_cat);  ptr = str;  for (i = 0; i < NPARAM; i++)  {    len = PARAM[i]._string.len;    if (len > 0)    {      /*printf("add %p ", PARAM[i]._string.addr + PARAM[i]._string.start); fflush(NULL);      printf("%.*s\n", (int)len, PARAM[i]._string.addr + PARAM[i]._string.start);*/      memcpy(ptr, PARAM[i]._string.addr + PARAM[i]._string.start, len);      ptr += len;    }  }  /*printf("\n");*/  RETURN->type = T_STRING;  RETURN->_string.addr = str;  RETURN->_string.start = 0;  RETURN->_string.len = len_cat;  SUBR_LEAVE();}PUBLIC void SUBR_file(void){  int i;  long length;  char *addr;  long len;  char *str, *ptr;  boolean slash;  SUBR_ENTER();  length = 0;  slash = FALSE;  for (i = 0; i < NPARAM; i++)  {    /*VALUE_conv(&PARAM[i], T_STRING);*/    SUBR_get_string_len(&PARAM[i], &addr, &len);    if (len > 0)    {      if (length > 0)      {        if (!slash && (addr[0] != '/'))          length++;      }      slash = addr[len - 1] == '/';      length += len;    }  }  STRING_new_temp(&str, NULL, length);  ptr = str;  for (i = 0; i < NPARAM; i++)  {    VALUE_get_string(&PARAM[i], &addr, &len);    if (len > 0)    {      if ((ptr > str) && (ptr[-1] != '/') && (*addr != '/'))        *ptr++ = '/';      memcpy(ptr, addr, len);      ptr += len;    }  }  RETURN->type = T_STRING;  RETURN->_string.addr = str;  RETURN->_string.start = 0;  RETURN->_string.len = length;  SUBR_LEAVE();}PUBLIC void SUBR_left(void){  long val;  SUBR_ENTER();  if (SUBR_check_string(PARAM))    goto _FIN;  if (NPARAM == 1)    val = 1;  else  {    VALUE_conv(&PARAM[1], T_INTEGER);    val = PARAM[1]._integer.value;  }  if (val < 0)    val += PARAM->_string.len;  PARAM->_string.len = MinMax(val, 0, PARAM->_string.len);_FIN:  SP -= NPARAM;  SP++;}PUBLIC void SUBR_right(void){  long val;  long new_len;  SUBR_ENTER();  if (SUBR_check_string(PARAM))    goto _FIN;  if (NPARAM == 1)    val = 1;  else  {    VALUE_conv(&PARAM[1], T_INTEGER);    val = PARAM[1]._integer.value;  }  if (val < 0)    val += PARAM->_string.len;  new_len = MinMax(val, 0, PARAM->_string.len);  PARAM->_string.start += PARAM->_string.len - new_len;  PARAM->_string.len = new_len;_FIN:  SP -= NPARAM;  SP++;}PUBLIC void SUBR_mid(void){  long start;  long len;  SUBR_ENTER();  if (SUBR_check_string(PARAM))    goto FIN;  VALUE_conv(&PARAM[1], T_INTEGER);  start = PARAM[1]._integer.value - 1;  if (start < 0)    THROW(E_ARG);  if (start >= PARAM->_string.len)  {    RELEASE(PARAM);    STRING_void_value(PARAM);    goto FIN;  }  if (NPARAM == 2)    len = PARAM->_string.len;  else  {    VALUE_conv(&PARAM[2], T_INTEGER);    len = PARAM[2]._integer.value;  }  if (len < 0)    len = Max(0, PARAM->_string.len - start + len);  len = MinMax(len, 0, PARAM->_string.len - start);  if (len == 0)  {    RELEASE(PARAM);    PARAM->_string.addr = NULL;    PARAM->_string.start = 0;  }  else    PARAM->_string.start += start;  PARAM->_string.len = len;FIN:  SP -= NPARAM;  SP++;}PUBLIC void SUBR_len(void){  long len;  SUBR_GET_PARAM(1);  if (SUBR_check_string(PARAM))    len = 0;  else    len = PARAM->_string.len;  RELEASE(PARAM);  PARAM->type = T_INTEGER;  PARAM->_integer.value = len;}PUBLIC void SUBR_space(void){  int len;  SUBR_ENTER_PARAM(1);  SUBR_check_integer(PARAM);  len = PARAM->_integer.value;  if (len < 0)    THROW(E_ARG);  if (len == 0)  {    STRING_void_value(RETURN);  }  else  {    STRING_new_temp_value(RETURN, NULL, len);    memset(RETURN->_string.addr, ' ', len);  }  SUBR_LEAVE();}PUBLIC void SUBR_string(void){  int i;  char *d;  char *s;  long ld, ls;  SUBR_ENTER_PARAM(2);  SUBR_check_integer(PARAM);  SUBR_get_string_len(&PARAM[1], &s, &ls);  ld = PARAM->_integer.value * ls;  if (ld < 0)    THROW(E_ARG);  if (ld == 0)  {    STRING_void_value(RETURN);  }  else  {    STRING_new_temp_value(RETURN, NULL, ld);    d = RETURN->_string.addr;    for (i = 0; i < PARAM->_integer.value; i++)    {      memcpy(d, s, ls);      d += ls;    }    *d = 0;  }  SUBR_LEAVE();}PUBLIC void SUBR_trim(void){  unsigned char *str;  bool left, right;  int code;  SUBR_GET_PARAM(1);  if (SUBR_check_string(PARAM))    return;  code = EXEC_code & 0x1F;  left = (code == 0 || code == 1);  right = (code == 0 || code == 2);  if (!(left || right))    THROW(E_ILLEGAL);  if (PARAM->_string.len > 0)  {    str = (uchar *)&PARAM->_string.addr[PARAM->_string.start];    if (left)    {      while (PARAM->_string.len > 0 && *str <= ' ')      {        PARAM->_string.start++;        PARAM->_string.len--;        str++;      }    }    if (right)    {      while (PARAM->_string.len > 0 && str[PARAM->_string.len - 1] <= ' ')      {        PARAM->_string.len--;      }    }  }}#define STRING_APPLY(_func) \  char *str; \  int len, i; \  \  SUBR_ENTER_PARAM(1); \   \  if (SUBR_check_string(PARAM)) \    STRING_void_value(RETURN); \  else \  { \    len = PARAM->_string.len; \    if (len > 0) \    { \      STRING_new_temp(&str, &PARAM->_string.addr[PARAM->_string.start], PARAM->_string.len); \      \      for (i = 0; i < len; i++) \        str[i] = _func(str[i]); \        \      RETURN->type = T_STRING; \      RETURN->_string.addr = str; \      RETURN->_string.start = 0; \      RETURN->_string.len = len; \    } \  } \  \  SUBR_LEAVE();PUBLIC void SUBR_upper(void){  STRING_APPLY(toupper);}PUBLIC void SUBR_lower(void){  STRING_APPLY(tolower);}PUBLIC void SUBR_chr(void){  int car;  SUBR_GET_PARAM(1);  VALUE_conv(PARAM, T_INTEGER);  /*SUBR_check_integer(PARAM);*/  car = PARAM->_integer.value;  if (car < 0 || car > 255)    THROW(E_ARG);  STRING_char_value(PARAM, car);}PUBLIC void SUBR_asc(void){  int pos = 0;  SUBR_ENTER();  if (!SUBR_check_string(PARAM))  {    pos = 1;    if (NPARAM == 2)    {      SUBR_check_integer(&PARAM[1]);      pos = PARAM[1]._integer.value;    }    if (pos < 1 || pos > PARAM->_string.len)      pos = 0;    else      pos = (unsigned char)PARAM->_string.addr[PARAM->_string.start + pos - 1];  }  RETURN->type = T_INTEGER;  RETURN->_integer.value = pos;  SUBR_LEAVE();}PRIVATE long instr(const char *ps, long ls, const char *pp, long lp, long is, boolean right){  long pos = 0, ip;  if (lp > ls)    goto FOUND;  ls = ls - lp + 1; /* Longueur du d�ut du texte o effectuer la recherche */  if (is < 0)    is = ls - is;  else if (is == 0)    is = right ? ls : 1;  else if (is > ls)    goto FOUND;  is--;  ps += is;  if (right)  {    for (; is >= 0; is--, ps--)    {      for (ip = 0; ip < lp; ip++)      {        if (ps[ip] != pp[ip])          goto NEXT_R;      }      pos = is + 1;      goto FOUND;  NEXT_R:    ;    }  }  else  {    for (; is < ls; is++, ps++)    {      for (ip = 0; ip < lp; ip++)      {        if (ps[ip] != pp[ip])          goto NEXT_L;      }      pos = is + 1;      goto FOUND;  NEXT_L:    ;    }  }FOUND:  return pos;}PUBLIC void SUBR_instr(void){  boolean right;  long is, pos;  char *ps, *pp;  long ls, lp;  SUBR_ENTER();  /* Knuth Morris Pratt un jour peut-�re ? */  pos = 0;  /* /!\ | et pas ||, car on veut que les deux fonctions soient ex�ut�s */  if (SUBR_check_string(PARAM) | SUBR_check_string(&PARAM[1]))    goto FOUND;  lp = PARAM[1]._string.len;  ls = PARAM->_string.len;  right = ((EXEC_code >> 8) == CODE_RINSTR);  if (lp > ls) goto FOUND;  is = 0;  if (NPARAM == 3)  {    SUBR_check_integer(&PARAM[2]);    is = PARAM[2]._integer.value;  }  ps = PARAM->_string.addr + PARAM->_string.start;  pp = PARAM[1]._string.addr + PARAM[1]._string.start;  pos = instr(ps, ls, pp, lp, is, right);FOUND:  RETURN->type = T_INTEGER;  RETURN->_integer.value = pos;  SUBR_LEAVE();}PUBLIC void SUBR_like(void){  char *pattern;  char *string;  long len_pattern, len_string;  boolean ret;  SUBR_ENTER_PARAM(2);  SUBR_get_string_len(&PARAM[0], &string, &len_string);  SUBR_get_string_len(&PARAM[1], &pattern, &len_pattern);  ret = REGEXP_match(pattern, len_pattern, string, len_string) ? -1 : 0;  RETURN->type = T_BOOLEAN;  RETURN->_boolean.value = ret;  SUBR_LEAVE();}PRIVATE int subst_nparam;PRIVATE VALUE *subst_param;PRIVATE void get_subst(int np, char **str, long *len){  if (np > 0 && np < subst_nparam)    VALUE_get_string(&subst_param[np], str, len);  else  {    *str = NULL;    *len = 0;  }}PUBLIC void SUBR_subst(void){  char *string;  long len;  int np;  SUBR_ENTER();  SUBR_get_string_len(&PARAM[0], &string, &len);  for (np = 1; np < NPARAM; np++)    VALUE_conv(&PARAM[np], T_STRING);  subst_param = PARAM;  subst_nparam = NPARAM;  string = STRING_subst(string, len, get_subst);  for (np = 0; np < NPARAM; np++)    RELEASE_STRING(&PARAM[np]);  RETURN->type = T_STRING;  RETURN->_string.addr = (char *)string;  RETURN->_string.start = 0;  RETURN->_string.len = STRING_length(string);  SUBR_LEAVE();}PUBLIC void SUBR_replace(void){  char *ps;  char *pp;  char *pr;  long ls, lp, lr;  long is, pos;  SUBR_ENTER_PARAM(3);  SUBR_get_string_len(&PARAM[0], &ps, &ls);  SUBR_get_string_len(&PARAM[1], &pp, &lp);  SUBR_get_string_len(&PARAM[2], &pr, &lr);  SUBST_init();  if (ls)  {    is = 0;    if (lp)    {      for(;;)      {        pos = instr(ps, ls, pp, lp, 1, FALSE);        if (pos == 0)          break;        pos--;        if (pos > 0)          SUBST_add(ps, pos);        SUBST_add(pr, lr);        pos += lp;        ps += pos;        ls -= pos;        if (ls <= 0)          break;      }    }    SUBST_add(ps, ls);  }  RETURN->type = T_STRING;  RETURN->_string.addr = SUBST_buffer();  RETURN->_string.start = 0;  RETURN->_string.len = STRING_length(RETURN->_string.addr);  SUBST_exit();  SUBR_LEAVE();}PUBLIC void SUBR_split(void){  CARRAY *array;  char *str;  char *sep = "";  char *esc = "";  SUBR_ENTER();  str = SUBR_get_string(&PARAM[0]);  if (NPARAM >= 2)  {    sep = SUBR_get_string(&PARAM[1]);    if (NPARAM == 3)      esc = SUBR_get_string(&PARAM[2]);  }  OBJECT_create((void **)&array, CLASS_StringArray, NULL, NULL, 0);  if (*str)  {    STRING_ref(str);    if (*sep) STRING_ref(sep);    if (*esc) STRING_ref(esc);    CARRAY_split(array, str, sep, esc);    STRING_unref(&str);    if (*sep) STRING_unref(&sep);    if (*esc) STRING_unref(&esc);  }  RETURN->_object.class = CLASS_StringArray;  RETURN->_object.object = array;  SUBR_LEAVE();}PUBLIC void SUBR_sconv(void){  char *str;  const char *src;  const char *dst;  char *result;  long len;  SUBR_ENTER_PARAM(3);  str = SUBR_get_string(&PARAM[0]);  len = PARAM[0]._string.len;  src = SUBR_get_string(&PARAM[1]);  dst = SUBR_get_string(&PARAM[2]);  STRING_conv(&result, str, len, src, dst);  if (!result)    RETURN->type = T_NULL;  else  {    RETURN->type = T_STRING;    RETURN->_string.addr = result;    RETURN->_string.start = 0;    RETURN->_string.len = STRING_length(result);  }  SUBR_LEAVE();}

⌨️ 快捷键说明

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