Skip to content

Commit 110c240

Browse files
committed
[Bug 14846] com.livecode.byte: Fix "(offset|index) of _ after _"
1 parent e94b32e commit 110c240

File tree

3 files changed

+179
-11
lines changed

3 files changed

+179
-11
lines changed

libscript/src/byte.mlc

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ use com.livecode.foreign
2525
public foreign handler MCByteEvalNumberOfBytesIn(in Target as Data, out Count as LCUIndex) as undefined binds to "<builtin>"
2626

2727
public foreign handler MCByteEvalOffsetOfBytes(in IsLast as CBool, in Needle as Data, in Target as Data, out Offset as LCUIndex) as undefined binds to "<builtin>"
28-
public foreign handler MCByteEvalOffsetOfBytesBefore(in IsLast as CBool, in Needle as Data, in Before as LCUIndex, in Target as Data, out Offset as LCUIndex) as undefined binds to "<builtin>"
29-
public foreign handler MCByteEvalOffsetOfBytesAfter(in IsFirst as CBool, in Needle as Data, in After as LCUIndex, in Target as Data, out Offset as LCUIndex) as undefined binds to "<builtin>"
28+
public foreign handler MCByteEvalOffsetOfBytesBefore(in IsLast as CBool, in Needle as Data, in Before as LCIndex, in Target as Data, out Offset as LCUIndex) as undefined binds to "<builtin>"
29+
public foreign handler MCByteEvalOffsetOfBytesAfter(in IsLast as CBool, in Needle as Data, in After as LCIndex, in Target as Data, out Offset as LCUIndex) as undefined binds to "<builtin>"
3030

3131
public foreign handler MCByteEvalIsAmongTheBytesOf(in Needle as Data, in Target as Data, out Value as CBool) as undefined binds to "<builtin>"
3232

@@ -122,8 +122,6 @@ The first (respectively last) offset of <Needle> in <Target> is number of bytes
122122

123123
Tags: Binary
124124
*/
125-
126-
/* bug 14846
127125
syntax ByteOffsetAfter is prefix operator with precedence 1
128126
"the" ( "first" <IsLast=false> | "last" <IsLast=true> | <IsLast=false> ) "offset" "of" <Needle: Expression> "after" <After: Expression> "in" <Target: Expression>
129127
begin
@@ -134,7 +132,6 @@ syntax ByteIndexAfter is prefix operator with precedence 1
134132
begin
135133
MCByteEvalOffsetOfBytesAfter(IsLast, Needle, After, Target, output)
136134
end syntax
137-
*/
138135

139136
/*
140137

@@ -151,8 +148,6 @@ The first (respectively last) offset of <Needle> in <Target> is number of bytes
151148

152149
Tags: Binary
153150
*/
154-
155-
/* bug 14846
156151
syntax ByteOffsetBefore is prefix operator with precedence 1
157152
"the" ( "first" <IsFirst=true> | "last" <IsFirst=false> | <IsFirst=false> ) "offset" "of" <Needle: Expression> "before" <Before: Expression> "in" <Target: Expression>
158153
begin
@@ -163,7 +158,6 @@ syntax ByteIndexBefore is prefix operator with precedence 1
163158
begin
164159
MCByteEvalOffsetOfBytesBefore(IsFirst, Needle, Before, Target, output)
165160
end syntax
166-
*/
167161

