2007-12-30 17:41:49 +01:00
|
|
|
/***************************************************************************
|
|
|
|
|
2009-08-17 12:41:51 +02:00
|
|
|
gbx_subr_string.c
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2018-02-12 02:53:46 +01:00
|
|
|
(c) 2000-2017 Benoît Minisini <g4mba5@gmail.com>
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-08-17 12:41:51 +02:00
|
|
|
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 2, or (at your option)
|
|
|
|
any later version.
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-08-17 12:41:51 +02:00
|
|
|
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.
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-08-17 12:41:51 +02:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
2011-06-03 02:51:09 +02:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
2011-12-31 03:39:20 +01:00
|
|
|
MA 02110-1301, USA.
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#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"
|
2014-05-23 13:52:04 +02:00
|
|
|
#include "gbx_split.h"
|
2007-12-30 17:41:49 +01:00
|
|
|
#include "gbx_c_array.h"
|
|
|
|
#include "gbx_local.h"
|
|
|
|
#include "gbx_compare.h"
|
|
|
|
|
2012-09-17 13:13:32 +02:00
|
|
|
//static int _count = 0;
|
|
|
|
|
2013-07-13 01:57:53 +02:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_cat(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER();
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2020-04-04 16:18:10 +02:00
|
|
|
if (NPARAM <= 2)
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
2011-09-08 18:01:36 +02:00
|
|
|
int len, len2;
|
|
|
|
char *str;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2020-04-04 16:18:10 +02:00
|
|
|
if (NPARAM == 1)
|
|
|
|
{
|
|
|
|
PARAM--;
|
|
|
|
len = PARAM[0]._string.len ;
|
|
|
|
VALUE_conv_string(&PARAM[1]);
|
|
|
|
len2 = PARAM[1]._string.len;
|
|
|
|
|
|
|
|
str = PARAM[0]._string.addr;
|
|
|
|
if (len && PARAM[0]._string.start == 0 && len == STRING_length(str) && STRING_from_ptr(str)->ref == 2)
|
|
|
|
{
|
|
|
|
STRING_from_ptr(str)->ref--;
|
|
|
|
str = STRING_add(str, PARAM[1]._string.addr + PARAM[1]._string.start, len2);
|
|
|
|
|
2020-04-06 04:40:47 +02:00
|
|
|
if (PCODE_is(PC[1], C_POP_LOCAL))
|
2020-04-04 16:18:10 +02:00
|
|
|
{
|
|
|
|
VALUE *bp = &BP[(signed char)PC[1]];
|
|
|
|
bp->_string.addr = str;
|
|
|
|
bp->_string.len += len2;
|
|
|
|
}
|
2020-04-06 04:40:47 +02:00
|
|
|
else if (PCODE_is(PC[1], C_POP_PARAM))
|
|
|
|
{
|
|
|
|
VALUE *pp = &PP[(signed char)PC[1]];
|
|
|
|
pp->_string.addr = str;
|
|
|
|
pp->_string.len += len2;
|
|
|
|
}
|
2020-04-04 16:18:10 +02:00
|
|
|
else if (PCODE_is(PC[1], C_POP_STATIC))
|
|
|
|
{
|
|
|
|
CLASS_VAR *var = &CP->load->stat[PC[1] & 0x7FF];
|
|
|
|
*(char **)((char *)CP->stat + var->pos) = str;
|
|
|
|
}
|
|
|
|
else if (PCODE_is(PC[1], C_POP_DYNAMIC))
|
|
|
|
{
|
|
|
|
CLASS_VAR *var = &CP->load->dyn[PC[1] & 0x7FF];
|
|
|
|
*(char **)(OP + var->pos) = str;
|
|
|
|
}
|
|
|
|
|
|
|
|
RELEASE_STRING(&PARAM[1]);
|
|
|
|
SP -= 2;
|
|
|
|
PC++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
VALUE_conv_string(&PARAM[0]);
|
|
|
|
len = PARAM[0]._string.len ;
|
|
|
|
VALUE_conv_string(&PARAM[1]);
|
|
|
|
len2 = PARAM[1]._string.len;
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2011-09-08 18:01:36 +02:00
|
|
|
str = STRING_new(NULL, len + len2);
|
2012-09-17 13:13:32 +02:00
|
|
|
|
|
|
|
//fprintf(stderr, "normal: str = %p p0 = %p p1 = %p\n", str, PARAM[0]._string.addr + PARAM[0]._string.start, PARAM[1]._string.addr + PARAM[1]._string.start);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2011-09-08 18:01:36 +02:00
|
|
|
memcpy(str, PARAM[0]._string.addr + PARAM[0]._string.start, len);
|
|
|
|
memcpy(&str[len], PARAM[1]._string.addr + PARAM[1]._string.start, len2);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-09-17 13:13:32 +02:00
|
|
|
RELEASE_STRING(&PARAM[0]);
|
2011-09-08 18:01:36 +02:00
|
|
|
RELEASE_STRING(&PARAM[1]);
|
|
|
|
|
|
|
|
SP -= 2;
|
|
|
|
SP->type = T_STRING;
|
|
|
|
SP->_string.addr = str;
|
|
|
|
SP->_string.start = 0;
|
|
|
|
SP->_string.len = len + len2;
|
|
|
|
SP++;
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
2011-09-08 18:01:36 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int len, len_cat;
|
|
|
|
char *str, *ptr;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-09-08 18:01:36 +02:00
|
|
|
len_cat = 0;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-09-08 18:01:36 +02:00
|
|
|
for (i = 0; i < NPARAM; i++)
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
2011-09-08 18:01:36 +02:00
|
|
|
VALUE_conv_string(&PARAM[i]);
|
|
|
|
len_cat += PARAM[i]._string.len;
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-09-08 18:01:36 +02:00
|
|
|
str = STRING_new(NULL, len_cat);
|
|
|
|
ptr = str;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-09-08 18:01:36 +02:00
|
|
|
i = NPARAM;
|
|
|
|
while (i--)
|
|
|
|
{
|
|
|
|
len = PARAM->_string.len;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2011-09-08 18:01:36 +02:00
|
|
|
if (len)
|
|
|
|
{
|
|
|
|
memcpy(ptr, PARAM->_string.addr + PARAM->_string.start, len);
|
|
|
|
ptr += len;
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2011-09-08 18:01:36 +02:00
|
|
|
RELEASE_STRING(PARAM);
|
|
|
|
PARAM++;
|
|
|
|
}
|
|
|
|
|
|
|
|
SP -= NPARAM;
|
|
|
|
SP->type = T_STRING;
|
|
|
|
SP->_string.addr = str;
|
|
|
|
SP->_string.start = 0;
|
|
|
|
SP->_string.len = len_cat;
|
|
|
|
SP++;
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_file(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
int i;
|
|
|
|
int length;
|
|
|
|
char *addr;
|
|
|
|
int len;
|
|
|
|
char *str, *ptr;
|
2009-07-08 21:57:50 +02:00
|
|
|
bool slash;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER();
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
length = 0;
|
|
|
|
slash = FALSE;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
for (i = 0; i < NPARAM; i++)
|
|
|
|
{
|
2019-08-21 22:36:54 +02:00
|
|
|
VALUE_conv_string(&PARAM[i]);
|
2019-08-22 12:36:52 +02:00
|
|
|
VALUE_get_string(&PARAM[i], &addr, &len);
|
2019-08-21 22:36:54 +02:00
|
|
|
//SUBR_get_string_len(&PARAM[i], &addr, &len);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2019-08-22 12:36:52 +02:00
|
|
|
if (addr && len > 0)
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
|
|
|
if (length > 0)
|
|
|
|
{
|
2009-09-27 11:28:52 +02:00
|
|
|
if (!slash && addr[0] != '/')
|
2009-01-02 01:05:38 +01:00
|
|
|
length++;
|
2009-09-27 11:28:52 +02:00
|
|
|
else if (slash && addr[0] == '/')
|
|
|
|
length--;
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
slash = addr[len - 1] == '/';
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
length += len;
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
str = STRING_new(NULL, length);
|
2009-01-02 01:05:38 +01:00
|
|
|
ptr = str;
|
2009-09-27 11:28:52 +02:00
|
|
|
slash = FALSE;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-06-09 01:08:04 +02:00
|
|
|
i = NPARAM;
|
|
|
|
while (i--)
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
2012-05-13 01:49:07 +02:00
|
|
|
if (PARAM->type != T_NULL)
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
2012-05-13 01:49:07 +02:00
|
|
|
VALUE_get_string(PARAM, &addr, &len);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-13 01:49:07 +02:00
|
|
|
if (len > 0)
|
2009-09-27 11:28:52 +02:00
|
|
|
{
|
2012-05-13 01:49:07 +02:00
|
|
|
if (ptr > str)
|
|
|
|
{
|
|
|
|
if (!slash && *addr != '/')
|
|
|
|
*ptr++ = '/';
|
|
|
|
else if (slash && *addr == '/')
|
|
|
|
ptr--;
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-13 01:49:07 +02:00
|
|
|
slash = addr[len - 1] == '/';
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-13 01:49:07 +02:00
|
|
|
memcpy(ptr, addr, len);
|
|
|
|
ptr += len;
|
2009-09-27 11:28:52 +02:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2012-05-13 01:49:07 +02:00
|
|
|
RELEASE_STRING(PARAM);
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2010-06-09 01:08:04 +02:00
|
|
|
PARAM++;
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SP -= NPARAM;
|
2010-06-05 01:48:53 +02:00
|
|
|
SP->type = T_STRING;
|
|
|
|
SP->_string.addr = str;
|
|
|
|
SP->_string.start = 0;
|
|
|
|
SP->_string.len = length;
|
2009-01-02 01:05:38 +01:00
|
|
|
SP++;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-01-17 22:39:26 +01:00
|
|
|
void SUBR_space(void)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
int len;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER_PARAM(1);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_check_integer(PARAM);
|
|
|
|
len = PARAM->_integer.value;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (len < 0)
|
|
|
|
THROW(E_ARG);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (len == 0)
|
|
|
|
{
|
2012-02-27 00:07:14 +01:00
|
|
|
STRING_void_value(&SP[-1]);
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-02-27 00:07:14 +01:00
|
|
|
char *str = STRING_new(NULL, len);
|
|
|
|
memset(str, ' ', len);
|
|
|
|
SP--;
|
|
|
|
SP->type = T_STRING;
|
|
|
|
SP->_string.addr = str;
|
|
|
|
SP->_string.start = 0;
|
|
|
|
SP->_string.len = len;
|
|
|
|
SP++;
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2012-02-27 00:07:14 +01:00
|
|
|
//SUBR_LEAVE();
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-01-17 22:39:26 +01:00
|
|
|
void SUBR_string(void)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
int i;
|
|
|
|
char *d;
|
|
|
|
char *s;
|
|
|
|
int 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;
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
*d = 0;
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_LEAVE();
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_trim(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
unsigned char *str;
|
|
|
|
bool left, right;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_GET_PARAM(1);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (SUBR_check_string(PARAM))
|
2011-09-06 04:32:34 +02:00
|
|
|
{
|
2011-09-06 22:47:26 +02:00
|
|
|
VOID_STRING(PARAM);
|
2009-01-02 01:05:38 +01:00
|
|
|
return;
|
2011-09-06 04:32:34 +02:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
code &= 0x1F;
|
2009-01-02 01:05:38 +01:00
|
|
|
left = (code == 0 || code == 1);
|
|
|
|
right = (code == 0 || code == 2);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (PARAM->_string.len > 0)
|
|
|
|
{
|
|
|
|
str = (uchar *)&PARAM->_string.addr[PARAM->_string.start];
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (left)
|
|
|
|
{
|
|
|
|
while (PARAM->_string.len > 0 && *str <= ' ')
|
|
|
|
{
|
|
|
|
PARAM->_string.start++;
|
|
|
|
PARAM->_string.len--;
|
|
|
|
str++;
|
|
|
|
}
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (right)
|
|
|
|
{
|
|
|
|
while (PARAM->_string.len > 0 && str[PARAM->_string.len - 1] <= ' ')
|
|
|
|
{
|
|
|
|
PARAM->_string.len--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2010-11-24 02:30:36 +01:00
|
|
|
void SUBR_upper(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2010-11-24 02:30:36 +01:00
|
|
|
char *str;
|
|
|
|
int len, i;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2010-11-24 02:30:36 +01:00
|
|
|
SUBR_ENTER_PARAM(1);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2010-11-24 02:30:36 +01:00
|
|
|
if (SUBR_check_string(PARAM))
|
2014-04-10 23:56:07 +02:00
|
|
|
{
|
|
|
|
VOID_STRING(&SP[-1]);
|
|
|
|
}
|
2010-11-24 02:30:36 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
len = PARAM->_string.len;
|
|
|
|
if (len > 0)
|
|
|
|
{
|
2012-02-27 00:07:14 +01:00
|
|
|
str = STRING_new(&PARAM->_string.addr[PARAM->_string.start], PARAM->_string.len);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2010-11-24 02:30:36 +01:00
|
|
|
if (code & 0x3F)
|
|
|
|
{
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
str[i] = tolower(str[i]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
str[i] = toupper(str[i]);
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-02-27 00:07:14 +01:00
|
|
|
SP--;
|
|
|
|
RELEASE_STRING(SP);
|
|
|
|
SP->type = T_STRING;
|
|
|
|
SP->_string.addr = str;
|
|
|
|
SP->_string.start = 0;
|
|
|
|
SP->_string.len = len;
|
|
|
|
SP++;
|
2010-11-24 02:30:36 +01:00
|
|
|
}
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2008-01-17 22:39:26 +01:00
|
|
|
void SUBR_chr(void)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
int car;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_GET_PARAM(1);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-06-03 01:23:50 +02:00
|
|
|
VALUE_conv_integer(PARAM);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
car = PARAM->_integer.value;
|
|
|
|
if (car < 0 || car > 255)
|
|
|
|
THROW(E_ARG);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
STRING_char_value(PARAM, car);
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_asc(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
int pos = 0;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER();
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (!SUBR_check_string(PARAM))
|
|
|
|
{
|
|
|
|
pos = 1;
|
|
|
|
if (NPARAM == 2)
|
|
|
|
{
|
|
|
|
SUBR_check_integer(&PARAM[1]);
|
|
|
|
pos = PARAM[1]._integer.value;
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (pos < 1 || pos > PARAM->_string.len)
|
|
|
|
pos = 0;
|
|
|
|
else
|
|
|
|
pos = (unsigned char)PARAM->_string.addr[PARAM->_string.start + pos - 1];
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
RETURN->type = T_INTEGER;
|
|
|
|
RETURN->_integer.value = pos;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_LEAVE();
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_instr(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-07-08 21:57:50 +02:00
|
|
|
bool right, nocase = FALSE;
|
2009-01-02 01:05:38 +01:00
|
|
|
int is, pos;
|
2018-06-12 16:30:11 +02:00
|
|
|
//int pos2;
|
2009-01-02 01:05:38 +01:00
|
|
|
char *ps, *pp;
|
|
|
|
int ls, lp;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER();
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
pos = 0;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (SUBR_check_string(PARAM))
|
|
|
|
goto __FOUND;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (SUBR_check_string(&PARAM[1]))
|
|
|
|
goto __FOUND;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
lp = PARAM[1]._string.len;
|
|
|
|
ls = PARAM->_string.len;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
right = ((code >> 8) == CODE_RINSTR);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (lp > ls) goto __FOUND;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
is = 0;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (NPARAM >= 3)
|
|
|
|
is = SUBR_get_integer(&PARAM[2]);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (NPARAM == 4)
|
2010-02-08 00:10:41 +01:00
|
|
|
nocase = SUBR_get_integer(&PARAM[3]) == GB_COMP_NOCASE;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
ps = PARAM->_string.addr + PARAM->_string.start;
|
|
|
|
pp = PARAM[1]._string.addr + PARAM[1]._string.start;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
pos = STRING_search(ps, ls, pp, lp, is, right, nocase);
|
2018-06-12 16:30:11 +02:00
|
|
|
/*pos2 = STRING_search2(ps, ls, pp, lp, is, right, nocase);
|
|
|
|
|
|
|
|
if (pos != pos2)
|
|
|
|
{
|
|
|
|
for(;;)
|
|
|
|
usleep(1000);
|
|
|
|
}*/
|
2007-12-30 17:41:49 +01:00
|
|
|
|
|
|
|
__FOUND:
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
RELEASE_STRING(PARAM);
|
|
|
|
RELEASE_STRING(&PARAM[1]);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
SP -= NPARAM;
|
|
|
|
SP->type = T_INTEGER;
|
|
|
|
SP->_integer.value = pos;
|
|
|
|
SP++;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_like(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2013-07-13 01:57:53 +02:00
|
|
|
static const void *jump[] = { &&__LIKE, &&__BEGINS, &&__ENDS, &&__MATCH };
|
2009-01-02 01:05:38 +01:00
|
|
|
char *pattern;
|
|
|
|
char *string;
|
|
|
|
int len_pattern, len_string;
|
2009-09-27 11:28:52 +02:00
|
|
|
bool ret = FALSE;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER_PARAM(2);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_get_string_len(&PARAM[0], &string, &len_string);
|
|
|
|
SUBR_get_string_len(&PARAM[1], &pattern, &len_pattern);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
goto *jump[code & 0x3];
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-09-27 11:28:52 +02:00
|
|
|
__LIKE:
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2010-12-29 09:21:51 +01:00
|
|
|
ret = REGEXP_match(pattern, len_pattern, string, len_string);
|
2009-09-27 11:28:52 +02:00
|
|
|
goto __RETURN;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-09-27 11:28:52 +02:00
|
|
|
__BEGINS:
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-09-27 11:28:52 +02:00
|
|
|
if (len_pattern == 0)
|
|
|
|
ret = TRUE;
|
|
|
|
else if (len_pattern <= len_string)
|
|
|
|
ret = STRING_equal_same(string, pattern, len_pattern);
|
|
|
|
goto __RETURN;
|
|
|
|
|
|
|
|
__ENDS:
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-09-27 11:28:52 +02:00
|
|
|
if (len_pattern == 0)
|
|
|
|
ret = TRUE;
|
|
|
|
else if (len_pattern <= len_string)
|
|
|
|
ret = STRING_equal_same(string + len_string - len_pattern, pattern, len_pattern);
|
|
|
|
goto __RETURN;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2013-07-13 01:57:53 +02:00
|
|
|
__MATCH:
|
|
|
|
|
2017-10-21 01:19:27 +02:00
|
|
|
ret = REGEXP_match_pcre(pattern, len_pattern, string, len_string);
|
2013-07-13 01:57:53 +02:00
|
|
|
goto __RETURN;
|
2009-09-27 11:28:52 +02:00
|
|
|
|
|
|
|
__RETURN:
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
RETURN->type = T_BOOLEAN;
|
2010-12-29 09:21:51 +01:00
|
|
|
RETURN->_boolean.value = -(ret ^ !!(code & 0x4));
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_LEAVE();
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int subst_nparam;
|
|
|
|
static VALUE *subst_param;
|
|
|
|
|
|
|
|
static void get_subst(int np, char **str, int *len)
|
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
if (np > 0 && np < subst_nparam)
|
|
|
|
VALUE_get_string(&subst_param[np], str, len);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*str = NULL;
|
|
|
|
*len = 0;
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_subst(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
char *string;
|
|
|
|
int len;
|
|
|
|
int np;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER();
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_get_string_len(&PARAM[0], &string, &len);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
for (np = 1; np < NPARAM; np++)
|
|
|
|
VALUE_conv_string(&PARAM[np]);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
subst_param = PARAM;
|
|
|
|
subst_nparam = NPARAM;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
string = STRING_subst(string, len, get_subst);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
/*for (np = 0; np < NPARAM; np++)
|
|
|
|
RELEASE_STRING(&PARAM[np]);*/
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
RETURN->type = T_STRING;
|
|
|
|
RETURN->_string.addr = (char *)string;
|
|
|
|
RETURN->_string.start = 0;
|
|
|
|
RETURN->_string.len = STRING_length(string);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_LEAVE();
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_replace(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
char *ps;
|
|
|
|
char *pp;
|
|
|
|
char *pr;
|
|
|
|
int ls, lp, lr;
|
2011-10-16 21:24:01 +02:00
|
|
|
int pos;
|
2009-01-02 01:05:38 +01:00
|
|
|
bool nocase = FALSE;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER();
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_get_string_len(&PARAM[0], &ps, &ls);
|
|
|
|
SUBR_get_string_len(&PARAM[1], &pp, &lp);
|
|
|
|
SUBR_get_string_len(&PARAM[2], &pr, &lr);
|
|
|
|
if (NPARAM == 4)
|
2010-02-08 00:10:41 +01:00
|
|
|
nocase = SUBR_get_integer(&PARAM[3]) == GB_COMP_NOCASE;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2011-12-11 20:14:04 +01:00
|
|
|
if (lp == 0 || ls == 0)
|
2010-09-11 12:23:36 +02:00
|
|
|
{
|
|
|
|
RELEASE(&PARAM[1]);
|
|
|
|
RELEASE(&PARAM[2]);
|
|
|
|
SP -= NPARAM;
|
|
|
|
SP++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-06-11 18:52:39 +02:00
|
|
|
if (lp == lr)
|
2011-12-11 20:14:04 +01:00
|
|
|
{
|
|
|
|
ps = STRING_new_temp(ps, ls);
|
2018-06-11 18:52:39 +02:00
|
|
|
RETURN->_string.addr = ps;
|
|
|
|
RETURN->_string.len = ls;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2018-06-11 18:52:39 +02:00
|
|
|
if (lp == 1)
|
2011-12-11 20:14:04 +01:00
|
|
|
{
|
2018-06-11 18:52:39 +02:00
|
|
|
char cp = *pp;
|
|
|
|
char cr = *pr;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2018-06-11 18:52:39 +02:00
|
|
|
if (nocase)
|
|
|
|
{
|
|
|
|
char cpl = tolower(cp);
|
|
|
|
cp = toupper(cp);
|
|
|
|
|
|
|
|
for (pos = 0; pos < ls; pos++)
|
|
|
|
{
|
|
|
|
if (ps[pos] == cp || ps[pos] == cpl)
|
|
|
|
ps[pos] = cr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (pos = 0; pos < ls; pos++)
|
|
|
|
{
|
|
|
|
if (ps[pos] == cp)
|
|
|
|
ps[pos] = cr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for(;;)
|
|
|
|
{
|
|
|
|
pos = STRING_search(ps, ls, pp, lp, 0, FALSE, nocase);
|
|
|
|
if (pos == 0)
|
|
|
|
break;
|
|
|
|
pos--;
|
|
|
|
memcpy(&ps[pos], pr, lp);
|
|
|
|
pos += lp;
|
|
|
|
ps += pos;
|
|
|
|
ls -= pos;
|
|
|
|
}
|
|
|
|
}
|
2011-12-11 20:14:04 +01:00
|
|
|
}
|
|
|
|
else
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
2011-12-11 20:14:04 +01:00
|
|
|
STRING_start_len(ls);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2008-11-09 00:42:08 +01:00
|
|
|
for(;;)
|
|
|
|
{
|
|
|
|
pos = STRING_search(ps, ls, pp, lp, 1, FALSE, nocase);
|
|
|
|
if (pos == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
pos--;
|
|
|
|
|
|
|
|
if (pos > 0)
|
2008-11-10 01:18:00 +01:00
|
|
|
STRING_make(ps, pos);
|
2008-11-09 00:42:08 +01:00
|
|
|
|
2008-11-10 01:18:00 +01:00
|
|
|
STRING_make(pr, lr);
|
2008-11-09 00:42:08 +01:00
|
|
|
|
|
|
|
pos += lp;
|
|
|
|
|
|
|
|
ps += pos;
|
|
|
|
ls -= pos;
|
|
|
|
|
|
|
|
if (ls <= 0)
|
|
|
|
break;
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2008-11-10 01:18:00 +01:00
|
|
|
STRING_make(ps, ls);
|
2011-12-11 20:14:04 +01:00
|
|
|
RETURN->_string.addr = STRING_end_temp();
|
|
|
|
RETURN->_string.len = STRING_length(RETURN->_string.addr);
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
RETURN->type = T_STRING;
|
|
|
|
RETURN->_string.start = 0;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_LEAVE();
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_split(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
CARRAY *array;
|
|
|
|
char *str;
|
|
|
|
int lstr;
|
2014-05-23 13:52:04 +02:00
|
|
|
char *sep = NULL;
|
|
|
|
int lsep = 0;
|
|
|
|
char *esc = NULL;
|
|
|
|
int lesc = 0;
|
2009-01-02 01:05:38 +01:00
|
|
|
bool no_void = FALSE;
|
2009-09-10 21:30:41 +02:00
|
|
|
bool keep_esc = FALSE;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER();
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2010-06-09 01:08:04 +02:00
|
|
|
VALUE_conv_string(PARAM);
|
|
|
|
VALUE_get_string(PARAM, &str, &lstr);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (NPARAM >= 2)
|
|
|
|
{
|
2014-05-23 13:52:04 +02:00
|
|
|
SUBR_get_string_len(&PARAM[1], &sep, &lsep);
|
2009-01-02 01:05:38 +01:00
|
|
|
if (NPARAM >= 3)
|
|
|
|
{
|
2014-05-23 13:52:04 +02:00
|
|
|
SUBR_get_string_len(&PARAM[2], &esc, &lesc);
|
2009-09-10 21:30:41 +02:00
|
|
|
if (NPARAM >= 4)
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
2009-09-10 21:30:41 +02:00
|
|
|
no_void = SUBR_get_boolean(&PARAM[3]);
|
|
|
|
if (NPARAM == 5)
|
|
|
|
keep_esc = SUBR_get_boolean(&PARAM[4]);
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2014-05-23 13:52:04 +02:00
|
|
|
array = STRING_split(str, lstr, sep, lsep, esc, lesc, no_void, keep_esc);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
RETURN->_object.class = CLASS_StringArray;
|
|
|
|
RETURN->_object.object = array;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_LEAVE();
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2008-01-17 22:39:26 +01:00
|
|
|
void SUBR_scan(void)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
CARRAY *array;
|
|
|
|
char *str;
|
|
|
|
int len_str;
|
|
|
|
char *pat;
|
|
|
|
int len_pat;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER_PARAM(2);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_get_string_len(&PARAM[0], &str, &len_str);
|
|
|
|
SUBR_get_string_len(&PARAM[1], &pat, &len_pat);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-06-18 02:14:53 +02:00
|
|
|
array = OBJECT_create(CLASS_StringArray, NULL, NULL, 0);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (len_str && len_pat)
|
|
|
|
REGEXP_scan(array, pat, len_pat, str, len_str);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
RETURN->_object.class = CLASS_StringArray;
|
|
|
|
RETURN->_object.object = array;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_LEAVE();
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2008-01-17 22:39:26 +01:00
|
|
|
void SUBR_iconv(void)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
char *str;
|
|
|
|
const char *src;
|
|
|
|
const char *dst;
|
|
|
|
char *result;
|
|
|
|
int len;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER_PARAM(3);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
str = SUBR_get_string(&PARAM[0]);
|
|
|
|
len = PARAM[0]._string.len;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
src = SUBR_get_string(&PARAM[1]);
|
|
|
|
dst = SUBR_get_string(&PARAM[2]);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
STRING_conv(&result, str, len, src, dst, TRUE);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (!result)
|
2018-08-22 09:30:27 +02:00
|
|
|
VALUE_null(RETURN);
|
2009-01-02 01:05:38 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
RETURN->type = T_STRING;
|
|
|
|
RETURN->_string.addr = result;
|
|
|
|
RETURN->_string.start = 0;
|
|
|
|
RETURN->_string.len = STRING_length(result);
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_LEAVE();
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_sconv(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2009-01-02 01:05:38 +01:00
|
|
|
char *str;
|
|
|
|
const char *src;
|
|
|
|
const char *dst;
|
|
|
|
char *result;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
SUBR_ENTER_PARAM(1);
|
|
|
|
|
|
|
|
if (LOCAL_is_UTF8)
|
|
|
|
return;
|
|
|
|
|
|
|
|
str = SUBR_get_string(&PARAM[0]);
|
|
|
|
len = PARAM[0]._string.len;
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
if (code & 0xF)
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
|
|
|
src = LOCAL_encoding;
|
2011-09-21 11:42:19 +02:00
|
|
|
dst = SC_UTF8;
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-21 11:42:19 +02:00
|
|
|
src = SC_UTF8;
|
2009-01-02 01:05:38 +01:00
|
|
|
dst = LOCAL_encoding;
|
|
|
|
}
|
|
|
|
|
|
|
|
STRING_conv(&result, str, len, src, dst, TRUE);
|
|
|
|
|
|
|
|
if (!result)
|
2018-08-22 09:30:27 +02:00
|
|
|
VALUE_null(RETURN);
|
2009-01-02 01:05:38 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
RETURN->type = T_STRING;
|
|
|
|
RETURN->_string.addr = result;
|
|
|
|
RETURN->_string.start = 0;
|
|
|
|
RETURN->_string.len = STRING_length(result);
|
|
|
|
}
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_LEAVE();
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_is_chr(ushort code)
|
2007-12-30 17:41:49 +01:00
|
|
|
{
|
2020-02-11 01:45:10 +01:00
|
|
|
static ushort test[256] = {
|
|
|
|
0x0041, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
|
|
|
|
0x0001, 0x00C1, 0x0041, 0x0041, 0x0041, 0x0041, 0x0001, 0x0001,
|
|
|
|
0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
|
|
|
|
0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
|
|
|
|
0x00C1, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
|
|
|
|
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
|
|
|
|
0x0231, 0x0231, 0x0231, 0x0231, 0x0231, 0x0231, 0x0231, 0x0231,
|
|
|
|
0x0231, 0x0231, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
|
|
|
|
0x0101, 0x022B, 0x022B, 0x022B, 0x022B, 0x022B, 0x022B, 0x020B,
|
|
|
|
0x020B, 0x020B, 0x020B, 0x020B, 0x020B, 0x020B, 0x020B, 0x020B,
|
|
|
|
0x020B, 0x020B, 0x020B, 0x020B, 0x020B, 0x020B, 0x020B, 0x020B,
|
|
|
|
0x020B, 0x020B, 0x020B, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
|
|
|
|
0x0101, 0x0227, 0x0227, 0x0227, 0x0227, 0x0227, 0x0227, 0x0207,
|
|
|
|
0x0207, 0x0207, 0x0207, 0x0207, 0x0207, 0x0207, 0x0207, 0x0207,
|
|
|
|
0x0207, 0x0207, 0x0207, 0x0207, 0x0207, 0x0207, 0x0207, 0x0207,
|
|
|
|
0x0207, 0x0207, 0x0207, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101
|
2009-01-02 01:05:38 +01:00
|
|
|
};
|
2020-02-11 01:45:10 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
char *addr;
|
|
|
|
int len;
|
|
|
|
int i;
|
2020-02-11 01:45:10 +01:00
|
|
|
bool ret;
|
|
|
|
ushort bit;
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER_PARAM(1);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
VALUE_conv_string(PARAM);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2010-06-09 01:08:04 +02:00
|
|
|
//SUBR_get_string_len(PARAM, &addr, &len);
|
|
|
|
VALUE_get_string(PARAM, &addr, &len);
|
2007-12-30 17:41:49 +01:00
|
|
|
|
2020-02-11 01:45:10 +01:00
|
|
|
if (len == 1)
|
|
|
|
ret = (test[(unsigned char)*addr] & (1 << ((code & 0xF) - 1))) != 0;
|
|
|
|
else if (len <= 0)
|
|
|
|
ret = FALSE;
|
|
|
|
else
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
2020-02-11 01:45:10 +01:00
|
|
|
bit = 1 << ((code & 0xF) - 1);
|
|
|
|
ret = TRUE;
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
if ((test[(unsigned char)addr[i]] & bit) == 0)
|
|
|
|
{
|
|
|
|
ret = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
2020-02-11 01:45:10 +01:00
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
RELEASE_STRING(PARAM);
|
2020-02-11 01:45:10 +01:00
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
SP--;
|
|
|
|
SP->type = T_BOOLEAN;
|
2020-02-11 01:45:10 +01:00
|
|
|
SP->_boolean.value = ret;
|
2010-06-05 01:48:53 +02:00
|
|
|
SP++;
|
2007-12-30 17:41:49 +01:00
|
|
|
}
|
|
|
|
|
2009-01-01 14:42:17 +01:00
|
|
|
void SUBR_tr(void)
|
|
|
|
{
|
|
|
|
char *str;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER_PARAM(1);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-05 11:31:11 +01:00
|
|
|
VALUE_conv_string(&PARAM[0]);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (SUBR_check_string(PARAM))
|
|
|
|
STRING_void_value(RETURN);
|
|
|
|
else
|
|
|
|
{
|
2010-06-05 01:48:53 +02:00
|
|
|
str = STRING_new_temp(&PARAM->_string.addr[PARAM->_string.start], PARAM->_string.len);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-01 14:42:17 +01:00
|
|
|
RETURN->type = T_CSTRING;
|
|
|
|
RETURN->_string.addr = (char *)LOCAL_gettext(str);
|
|
|
|
RETURN->_string.start = 0;
|
|
|
|
RETURN->_string.len = strlen(RETURN->_string.addr);
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_LEAVE();
|
|
|
|
}
|
|
|
|
|
2014-11-09 16:25:46 +01:00
|
|
|
static void make_hex_char(uchar c)
|
|
|
|
{
|
2019-04-04 23:12:07 +02:00
|
|
|
static const char hex_digit[] = "0123456789ABCDEF";
|
2014-11-09 16:25:46 +01:00
|
|
|
|
|
|
|
STRING_make_char(hex_digit[c >> 4]);
|
2019-04-04 23:12:07 +02:00
|
|
|
STRING_make_char(hex_digit[c & 15]);
|
2014-11-09 16:25:46 +01:00
|
|
|
}
|
|
|
|
|
2010-06-05 01:48:53 +02:00
|
|
|
void SUBR_quote(ushort code)
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
2014-11-09 16:25:46 +01:00
|
|
|
static void *jump[8] = { &&__QUOTE, &&__SHELL, &&__HTML, &&__BASE64, &&__URL , &&__ILLEGAL, &&__ILLEGAL, &&__ILLEGAL };
|
2009-01-02 01:05:38 +01:00
|
|
|
char *str;
|
|
|
|
int lstr;
|
|
|
|
int i;
|
|
|
|
unsigned char c;
|
|
|
|
char buf[8];
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER_PARAM(1);
|
|
|
|
|
2009-01-05 11:31:11 +01:00
|
|
|
VALUE_conv_string(&PARAM[0]);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-05 11:31:11 +01:00
|
|
|
str = PARAM->_string.addr + PARAM->_string.start;
|
|
|
|
lstr = PARAM->_string.len;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
STRING_start_len(lstr);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2014-11-09 16:25:46 +01:00
|
|
|
goto *jump[code & 0x7];
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
__QUOTE:
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
STRING_make_char('"');
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
for (i = 0; i < lstr; i++)
|
|
|
|
{
|
|
|
|
c = str[i];
|
2009-04-08 12:11:16 +02:00
|
|
|
//if (c >= ' ' && c <= 126 && c != '\\' && c != '"')
|
|
|
|
if (c >= ' ' && c != '\\' && c != '"')
|
2009-01-02 01:05:38 +01:00
|
|
|
STRING_make_char(c);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
STRING_make_char('\\');
|
|
|
|
if (c == '\n')
|
2011-09-03 11:52:28 +02:00
|
|
|
c = 'n';
|
2009-01-02 01:05:38 +01:00
|
|
|
else if (c == '\r')
|
2011-09-03 11:52:28 +02:00
|
|
|
c = 'r';
|
2009-01-02 01:05:38 +01:00
|
|
|
else if (c == '\t')
|
2011-09-03 11:52:28 +02:00
|
|
|
c = 't';
|
|
|
|
else if (!(c == '"' || c == '\\'))
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "x%02X", c);
|
|
|
|
STRING_make(buf, 3);
|
2011-09-03 11:52:28 +02:00
|
|
|
continue;
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
2011-09-03 11:52:28 +02:00
|
|
|
STRING_make_char(c);
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
STRING_make_char('"');
|
|
|
|
goto __END;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
__SHELL:
|
|
|
|
|
2016-01-02 12:11:52 +01:00
|
|
|
/*if (!LOCAL_is_UTF8)
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
|
|
|
char *conv;
|
2011-09-21 11:42:19 +02:00
|
|
|
STRING_conv(&conv, str, lstr, SC_UTF8, LOCAL_encoding, FALSE);
|
2009-01-02 01:05:38 +01:00
|
|
|
str = conv;
|
|
|
|
lstr = str ? strlen(str) : 0;
|
2016-01-02 12:11:52 +01:00
|
|
|
}*/
|
|
|
|
|
2012-02-27 00:07:14 +01:00
|
|
|
// TODO: The following works with bash, but not with dash!
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2014-11-12 23:25:37 +01:00
|
|
|
STRING_make_char('\'');
|
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
for (i = 0; i < lstr; i++)
|
|
|
|
{
|
|
|
|
c = str[i];
|
2014-11-12 23:25:37 +01:00
|
|
|
if (c == '\'')
|
2015-03-22 13:12:23 +01:00
|
|
|
{
|
|
|
|
STRING_make("'\\'", 3);
|
|
|
|
}
|
2014-11-12 23:25:37 +01:00
|
|
|
STRING_make_char(c);
|
|
|
|
/*
|
2009-01-02 01:05:38 +01:00
|
|
|
if (c == '\n')
|
|
|
|
STRING_make("$'\\n'", 5);
|
|
|
|
else if (c == '\r')
|
|
|
|
STRING_make("$'\\r'", 5);
|
|
|
|
else if (c == '\t')
|
|
|
|
STRING_make("$'\\t'", 5);
|
|
|
|
else if (c < ' ') //|| (c > 126 && !LOCAL_is_UTF8))
|
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "$'\\x%02X'", c);
|
|
|
|
STRING_make(buf, 7);
|
|
|
|
}
|
|
|
|
else if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || index(".-/_~", c) || c > 126)
|
|
|
|
STRING_make_char(c);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
STRING_make_char('\\');
|
|
|
|
STRING_make_char(c);
|
|
|
|
}
|
2014-11-12 23:25:37 +01:00
|
|
|
*/
|
2009-01-02 01:05:38 +01:00
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2014-11-12 23:25:37 +01:00
|
|
|
STRING_make_char('\'');
|
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
goto __END;
|
|
|
|
|
|
|
|
__HTML:
|
|
|
|
|
|
|
|
for (i = 0; i < lstr; i++)
|
|
|
|
{
|
|
|
|
c = str[i];
|
|
|
|
if (c == '&')
|
|
|
|
STRING_make("&", 5);
|
|
|
|
else if (c == '<')
|
|
|
|
STRING_make("<", 4);
|
|
|
|
else if (c == '>')
|
|
|
|
STRING_make(">", 4);
|
|
|
|
else if (c == '"')
|
|
|
|
STRING_make(""", 6);
|
2011-09-03 11:52:28 +02:00
|
|
|
else if (c == '\'')
|
|
|
|
STRING_make("'", 6);
|
2014-05-23 13:52:04 +02:00
|
|
|
else if (c == 0xC2 && (uchar)str[i + 1] == 0xA0)
|
2012-01-22 14:13:25 +01:00
|
|
|
{
|
|
|
|
STRING_make(" ", 6);
|
|
|
|
i++;
|
|
|
|
}
|
2009-01-02 01:05:38 +01:00
|
|
|
else
|
|
|
|
STRING_make_char(c);
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-20 01:10:12 +02:00
|
|
|
goto __END;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-19 23:35:26 +02:00
|
|
|
__BASE64:
|
|
|
|
{
|
2012-05-20 04:21:43 +02:00
|
|
|
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
2012-05-19 23:35:26 +02:00
|
|
|
uchar *in;
|
|
|
|
char *out = buf;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-19 23:35:26 +02:00
|
|
|
for (i = 0; i < (lstr - 2); i += 3)
|
|
|
|
{
|
|
|
|
in = (uchar *)&str[i];
|
|
|
|
out[0] = base64[in[0] >> 2];
|
|
|
|
out[1] = base64[((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4)];
|
|
|
|
out[2] = base64[((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6)];
|
|
|
|
out[3] = base64[in[2] & 0x3F];
|
|
|
|
STRING_make(out, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i < lstr)
|
|
|
|
{
|
|
|
|
in = (uchar *)&str[i];
|
|
|
|
lstr -= i;
|
|
|
|
out[0] = base64[in[0] >> 2];
|
|
|
|
out[1] = base64[((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4)];
|
|
|
|
out[2] = (lstr > 1 ? base64[((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6) ] : '=');
|
|
|
|
out[3] = (lstr > 2 ? base64[in[2] & 0x3F] : '=');
|
|
|
|
STRING_make(out, 4);
|
|
|
|
}
|
|
|
|
}
|
2014-09-03 16:33:18 +02:00
|
|
|
|
|
|
|
goto __END;
|
|
|
|
|
2014-11-09 16:25:46 +01:00
|
|
|
__URL:
|
|
|
|
|
|
|
|
// Warning! '/' is not encoded, so that the function is more pratical, by supposing that no file url will have '/' in its name.
|
|
|
|
|
|
|
|
for (i = 0; i < lstr; i++)
|
|
|
|
{
|
|
|
|
c = str[i];
|
|
|
|
if (c == ' ')
|
|
|
|
STRING_make_char('+');
|
|
|
|
else if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || index("-._~,$!/", c))
|
|
|
|
STRING_make_char(c);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
STRING_make_char('%');
|
|
|
|
make_hex_char(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
goto __END;
|
|
|
|
|
2014-09-26 23:52:42 +02:00
|
|
|
#if 0
|
2014-09-03 16:33:18 +02:00
|
|
|
__JAVASCRIPT:
|
|
|
|
{
|
|
|
|
STRING_make_char('\'');
|
|
|
|
|
|
|
|
for (i = 0; i < lstr; i++)
|
|
|
|
{
|
|
|
|
c = str[i];
|
2014-09-16 03:10:58 +02:00
|
|
|
if (c >= ' ' && c <= 126 && c != '\\' && c != '\'')
|
2014-09-03 16:33:18 +02:00
|
|
|
STRING_make_char(c);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
STRING_make_char('\\');
|
|
|
|
if (c == '\n')
|
|
|
|
c = 'n';
|
|
|
|
else if (c == '\r')
|
|
|
|
c = 'r';
|
|
|
|
else if (c == '\t')
|
|
|
|
c = 't';
|
|
|
|
else if (!(c == '\'' || c == '\\'))
|
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "x%02X", c);
|
|
|
|
STRING_make(buf, 3);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
STRING_make_char(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
STRING_make_char('\'');
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
goto __END;
|
|
|
|
|
2014-11-09 16:25:46 +01:00
|
|
|
#endif
|
|
|
|
|
2014-09-03 16:33:18 +02:00
|
|
|
__ILLEGAL:
|
|
|
|
|
|
|
|
THROW_ILLEGAL();
|
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
__END:
|
|
|
|
|
|
|
|
RETURN->type = T_STRING;
|
|
|
|
RETURN->_string.addr = STRING_end_temp();
|
|
|
|
RETURN->_string.start = 0;
|
|
|
|
RETURN->_string.len = STRING_length(RETURN->_string.addr);
|
|
|
|
|
|
|
|
SUBR_LEAVE();
|
|
|
|
}
|
|
|
|
|
|
|
|
static int read_hex_digit(unsigned char c)
|
|
|
|
{
|
|
|
|
if (c >= '0' && c <= '9')
|
|
|
|
return (c - '0');
|
|
|
|
else if (c >= 'A' && c <= 'F')
|
|
|
|
return (c - 'A' + 10);
|
|
|
|
else if (c >= 'a' && c <= 'f')
|
|
|
|
return (c - 'a' + 10);
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-05-19 23:35:26 +02:00
|
|
|
void SUBR_unquote(ushort code)
|
2009-01-02 01:05:38 +01:00
|
|
|
{
|
2014-11-09 16:25:46 +01:00
|
|
|
static void *jump[4] = { &&__UNQUOTE, &&__FROM_BASE64, &&__FROM_URL, &&__ILLEGAL };
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
char *str;
|
|
|
|
int lstr;
|
|
|
|
int i;
|
|
|
|
unsigned char c;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_ENTER_PARAM(1);
|
2012-05-19 23:35:26 +02:00
|
|
|
|
2009-01-05 11:25:50 +01:00
|
|
|
VALUE_conv_string(&PARAM[0]);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-05 11:25:50 +01:00
|
|
|
str = PARAM->_string.addr + PARAM->_string.start;
|
|
|
|
lstr = PARAM->_string.len;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
STRING_start_len(lstr);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-19 23:35:26 +02:00
|
|
|
goto *jump[code & 0x3];
|
|
|
|
|
|
|
|
__UNQUOTE:
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (lstr >= 2 && str[0] == '"' && str[lstr - 1] == '"')
|
|
|
|
{
|
|
|
|
str++;
|
|
|
|
lstr -= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < lstr; i++)
|
|
|
|
{
|
|
|
|
c = str[i];
|
|
|
|
if (c == '\\')
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
if (i >= lstr)
|
|
|
|
break;
|
|
|
|
c = str[i];
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
if (c == 'n')
|
|
|
|
c = '\n';
|
|
|
|
else if (c == 't')
|
|
|
|
c = '\t';
|
|
|
|
else if (c == 'r')
|
|
|
|
c = '\r';
|
|
|
|
else if (c == 'x')
|
|
|
|
{
|
|
|
|
if (i >= (lstr - 2))
|
|
|
|
break;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
c = (read_hex_digit(str[i + 1]) << 4) + read_hex_digit(str[i + 2]);
|
|
|
|
i += 2;
|
|
|
|
}
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
STRING_make_char(c);
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-19 23:35:26 +02:00
|
|
|
goto __END;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2014-11-09 16:25:46 +01:00
|
|
|
__FROM_BASE64:
|
2012-05-19 23:35:26 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
char buf[4];
|
|
|
|
unsigned char n = 0;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-19 23:35:26 +02:00
|
|
|
for (i = 0; i < lstr; i++)
|
|
|
|
{
|
|
|
|
c = str[i];
|
|
|
|
if (c >= 'A' && c <= 'Z')
|
|
|
|
c = c - 'A';
|
|
|
|
else if (c >= 'a' && c <= 'z')
|
|
|
|
c = c - 'a' + 26;
|
|
|
|
else if (c >= '0' && c <= '9')
|
|
|
|
c = c - '0' + 52;
|
|
|
|
else if (c == '+')
|
|
|
|
c = 62;
|
|
|
|
else if (c == '/')
|
|
|
|
c = 63;
|
|
|
|
else if (c == '=')
|
2013-07-21 12:15:54 +02:00
|
|
|
break;
|
2012-05-19 23:35:26 +02:00
|
|
|
else
|
|
|
|
continue;
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-19 23:35:26 +02:00
|
|
|
switch (n & 3)
|
|
|
|
{
|
|
|
|
case 0: buf[0] = c << 2; break;
|
|
|
|
case 1: buf[0] |= c >> 4; buf[1] = c << 4; break;
|
|
|
|
case 2: buf[1] |= c >> 2; buf[2] = c << 6; break;
|
|
|
|
case 3: buf[2] |= c; STRING_make(buf, 3); break;
|
|
|
|
}
|
|
|
|
n++;
|
|
|
|
}
|
2013-07-21 12:15:54 +02:00
|
|
|
|
|
|
|
if ((n & 3) > 1)
|
|
|
|
STRING_make(buf, (n & 3) - 1);
|
2012-05-19 23:35:26 +02:00
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-19 23:35:26 +02:00
|
|
|
goto __END;
|
2014-11-09 16:25:46 +01:00
|
|
|
|
|
|
|
__FROM_URL:
|
|
|
|
|
|
|
|
for (i = 0; i < lstr; i++)
|
|
|
|
{
|
|
|
|
c = str[i];
|
|
|
|
if (c == '+')
|
|
|
|
c = ' ';
|
|
|
|
else if (c == '%')
|
|
|
|
{
|
|
|
|
if (i >= (lstr - 2))
|
|
|
|
break;
|
|
|
|
|
|
|
|
c = (read_hex_digit(str[i + 1]) << 4) + read_hex_digit(str[i + 2]);
|
|
|
|
i += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
STRING_make_char(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
goto __END;
|
|
|
|
|
|
|
|
__ILLEGAL:
|
|
|
|
|
|
|
|
THROW_ILLEGAL();
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-05-19 23:35:26 +02:00
|
|
|
__END:
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
RETURN->type = T_STRING;
|
|
|
|
RETURN->_string.addr = STRING_end_temp();
|
|
|
|
RETURN->_string.start = 0;
|
|
|
|
RETURN->_string.len = STRING_length(RETURN->_string.addr);
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2009-01-02 01:05:38 +01:00
|
|
|
SUBR_LEAVE();
|
|
|
|
}
|
2012-01-31 03:33:01 +01:00
|
|
|
|
|
|
|
void SUBR_swap(ushort code)
|
|
|
|
{
|
2014-08-23 17:10:11 +02:00
|
|
|
char *src, *dst;
|
|
|
|
int len, i, j;
|
|
|
|
|
2012-01-31 03:33:01 +01:00
|
|
|
if (!(code & 0xFF))
|
|
|
|
{
|
|
|
|
SUBR_move(1);
|
|
|
|
return;
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-01-31 03:33:01 +01:00
|
|
|
SUBR_ENTER();
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2014-08-23 17:10:11 +02:00
|
|
|
if (NPARAM == 2 && (SUBR_get_integer(&PARAM[1]) == GB_BIG_ENDIAN) == EXEC_big_endian)
|
2012-01-31 03:33:01 +01:00
|
|
|
{
|
2014-08-23 17:10:11 +02:00
|
|
|
SP--;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SUBR_check_string(PARAM))
|
|
|
|
STRING_void_value(RETURN);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
len = PARAM->_string.len;
|
|
|
|
if (len > 0)
|
2012-01-31 03:33:01 +01:00
|
|
|
{
|
2014-08-23 17:10:11 +02:00
|
|
|
src = PARAM->_string.addr + PARAM->_string.start;
|
|
|
|
dst = STRING_new_temp(NULL, PARAM->_string.len);
|
|
|
|
|
|
|
|
for (i = 0, j = len - 1; i < len; i++,j--)
|
|
|
|
dst[i] = src[j];
|
|
|
|
|
|
|
|
RETURN->type = T_STRING;
|
|
|
|
RETURN->_string.addr = dst;
|
|
|
|
RETURN->_string.start = 0;
|
|
|
|
RETURN->_string.len = len;
|
2012-01-31 03:33:01 +01:00
|
|
|
}
|
|
|
|
}
|
2016-01-02 12:11:52 +01:00
|
|
|
|
2012-01-31 03:33:01 +01:00
|
|
|
SUBR_LEAVE();
|
|
|
|
}
|
|
|
|
|
|
|
|
|