📄 gbx_subr_string.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 + -