Deprecate 1-indexed string functions

This commit is contained in:
Rangi42
2025-08-05 16:46:09 -04:00
parent 39f0f9edc0
commit 3a0a4b7f90
21 changed files with 55 additions and 174 deletions

View File

@@ -625,18 +625,6 @@ the charmap entries of a string are counted by
.Ql CHARLEN ;
and the values of a charmap entry are counted by
.Ql CHARSIZE .
.Pp
The following legacy functions are similar to other functions that operate on string expressions, but for historical reasons, they count starting from
.Em position 1 ,
not from index 0!
(Position -1 still counts from the end.)
.Bl -column "STRSUB(str, pos, len)"
.It Sy Name Ta Sy Operation
.It Fn STRSUB str pos len Ta Returns a substring of Ar str No starting at Ar pos No and Ar len No characters long. If Ar len No is not specified, the substring continues to the end of Ar str No .
.It Fn STRIN str sub Ta Returns the first position of Ar sub No in Ar str Ns , or 0 if it's not present.
.It Fn STRRIN str sub Ta Returns the last position of Ar sub No in Ar str Ns , or 0 if it's not present.
.It Fn CHARSUB str pos Ta Returns the substring of Ar str No for the charmap entry at Ar pos No with the current charmap . Pq Ar pos No counts charmap entries, not characters.
.El
.Ss Character maps
When writing text strings that are meant to be displayed on the Game Boy, the character encoding in the ROM may need to be different than the source file encoding.
For example, the tiles used for uppercase letters may be placed starting at tile index 128, which differs from ASCII starting at 65.

View File

