Allow STRING * INT or INT * STRING, which repeats STRING that many times.

This commit is contained in:
Dianne Skoll
2024-02-03 16:00:23 -05:00
parent 9455ec48d7
commit b2bd6109dc
3 changed files with 71 additions and 7 deletions

View File

@@ -944,7 +944,7 @@ static int Subtract(void)
/***************************************************************/
static int Multiply(void)
{
Value v1, v2;
Value v1, v2, v3;
int r;
PopValStack(v2);
@@ -964,6 +964,55 @@ static int Multiply(void)
PushValStack(v1);
return OK;
}
/* String times int means repeat the string that many times */
if ((v1.type == INT_TYPE && v2.type == STR_TYPE) ||
(v1.type == STR_TYPE && v2.type == INT_TYPE)) {
int rep = (v1.type == INT_TYPE ? v1.v.val : v2.v.val);
char const *str = (v1.type == INT_TYPE ? v2.v.str : v1.v.str);
int l;
/* Can't multiply by a negative number */
if (rep < 0) {
return E_2LOW;
}
if (rep == 0 || !str || !*str) {
/* Empty string */
DestroyValue(v1); DestroyValue(v2);
v3.type = STR_TYPE;
v3.v.str = malloc(1);
if (!v3.v.str) {
return E_NO_MEM;
}
*v3.v.str = 0;
PushValStack(v3);
return OK;
}
/* Create the new value */
l = (int) strlen(str);
if (l * rep < 0) {
DestroyValue(v1); DestroyValue(v2);
return E_STRING_TOO_LONG;
}
if (MaxStringLen > 0 && (l * rep) > MaxStringLen) {
DestroyValue(v1); DestroyValue(v2);
return E_STRING_TOO_LONG;
}
v3.type = STR_TYPE;
v3.v.str = malloc(l * rep + 1);
if (!v3.v.str) {
DestroyValue(v1); DestroyValue(v2);
return E_NO_MEM;
}
*v3.v.str = 0;
for (int i=0; i<rep; i++) {
strcat(v3.v.str, str);
}
DestroyValue(v1); DestroyValue(v2);
PushValStack(v3);
return OK;
}
DestroyValue(v1); DestroyValue(v2);
return E_BAD_TYPE;
}

View File

@@ -4828,12 +4828,12 @@ set a htmlstriptags("<img src=\"foo\">")
htmlstriptags("<img src=\"foo\">") => ""
# $ParseUntriggered
REM 2 Jan 1990 MSG ["bad_expr" * 2]
REM 2 Jan 1990 MSG ["bad_expr" / 2]
../tests/test.rem(885): Expired
"bad_expr" * 2 => Type mismatch
../tests/test.rem(885): `*': Type mismatch
"bad_expr" / 2 => Type mismatch
../tests/test.rem(885): `/': Type mismatch
SET $ParseUntriggered 0
REM 2 Jan 1990 MSG ["bad_expr" * 2]
REM 2 Jan 1990 MSG ["bad_expr" / 2]
../tests/test.rem(887): Expired
SET $ParseUntriggered 1

View File

@@ -882,11 +882,26 @@ set a htmlstriptags("this is > whut <b>foo</b>")
set a htmlstriptags("<img src=\"foo\">")
# $ParseUntriggered
REM 2 Jan 1990 MSG ["bad_expr" * 2]
REM 2 Jan 1990 MSG ["bad_expr" / 2]
SET $ParseUntriggered 0
REM 2 Jan 1990 MSG ["bad_expr" * 2]
REM 2 Jan 1990 MSG ["bad_expr" / 2]
SET $ParseUntriggered 1
# String multiplication
set a "zero" * 0
set a 0 * "zero"
set a "" * 10000000
set a 10000000 * ""
# Too long for default limits
set a "wookie" * 1000000
set a 1000000 * "wookie"
set a "Cabbage! " * 7
set a 7 * "Cabbage! "
# Should result in errors
set pqxya 1+2)