168162
/*
169163
Summary: Determines whether <Needle> is in <Target>.

libscript/src/module-byte.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ extern "C" MC_DLLEXPORT void MCByteEvalOffsetOfBytes(bool p_is_last, MCDataRef p
8383
return MCByteEvalOffsetOfBytesInRange(p_needle, p_target, p_is_last, MCRangeMake(0, UINDEX_MAX), r_output);
8484
}
8585

86-
extern "C" MC_DLLEXPORT void MCByteEvalOffsetOfBytesAfter(MCDataRef p_needle, MCDataRef p_target, uindex_t p_after, bool p_is_last, uindex_t& r_output)
86+
extern "C" MC_DLLEXPORT void MCByteEvalOffsetOfBytesAfter(bool p_is_last, MCDataRef p_needle, index_t p_after, MCDataRef p_target, uindex_t& r_output)
8787
{
8888
uindex_t t_start, t_count;
8989
if (!MCChunkGetExtentsOfByteChunkByExpressionInRange(p_target, nil, p_after, true, true, false, t_start, t_count))
@@ -95,10 +95,14 @@ extern "C" MC_DLLEXPORT void MCByteEvalOffsetOfBytesAfter(MCDataRef p_needle, MC
9595
return MCByteEvalOffsetOfBytesInRange(p_needle, p_target, p_is_last, MCRangeMake(t_start + t_count, UINDEX_MAX), r_output);
9696
}
9797

98-
extern "C" MC_DLLEXPORT void MCByteEvalOffsetOfBytesBefore(MCDataRef p_needle, MCDataRef p_target, uindex_t p_before, bool p_is_first, uindex_t& r_output)
98+
extern "C" MC_DLLEXPORT void MCByteEvalOffsetOfBytesBefore(bool p_is_first, MCDataRef p_needle, index_t p_before, MCDataRef p_target, uindex_t& r_output)
9999
{
100100
uindex_t t_start, t_count;
101-
if (!MCChunkGetExtentsOfByteChunkByExpressionInRange(p_target, nil, p_before, true, false, true, t_start, t_count))
101+
if (0 == p_before)
102+
{
103+
t_start = UINDEX_MAX;
104+
}
105+
else if (!MCChunkGetExtentsOfByteChunkByExpressionInRange(p_target, nil, p_before, true, false, true, t_start, t_count))
102106
{
103107
MCErrorCreateAndThrow(kMCGenericErrorTypeInfo, "reason", MCSTR("chunk index out of range"), nil);
104108
return;

tests/lcb/stdlib/byte.lcb

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,176 @@ public handler TestOffset()
102102
test "index" when the index of N in H is 2
103103
end handler
104104

105+
----------------------------------------------------------------
106+
107+
public handler TestOffsetAfter()
108+
variable N as Data
109+
variable H as Data
110+
111+
-- Only test single-byte needles for now
112+
put EncodeUTF8("x") into N
113+
put EncodeUTF8("x.xx.") into H
114+
test "offset after (single, +ve)" when the offset of N after 1 in H is 3
115+
test "first offset after (single, +ve)" when the first offset of N after 1 in H is 3
116+
test "last offset after (single, +ve)" when the last offset of N after 1 in H is 4
117+
test "offset after (single, -ve)" when the offset of N after -5 in H is 3
118+
test "first offset after (single, -ve)" when the first offset of N after -5 in H is 3
119+
test "last offset after (single, -ve)" when the last offset of N after -5 in H is 4
120+
121+
-- For bytes, "index" is synonymous with "offset"
122+
test "index after" when the index of N after 1 in H is 3
123+
124+
put EncodeUTF8("x") into N
125+
put EncodeUTF8("x..") into H
126+
test "offset after (single, missing, +ve)" when the offset of N after 1 in H is 0
127+
test "first offset after (single, missing, +ve)" when the first offset of N after 1 in H is 0
128+
test "last offset after (single, missing, +ve)" when the last offset of N after 1 in H is 0
129+
test "offset after (single, missing, -ve)" when the offset of N after -3 in H is 0
130+
test "first offset after (single, missing, -ve)" when the first offset of N after -3 in H is 0
131+
test "last offset after (single, missing, -ve)" when the last offset of N after -3 in H is 0
132+
133+
MCUnitTestHandlerThrows(TestOffsetAfter_SingleInvalidPositive, "offset after (single, invalid +ve)")
134+
MCUnitTestHandlerThrows(TestOffsetAfter_SingleInvalidNegative, "offset after (single, invalid -ve)")
135+
MCUnitTestHandlerThrows(TestFirstOffsetAfter_SingleInvalidPositive, "first offset after (single, invalid +ve)")
136+
MCUnitTestHandlerThrows(TestFirstOffsetAfter_SingleInvalidNegative, "first offset after (single, invalid -ve)")
137+
MCUnitTestHandlerThrows(TestLastOffsetAfter_SingleInvalidPositive, "last offset after (single, invalid +ve)")
138+
MCUnitTestHandlerThrows(TestLastOffsetAfter_SingleInvalidNegative, "last offset after (single, invalid -ve)")
139+
end handler
140+
141+
handler TestOffsetAfter_SingleInvalidPositive()
142+
get the offset of the byte with code 0 after 2 in the byte with code 0
143+
end handler
144+
145+
handler TestOffsetAfter_SingleInvalidNegative()
146+
get the offset of the byte with code 0 after -3 in the byte with code 0
147+
end handler
148+
149+
handler TestFirstOffsetAfter_SingleInvalidPositive()
150+
get the first offset of the byte with code 0 after 2 in the byte with code 0
151+
end handler
152+
153+
handler TestFirstOffsetAfter_SingleInvalidNegative()
154+
get the first offset of the byte with code 0 after -3 in the byte with code 0
155+
end handler
156+
157+
handler TestLastOffsetAfter_SingleInvalidPositive()
158+
get the last offset of the byte with code 0 after 2 in the byte with code 0
159+
end handler
160+
161+
handler TestLastOffsetAfter_SingleInvalidNegative()
162+
get the last offset of the byte with code 0 after -3 in the byte with code 0
163+
end handler
164+
165+
public handler TestOffsetAfterZero()
166+
variable N as Data
167+
variable H as Data
168+
169+
put EncodeUTF8("x") into N
170+
put EncodeUTF8("x") into H
171+
172+
-- "offset of _ after 0 in _" should be equivalent to "offset of _ in _"
173+
variable tNoAfter
174+
put the offset of N in H into tNoAfter
175+
test "offset after (single, 0)" when the offset of N after 0 in H is tNoAfter
176+
177+
put the first offset of N in H into tNoAfter
178+
test "first offset after (single, 0)" when the first offset of N after 0 in H is tNoAfter
179+
180+
put the last offset of N in H into tNoAfter
181+
test "the last offset after (single, 0, same)" when the last offset of N after 0 in H is tNoAfter
182+
183+
put EncodeUTF8("x") into N
184+
put EncodeUTF8(".x.") into H
185+
put the last offset of N in H into tNoAfter
186+
test "last offset after (single, 0)" when the last offset of N after 0 in H is tNoAfter
187+
188+
end handler
189+
190+
----------------------------------------------------------------
191+
192+
public handler TestOffsetBefore()
193+
variable N as Data
194+
variable H as Data
195+
196+
-- Only test single-byte needles for now
197+
put EncodeUTF8("x") into N
198+
put EncodeUTF8("x.xx.") into H
199+
test "offset before (single, +ve)" when the offset of N before 4 in H is 3
200+
test "first offset before (single, +ve)" when the first offset of N before 4 in H is 1
201+
test "last offset before (single, +ve)" when the last offset of N before 4 in H is 3
202+
test "offset before (single, -ve)" when the offset of N before -2 in H is 3
203+
test "first offset before (single, -ve)" when the first offset of N before -2 in H is 1
204+
test "last offset before (single, -ve)" when the last offset of N before -2 in H is 3
205+
206+
-- For bytes, "index" is synonymous with "offset"
207+
test "index before" when the index of N before 4 in H is 3
208+
209+
put EncodeUTF8("x") into N
210+
put EncodeUTF8("x..") into H
211+
test "offset before (single, missing, +ve)" when the offset of N before 1 in H is 0
212+
test "first offset before (single, missing, +ve)" when the first offset of N before 1 in H is 0
213+
test "last offset before (single, missing, +ve)" when the last offset of N before 1 in H is 0
214+
test "offset before (single, missing, -ve)" when the offset of N before -3 in H is 0
215+
test "first offset before (single, missing, -ve)" when the first offset of N before -3 in H is 0
216+
test "last offset before (single, missing, -ve)" when the last offset of N before -3 in H is 0
217+
218+
MCUnitTestHandlerThrows(TestOffsetBefore_SingleInvalidPositive, "offset before (single, invalid +ve)")
219+
MCUnitTestHandlerThrows(TestOffsetBefore_SingleInvalidNegative, "offset before (single, invalid -ve)")
220+
MCUnitTestHandlerThrows(TestFirstOffsetBefore_SingleInvalidPositive, "first offset before (single, invalid +ve)")
221+
MCUnitTestHandlerThrows(TestFirstOffsetBefore_SingleInvalidNegative, "first offset before (single, invalid -ve)")
222+
MCUnitTestHandlerThrows(TestLastOffsetBefore_SingleInvalidPositive, "last offset before (single, invalid +ve)")
223+
MCUnitTestHandlerThrows(TestLastOffsetBefore_SingleInvalidNegative, "last offset before (single, invalid -ve)")
224+
end handler
225+
226+
handler TestOffsetBefore_SingleInvalidPositive()
227+
get the offset of the byte with code 0 before 3 in the byte with code 0
228+
end handler
229+
230+
handler TestOffsetBefore_SingleInvalidNegative()
231+
get the offset of the byte with code 0 before -2 in the byte with code 0
232+
end handler
233+
234+
handler TestFirstOffsetBefore_SingleInvalidPositive()
235+
get the first offset of the byte with code 0 before 3 in the byte with code 0
236+
end handler
237+
238+
handler TestFirstOffsetBefore_SingleInvalidNegative()
239+
get the first offset of the byte with code 0 before -2 in the byte with code 0
240+
end handler
241+
242+
handler TestLastOffsetBefore_SingleInvalidPositive()
243+
get the last offset of the byte with code 0 before 3 in the byte with code 0
244+
end handler
245+
246+
handler TestLastOffsetBefore_SingleInvalidNegative()
247+
get the last offset of the byte with code 0 before -2 in the byte with code 0
248+
end handler
249+
250+
public handler TestOffsetBeforeZero()
251+
variable N as Data
252+
variable H as Data
253+
254+
put EncodeUTF8("x") into N
255+
put EncodeUTF8("x") into H
256+
257+
-- "offset of _ before 0 in _" should be equivalent to "last offset of _ in _"
258+
variable tNoBefore
259+
put the last offset of N in H into tNoBefore
260+
test "offset before (single, 0)" when the offset of N before 0 in H is tNoBefore
261+
return
262+
put the first offset of N in H into tNoBefore
263+
test "first offset before (single, 0)" when the first offset of N before 0 in H is tNoBefore
264+
265+
put the last offset of N in H into tNoBefore
266+
test "the last offset before (single, 0, same)" when the last offset of N before 0 in H is tNoBefore
267+
268+
put EncodeUTF8("x") into N
269+
put EncodeUTF8(".x.") into H
270+
put the last offset of N in H into tNoBefore
271+
test "last offset before (single, 0)" when the last offset of N before 0 in H is tNoBefore
272+
273+
end handler
274+
105275
----------------------------------------------------------------
106276
-- Helper functions
107277
----------------------------------------------------------------

0 commit comments

Comments
 (0)