@@ -351,6 +351,8 @@ std::string
}
std::string act_StringSub(std::string const &str, int32_t negPos, std::optional<uint32_t> optLen) {
warning(WARNING_OBSOLETE, "`STRSUB` is deprecated; use 0-indexed `STRSLICE` instead");
size_t adjustLen = act_StringLen(str, false);
uint32_t pos = adjustNegativePos(negPos, adjustLen, "STRSUB");
uint32_t len = optLen ? *optLen : pos > adjustLen ? 0 : adjustLen + 1 - pos;
@@ -447,6 +449,8 @@ std::string act_StringChar(std::string const &str, int32_t negIdx) {
}
std::string act_CharSub(std::string const &str, int32_t negPos) {
warning(WARNING_OBSOLETE, "`CHARSUB` is deprecated; use 0-indexed `STRCHAR` instead");
size_t adjustLen = act_CharLen(str);
uint32_t pos = adjustNegativePos(negPos, adjustLen, "CHARSUB");

View File

@@ -1493,10 +1493,12 @@ relocexpr_no_str:
$$.makeNumber(pos != std::string::npos ? pos : -1);
}
| OP_STRIN LPAREN string COMMA string RPAREN {
warning(WARNING_OBSOLETE, "`STRIN` is deprecated; use 0-indexed `STRFIND` instead");
size_t pos = $3.find($5);
$$.makeNumber(pos != std::string::npos ? pos + 1 : 0);
}
| OP_STRRIN LPAREN string COMMA string RPAREN {
warning(WARNING_OBSOLETE, "`STRRIN` is deprecated; use 0-indexed `STRRFIND` instead");
size_t pos = $3.rfind($5);
$$.makeNumber(pos != std::string::npos ? pos + 1 : 0);
}

View File

@@ -18,11 +18,6 @@ DEF S EQUS "XBold<NULL>ABC"
assert STRCHAR("{S}", 0) == $58 ; ASCII "X"
db "{S}"
for n, CHARLEN("{S}")
assert STRCHAR("{S}", n) == CHARSUB("{S}", n + 1)
assert STRCHAR("{S}", -n - 1) == CHARSUB("{S}", -n - 1)
endr
newcharmap ascii
assert CHARLEN("{S}") == 14

View File

@@ -1,3 +0,0 @@
DEF S EQUS STRCHAR("ABC", 3)
DEF T EQUS CHARSUB("ABC", 4)
DEF U EQUS CHARSUB("ABC", 0)

View File

@@ -1,6 +0,0 @@
warning: invalid-strchar-charsub.asm(1): [-Wbuiltin-args]
STRCHAR: Index 3 is past the end of the string
warning: invalid-strchar-charsub.asm(2): [-Wbuiltin-args]
CHARSUB: Position 4 is past the end of the string
warning: invalid-strchar-charsub.asm(3): [-Wbuiltin-args]
CHARSUB: Position starts at 1

View File

@@ -0,0 +1,2 @@
DEF S EQUS STRCHAR("ABC", 3)
DEF T EQUS STRCHAR("ABC", -4)

View File

@@ -0,0 +1,4 @@
warning: invalid-strchar.asm(1): [-Wbuiltin-args]
STRCHAR: Index 3 is past the end of the string
warning: invalid-strchar.asm(2): [-Wbuiltin-args]
STRCHAR: Index starts at 0

View File

@@ -14,11 +14,11 @@
DEF invalid EQUS "aäb漢,a<><61>b<EFBFBD><62><EFBFBD>!"
DEF n = STRLEN("{invalid}")
DEF copy EQUS STRSUB("{invalid}", 1)
DEF copy EQUS STRSLICE("{invalid}", 0)
println "\"{#s:invalid}\" == \"{#s:copy}\" ({d:n})"
DEF mid1 EQUS STRSUB("{invalid}", 5, 2)
DEF mid1 EQUS STRSLICE("{invalid}", 4, 6)
DEF mid2 EQUS STRSLICE("{invalid}", 8, 9)
println "\"{#s:mid2}{#s:mid1}\""
@@ -51,8 +51,5 @@ DEF n = STRLEN("{invalid}")
DEF r = CHARLEN("{invalid}")
println "\"{#s:invalid}\": {d:n} == {d:r}"
DEF final EQUS STRSUB("{invalid}", 4, 1)
println "\"{#s:invalid}\" ends \"{#s:final}\""
REDEF final EQUS STRSLICE("{invalid}", 3, 4)
DEF final EQUS STRSLICE("{invalid}", 3, 4)
println "\"{#s:invalid}\" ends \"{#s:final}\""

View File

@@ -7,13 +7,13 @@ error: invalid-utf-8-strings.asm(16):
error: invalid-utf-8-strings.asm(16):
STRLEN: Invalid UTF-8 byte 0xA2
error: invalid-utf-8-strings.asm(17):
STRSUB: Invalid UTF-8 byte 0xA3
STRSLICE: Invalid UTF-8 byte 0xA3
error: invalid-utf-8-strings.asm(17):
STRSUB: Invalid UTF-8 byte 0xA4
STRSLICE: Invalid UTF-8 byte 0xA4
error: invalid-utf-8-strings.asm(17):
STRSUB: Invalid UTF-8 byte 0xF0
STRSLICE: Invalid UTF-8 byte 0xF0
error: invalid-utf-8-strings.asm(17):
STRSUB: Invalid UTF-8 byte 0xA2
STRSLICE: Invalid UTF-8 byte 0xA2
error: invalid-utf-8-strings.asm(22):
STRSLICE: Invalid UTF-8 byte 0xA3
error: invalid-utf-8-strings.asm(22):
@@ -55,7 +55,5 @@ error: invalid-utf-8-strings.asm(40):
error: invalid-utf-8-strings.asm(50):
STRLEN: Incomplete UTF-8 character
error: invalid-utf-8-strings.asm(54):
STRSUB: Incomplete UTF-8 character
error: invalid-utf-8-strings.asm(57):
STRSLICE: Incomplete UTF-8 character
Assembly aborted with 30 errors!
Assembly aborted with 29 errors!

View File

@@ -4,4 +4,3 @@
"漢<>"
"abc<62><63>": 4 == 4
"abc<62><63>" ends "<22><>"
"abc<62><63>" ends "<22><>"

View File

@@ -23,11 +23,3 @@ assert_equal strrpl(#s, "\0", "0"), "hello0world"
assert_equal strfmt("%s", #s), #s
assert_equal strchar(#s, 5), "\0"
assert_equal strchar(#s, -1), "d"
assert strin(#s, "o\0w") == 5
assert strin(#s, "orld") == 8
assert strrin(#s, "o\0w") == 5
assert strrin(#s, "o") == 8
assert_equal strsub(#s, 5, 3), "o\0w"
assert_equal strsub(#s, 7), "world"

View File

@@ -1,6 +1,6 @@
MACRO N
FOR R,1,_NARG+1
PRINT STRSUB("\n\"\\ PR1NT,ABCDEFGHIMnOSU2_+-()<>",\<R>+1,1)
PRINT STRSLICE("\n\"\\ PR1NT,ABCDEFGHILMnOS2_+-()<>",\<R>,\<R>+1)
ENDR
REPT R-2
PRINT"\1,"
@@ -8,4 +8,4 @@ SHIFT
ENDR
PRINT"\1\n"
ENDM
N 19,10,12,5,21,3,7,0,15,21,5,3,5,9,6,9,25,7,10,5,16,26,6,0,4,5,18,7,8,3,22,8,5,22,23,11,28,1,2,20,2,1,2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,1,9,2,30,5,31,26,6,9,6,29,0,14,7,13,5,0,5,14,4,8,3,5,27,24,0,4,5,18,7,8,1,2,6,9,1,0,22,17,18,15,8,0,14,7,13,5,0,4,5,18,7,8,1,2,6,2,20,1,0,14,7,13,19,0,3,7,3
N 20,10,12,5,22,3,7,0,15,22,5,3,5,9,6,9,25,7,10,5,16,26,6,0,4,5,18,7,8,3,23,8,5,23,19,18,12,14,28,1,2,21,2,1,2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,1,9,2,30,5,31,9,2,30,5,31,26,6,29,0,14,7,13,5,0,5,14,4,8,3,5,27,24,0,4,5,18,7,8,1,2,6,9,1,0,23,17,18,15,8,0,14,7,13,5,0,4,5,18,7,8,1,2,6,2,21,1,0,14,7,13,20,0,7,3

View File

@@ -1,6 +1,6 @@
MACRO N
FOR R,1,_NARG+1
PRINT STRSUB("\n\"\\ PR1NT,ABCDEFGHIMnOSU2_+-()<>",\<R>+1,1)
PRINT STRSLICE("\n\"\\ PR1NT,ABCDEFGHILMnOS2_+-()<>",\<R>,\<R>+1)
ENDR
REPT R-2
PRINT"\1,"
@@ -8,4 +8,4 @@ SHIFT
ENDR
PRINT"\1\n"
ENDM
N 19,10,12,5,21,3,7,0,15,21,5,3,5,9,6,9,25,7,10,5,16,26,6,0,4,5,18,7,8,3,22,8,5,22,23,11,28,1,2,20,2,1,2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,1,9,2,30,5,31,26,6,9,6,29,0,14,7,13,5,0,5,14,4,8,3,5,27,24,0,4,5,18,7,8,1,2,6,9,1,0,22,17,18,15,8,0,14,7,13,5,0,4,5,18,7,8,1,2,6,2,20,1,0,14,7,13,19,0,3,7,3
N 20,10,12,5,22,3,7,0,15,22,5,3,5,9,6,9,25,7,10,5,16,26,6,0,4,5,18,7,8,3,23,8,5,23,19,18,12,14,28,1,2,21,2,1,2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,1,9,2,30,5,31,9,2,30,5,31,26,6,29,0,14,7,13,5,0,5,14,4,8,3,5,27,24,0,4,5,18,7,8,1,2,6,9,1,0,23,17,18,15,8,0,14,7,13,5,0,4,5,18,7,8,1,2,6,2,21,1,0,14,7,13,20,0,7,3

View File

@@ -4,7 +4,7 @@ def hello equs "world"
def name equs "hello"
println "{name}"
println #name
assert !strcmp(strsub(#name, 1, 4), "hell")
assert !strcmp(strslice(#name, 0, 4), "hell")
assert strlen(#hello) == charlen(#hello)
assert strlen("{hello}") == 5

View File

@@ -1,28 +0,0 @@
SECTION "Test", ROM0
assert STRFIND("foo bar baz", "bar") == STRRFIND("foo bar baz", "bar")
assert STRIN("foo bar baz", "bar") == STRRIN("foo bar baz", "bar")
assert STRFIND("foo bar bargain", "bar") == 4
assert STRIN("foo bar bargain", "bar") == 5
assert STRRFIND("foo bar bargain", "bar") == 8
assert STRRIN("foo bar bargain", "bar") == 9
assert STRFIND("foo bar", "qux") == -1
assert STRIN("foo bar", "qux") == 0
assert STRRFIND("foo bar", "qux") == -1
assert STRRIN("foo bar", "qux") == 0
assert STRFIND("foo", "foobar") == -1
assert STRIN("foo", "foobar") == 0
assert STRRFIND("foo", "foobar") == -1
assert STRRIN("foo", "foobar") == 0
assert STRFIND("foobar", "") == 0
assert STRIN("foobar", "") == 1
assert STRRFIND("foobar", "") == STRLEN("foobar")
assert STRRIN("foobar", "") == STRLEN("foobar") + 1

View File

@@ -0,0 +1,10 @@
assert STRFIND("foo bar baz", "bar") == STRRFIND("foo bar baz", "bar")
assert STRFIND("foo bar bargain", "bar") == 4
assert STRRFIND("foo bar bargain", "bar") == 8
assert STRFIND("foo bar", "qux") == -1
assert STRRFIND("foo bar", "qux") == -1
assert STRFIND("foo", "foobar") == -1
assert STRRFIND("foo", "foobar") == -1
assert STRFIND("foobar", "") == 0
assert STRRFIND("foobar", "") == STRLEN("foobar")

View File

@@ -1,40 +0,0 @@
warning: strslice-strsub.asm(14) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Start index 4 is past the end of the string
warning: strslice-strsub.asm(15) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Index starts at 0
warning: strslice-strsub.asm(18) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 31 is past the end of the string
warning: strslice-strsub.asm(19) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 300 is past the end of the string
warning: strslice-strsub.asm(20) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Index starts at 0
warning: strslice-strsub.asm(20) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 300 is past the end of the string
warning: strslice-strsub.asm(22) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Start index 4 is past the end of the string
warning: strslice-strsub.asm(22) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 4 is past the end of the string
warning: strslice-strsub.asm(23) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 4 is past the end of the string
warning: strslice-strsub.asm(26) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 12 is past the end of the string
warning: strslice-strsub.asm(41) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Position starts at 1
warning: strslice-strsub.asm(43) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Position 5 is past the end of the string
warning: strslice-strsub.asm(44) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Position starts at 1
warning: strslice-strsub.asm(47) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Length too big: 32
warning: strslice-strsub.asm(48) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Length too big: 300
warning: strslice-strsub.asm(49) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Position starts at 1
warning: strslice-strsub.asm(49) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Length too big: 300
warning: strslice-strsub.asm(51) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Position 5 is past the end of the string
warning: strslice-strsub.asm(52) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Length too big: 1
warning: strslice-strsub.asm(55) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Length too big: 10

View File

@@ -26,32 +26,3 @@ ENDM
xstrslice "カタカナ", 2, 12
xstrslice "g̈", 0, 1
xstrslice "g̈", 0, 2
MACRO xstrsub
PRINTLN "STRSUB(\#): ", STRSUB(\#)
ENDM
xstrsub "ABC", 1, 1
xstrsub "ABC", 2, 1
xstrsub "ABC", 3, 1
xstrsub "ABC", -3, 1
xstrsub "ABC", -2, 1
xstrsub "ABC", -1, 1
xstrsub "ABC", 2
xstrsub "ABC", 0
xstrsub "ABC", -2
xstrsub "ABC", 5
xstrsub "ABC", -5
xstrsub "ABC", 1, 2
xstrsub "ABC", 2, 2
xstrsub "ABC", 2, 32
xstrsub "ABC", 2, 300
xstrsub "ABC", -4, 300
xstrsub "ABC", 4, 0
xstrsub "ABC", 5, 0
xstrsub "ABC", 4, 1
xstrsub "カタカナ", 1, 2
xstrsub "カタカナ", 3, 2
xstrsub "カタカナ", 3, 10
xstrsub "g̈", 1, 1
xstrsub "g̈", 1, 2

20
test/asm/strslice.err Normal file
View File

@@ -0,0 +1,20 @@
warning: strslice.asm(14) -> strslice.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Start index 4 is past the end of the string
warning: strslice.asm(15) -> strslice.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Index starts at 0
warning: strslice.asm(18) -> strslice.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 31 is past the end of the string
warning: strslice.asm(19) -> strslice.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 300 is past the end of the string
warning: strslice.asm(20) -> strslice.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Index starts at 0
warning: strslice.asm(20) -> strslice.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 300 is past the end of the string
warning: strslice.asm(22) -> strslice.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Start index 4 is past the end of the string
warning: strslice.asm(22) -> strslice.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 4 is past the end of the string
warning: strslice.asm(23) -> strslice.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 4 is past the end of the string
warning: strslice.asm(26) -> strslice.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 12 is past the end of the string

View File

@@ -22,27 +22,3 @@ STRSLICE("カタカナ",2,4): カナ
STRSLICE("カタカナ",2,12): カナ
STRSLICE("g̈",0,1): g
STRSLICE("g̈",0,2): g̈
STRSUB("ABC",1,1): A
STRSUB("ABC",2,1): B
STRSUB("ABC",3,1): C
STRSUB("ABC",-3,1): A
STRSUB("ABC",-2,1): B
STRSUB("ABC",-1,1): C
STRSUB("ABC",2): BC
STRSUB("ABC",0): ABC
STRSUB("ABC",-2): BC
STRSUB("ABC",5):
STRSUB("ABC",-5): ABC
STRSUB("ABC",1,2): AB
STRSUB("ABC",2,2): BC
STRSUB("ABC",2,32): BC
STRSUB("ABC",2,300): BC
STRSUB("ABC",-4,300): ABC
STRSUB("ABC",4,0):
STRSUB("ABC",5,0):
STRSUB("ABC",4,1):
STRSUB("カタカナ",1,2): カタ
STRSUB("カタカナ",3,2): カナ
STRSUB("カタカナ",3,10): カナ
STRSUB("g̈",1,1): g
STRSUB("g̈",1,2): g̈