Skip to content

Commit 53408a8

Browse files
committed
[[ Bug 14532 ]] Port fix for bug 14532 forward to develop branch
2 parents 4b4baf9 + 2907ed9 commit 53408a8

File tree

8 files changed

+348
-167
lines changed

8 files changed

+348
-167
lines changed

engine/src/chunk.cpp

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5677,6 +5677,89 @@ MCTextChunkIterator::MCTextChunkIterator(Chunk_term p_chunk_type, MCStringRef p_
56775677
MCLocaleBreakIteratorRelease(break_iterator);
56785678
}
56795679

5680+
// AL-2015-02-10: [[ Bug 14532 ]] Add text chunk iterator constructor for restricted range chunk operations.
5681+
MCTextChunkIterator::MCTextChunkIterator(Chunk_term p_chunk_type, MCStringRef p_text, MCRange p_restriction)
5682+
{
5683+
/* UNCHECKED */ MCStringCopy(p_text, text);
5684+
type = p_chunk_type;
5685+
5686+
if (type == CT_CHARACTER && (MCStringIsNative(text) || (MCStringIsSimple(text) && MCStringIsUncombined(text))))
5687+
type = CT_CODEUNIT;
5688+
5689+
MCBreakIteratorRef break_iterator;
5690+
5691+
break_iterator = nil;
5692+
sp = nil;
5693+
range = MCRangeMake(p_restriction . offset, 0);
5694+
length = p_restriction . length == UINDEX_MAX ? MCStringGetLength(text) : p_restriction . offset + p_restriction . length;
5695+
// AL-2014-10-24: [[ Bug 13783 ]] Set exhausted to true if the string is immediately exhausted
5696+
exhausted = (p_restriction . length == 0 || p_restriction . offset>= MCStringGetLength(text));
5697+
first_chunk = true;
5698+
break_position = 0;
5699+
delimiter_length = 0;
5700+
5701+
switch (type)
5702+
{
5703+
case CT_TOKEN:
5704+
{
5705+
MCAutoStringRef t_substring;
5706+
MCStringCopySubstring(text, p_restriction, &t_substring);
5707+
MCValueAssign(text, *t_substring);
5708+
sp = new MCScriptPoint(text);
5709+
}
5710+
break;
5711+
case CT_CHARACTER:
5712+
case CT_SENTENCE:
5713+
{
5714+
MCAutoStringRef t_substring;
5715+
MCStringCopySubstring(text, p_restriction, &t_substring);
5716+
MCRange t_range;
5717+
uindex_t t_end;
5718+
/* UNCHECKED */ MCLocaleBreakIteratorCreate(kMCBasicLocale, p_chunk_type == CT_SENTENCE ? kMCBreakIteratorTypeSentence : kMCBreakIteratorTypeCharacter, break_iterator);
5719+
/* UNCHECKED */ MCLocaleBreakIteratorSetText(break_iterator, *t_substring);
5720+
t_range . length = p_restriction . length;
5721+
t_range . offset = p_restriction . offset;
5722+
5723+
while ((t_end = MCLocaleBreakIteratorAdvance(break_iterator)) != kMCLocaleBreakIteratorDone)
5724+
{
5725+
t_range . offset += t_range . length;
5726+
t_range . length = t_end - t_range . offset;
5727+
breaks . Push(t_range);
5728+
}
5729+
}
5730+
break;
5731+
case CT_TRUEWORD:
5732+
{
5733+
MCAutoStringRef t_substring;
5734+
MCStringCopySubstring(text, p_restriction, &t_substring);
5735+
MCAutoArray<uindex_t> t_breaks;
5736+
/* UNCHECKED */ MCLocaleBreakIteratorCreate(kMCBasicLocale, kMCBreakIteratorTypeWord, break_iterator);
5737+
/* UNCHECKED */ MCLocaleBreakIteratorSetText(break_iterator, *t_substring);
5738+
MCRange t_range;
5739+
t_range . length = p_restriction . length;
5740+
t_range . offset = p_restriction . offset;
5741+
5742+
while (MCLocaleWordBreakIteratorAdvance(*t_substring, break_iterator, t_range)
5743+
&& t_range . offset + t_range . length != kMCLocaleBreakIteratorDone)
5744+
{
5745+
breaks . Push(t_range);
5746+
}
5747+
}
5748+
break;
5749+
case CT_LINE:
5750+
case CT_ITEM:
5751+
case CT_PARAGRAPH:
5752+
// delimiter length may vary for line and item.
5753+
delimiter_length = 1;
5754+
default:
5755+
break;
5756+
}
5757+
5758+
if (break_iterator != nil)
5759+
MCLocaleBreakIteratorRelease(break_iterator);
5760+
}
5761+
5762+
56805763
MCTextChunkIterator::~MCTextChunkIterator()
56815764
{
56825765
MCValueRelease(text);
@@ -5743,7 +5826,8 @@ bool MCTextChunkIterator::next(MCExecContext& ctxt)
57435826

57445827
MCRange t_found_range;
57455828
// calculate the length of the line / item
5746-
if (!MCStringFind(text, MCRangeMake(t_offset, UINDEX_MAX), t_delimiter, ctxt . GetStringComparisonType(), &t_found_range))
5829+
// AL-2015-02-10: [[ Bug 14532 ]] Use restricted range for delimiter search
5830+
if (!MCStringFind(text, MCRangeMake(t_offset, length - t_offset), t_delimiter, ctxt . GetStringComparisonType(), &t_found_range))
57475831
{
57485832
range . length = length - range . offset;
57495833
exhausted = true;
@@ -5763,8 +5847,9 @@ bool MCTextChunkIterator::next(MCExecContext& ctxt)
57635847
uindex_t t_pg_offset;
57645848
bool t_newline_found, t_pg_found;
57655849

5850+
// AL-2015-02-10: [[ Bug 14532 ]] Use restricted range for delimiter search
57665851
t_pg_offset = t_offset;
5767-
t_newline_found = MCStringFirstIndexOfChar(text, '\n', t_offset, kMCCompareExact, t_offset);
5852+
t_newline_found = MCStringFirstIndexOfCharInRange(text, '\n', MCRangeMake(t_offset, length - t_offset), kMCCompareExact, t_offset);
57685853
// AL-2014-07-21: [[ Bug 12162 ]] Ignore PS when calculating paragraph chunk.
57695854
t_pg_found = false; /*MCStringFirstIndexOfChar(text, 0x2029, t_pg_offset, kMCCompareExact, t_pg_offset);*/
57705855

@@ -5795,7 +5880,8 @@ bool MCTextChunkIterator::next(MCExecContext& ctxt)
57955880

57965881
MCStringsSkipWord(ctxt, text, false, t_offset);
57975882

5798-
if (t_offset == length)
5883+
// AL-2015-02-10: [[ Bug 14532 ]] Use restricted range for exhaustion check
5884+
if (t_offset >= length)
57995885
exhausted = true;
58005886

58015887
range . length = t_offset - range . offset;
@@ -5851,11 +5937,11 @@ bool MCTextChunkIterator::isamong(MCExecContext& ctxt, MCStringRef p_needle)
58515937
// Otherwise we need to find p_needle and check to see if there is a delimiter either side.
58525938
// This is because of the case where the delimiter is within p_needle - e.g.
58535939
// "a,b" is among the items of "a,b,c,d" should return true.
5854-
5940+
// AL-2015-02-10: [[ Bug 14532 ]] Use restricted range for isamong search
58555941
if (type == CT_PARAGRAPH)
5856-
return MCStringsIsAmongTheParagraphsOfRange(ctxt, p_needle, text, ctxt . GetStringComparisonType(), MCRangeMake(0, length));
5942+
return MCStringsIsAmongTheParagraphsOfRange(ctxt, p_needle, text, ctxt . GetStringComparisonType(), MCRangeMake(range . offset, length));
58575943

5858-
return MCStringsIsAmongTheChunksOfRange(ctxt, p_needle, text, type, ctxt . GetStringComparisonType(), MCRangeMake(0, length));
5944+
return MCStringsIsAmongTheChunksOfRange(ctxt, p_needle, text, type, ctxt . GetStringComparisonType(), MCRangeMake(range . offset, length));
58595945
}
58605946
default:
58615947
if (MCStringIsEmpty(p_needle))

engine/src/chunk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ class MCTextChunkIterator
250250

251251
public:
252252
MCTextChunkIterator(Chunk_term p_chunk_type, MCStringRef p_text);
253+
// AL-2015-02-10: [[ Bug 14532 ]] Add text chunk iterator constructor for restricted range chunk operations.
254+
MCTextChunkIterator(Chunk_term p_chunk_type, MCStringRef p_text, MCRange p_restriction);
253255
~MCTextChunkIterator();
254256

255257
MCRange getrange()

0 commit comments

Comments
 (0)