@@ -76,13 +76,19 @@ void MCStringsCountChunksInRange(MCExecContext& ctxt, Chunk_term p_chunk_type, M
7676
7777 if (p_chunk_type == CT_CODEUNIT)
7878 {
79- r_count = MCU_min (MCStringGetLength (p_string), p_range . length) - p_range . offset;
79+ // AL-2015-03-03: [[ Bug 14744 ]] Fix incorrect codeunit count calculation
80+ r_count = MCU_min (MCStringGetLength (p_string) - p_range . offset, p_range . length);
8081 return ;
8182 }
8283
84+ MCChunkType t_type;
85+ t_type = MCChunkTypeFromChunkTerm (p_chunk_type);
86+
8387 MCTextChunkIterator *tci;
84- tci = new MCTextChunkIterator (p_chunk_type, p_string, p_range);
85- r_count = tci -> countchunks (ctxt);
88+ tci = MCStringsTextChunkIteratorCreate (ctxt, p_string, p_chunk_type);
89+
90+ r_count = tci -> CountChunks ();
91+
8692 delete tci;
8793 return ;
8894}
@@ -107,36 +113,7 @@ uinteger_t MCStringsCountChunkCallback(void *context)
107113
108114void MCStringsSkipWord (MCExecContext& ctxt, MCStringRef p_string, bool p_skip_spaces, uindex_t & x_offset)
109115{
110- uindex_t t_space_offset;
111- uindex_t t_length = MCStringGetLength (p_string);
112- uindex_t t_end_quote_offset = t_length;
113- uindex_t t_end_line_offset = t_length;
114-
115- if (MCStringGetCharAtIndex (p_string, x_offset) == ' "' )
116- {
117- // then bump the offset up to the next quotation mark + 1, or the beginning of the next line
118- // if neither of these are present then set offset to string length.
119- MCStringFirstIndexOfChar (p_string, ' "' , x_offset + 1 , kMCCompareExact , t_end_quote_offset);
120- MCStringFirstIndexOf (p_string, ctxt . GetLineDelimiter (), x_offset + 1 , kMCCompareExact , t_end_line_offset);
121-
122- if (t_end_quote_offset < t_end_line_offset)
123- x_offset = t_end_quote_offset + 1 ;
124- else if (t_end_line_offset < t_end_quote_offset)
125- x_offset = t_end_line_offset + MCStringGetLength (ctxt . GetLineDelimiter ());
126- else
127- x_offset = t_length;
128- }
129- else
130- {
131- while (!MCUnicodeIsWhitespace (MCStringGetCharAtIndex (p_string, x_offset)) && x_offset < t_length)
132- x_offset++;
133- }
134-
135- if (p_skip_spaces)
136- {
137- while (MCUnicodeIsWhitespace (MCStringGetCharAtIndex (p_string, x_offset)) && x_offset < t_length)
138- x_offset++;
139- }
116+ MCChunkSkipWord (p_string, ctxt . GetLineDelimiter (), ctxt . GetStringComparisonType (), p_skip_spaces, x_offset);
140117}
141118
142119// AL-2015-02-10: [[ Bug 14532 ]] Allow chunk extents to be counted in a given range, to prevent substring copying in text chunk resolution.
@@ -199,35 +176,35 @@ void MCStringsGetExtentsByOrdinalInRange(MCExecContext& ctxt, Chunk_term p_chunk
199176void MCStringsGetExtentsByRangeInRange (MCExecContext& ctxt, Chunk_term p_chunk_type, integer_t p_first, integer_t p_last, MCValueRef p_string, MCRange *p_range, uinteger_t & r_first, uinteger_t & r_chunk_count)
200177{
201178 if (MCValueGetTypeCode (p_string) == kMCValueTypeCodeData )
202- MCChunkGetExtentsOfByteChunkByRangeInRange ((MCDataRef)p_string, p_range, p_first, p_last, r_first, r_chunk_count);
179+ MCChunkGetExtentsOfByteChunkByRangeInRange ((MCDataRef)p_string, p_range, p_first, p_last, false , false , false , r_first, r_chunk_count);
203180 else if (p_chunk_type == CT_CODEUNIT)
204- MCChunkGetExtentsOfCodeunitChunkByRangeInRange ((MCStringRef)p_string, p_range, p_first, p_last, r_first, r_chunk_count);
181+ MCChunkGetExtentsOfCodeunitChunkByRangeInRange ((MCStringRef)p_string, p_range, p_first, p_last, false , false , false , r_first, r_chunk_count);
205182 else
206183 {
207184 MCChunkCountState t_state;
208185 t_state . string = (MCStringRef)p_string;
209186 t_state . chunk = p_chunk_type;
210187 t_state . ctxt = &ctxt;
211188 t_state . range = p_range;
212- MCChunkGetExtentsByRangeInRange (p_first, p_last, MCStringsCountChunkCallback, &t_state, r_first, r_chunk_count);
189+ MCChunkGetExtentsByRangeInRange (false , false , false , p_first, p_last, MCStringsCountChunkCallback, &t_state, r_first, r_chunk_count);
213190 }
214191}
215192
216193// AL-2015-02-10: [[ Bug 14532 ]] Allow chunk extents to be counted in a given range, to prevent substring copying in text chunk resolution.
217194void MCStringsGetExtentsByExpressionInRange (MCExecContext& ctxt, Chunk_term p_chunk_type, integer_t p_first, MCStringRef p_string, MCRange *p_range, uinteger_t & r_first, uinteger_t & r_chunk_count)
218195{
219196 if (MCValueGetTypeCode (p_string) == kMCValueTypeCodeData )
220- MCChunkGetExtentsOfByteChunkByExpressionInRange ((MCDataRef)p_string, p_range, p_first, r_first, r_chunk_count);
197+ MCChunkGetExtentsOfByteChunkByExpressionInRange ((MCDataRef)p_string, p_range, p_first, false , false , false , r_first, r_chunk_count);
221198 else if (p_chunk_type == CT_CODEUNIT)
222- MCChunkGetExtentsOfCodeunitChunkByExpressionInRange ((MCStringRef)p_string, p_range, p_first, r_first, r_chunk_count);
199+ MCChunkGetExtentsOfCodeunitChunkByExpressionInRange ((MCStringRef)p_string, p_range, p_first, false , false , false , r_first, r_chunk_count);
223200 else
224201 {
225202 MCChunkCountState t_state;
226203 t_state . string = (MCStringRef)p_string;
227204 t_state . chunk = p_chunk_type;
228205 t_state . ctxt = &ctxt;
229206 t_state . range = p_range;
230- MCChunkGetExtentsByExpressionInRange (p_first, MCStringsCountChunkCallback, &t_state, r_first, r_chunk_count);
207+ MCChunkGetExtentsByExpressionInRange (false , false , false , p_first, MCStringsCountChunkCallback, &t_state, r_first, r_chunk_count);
231208 }
232209}
233210
@@ -1150,3 +1127,74 @@ void MCStringsMarkBytesOfTextByOrdinal(MCExecContext& ctxt, Chunk_term p_ordinal
11501127 x_mark . start = t_cu_range . offset + t_first;
11511128 x_mark . finish = x_mark . start + t_chunk_count;
11521129}
1130+
1131+ // //////////////////////////////////////////////////////////////////////////////
1132+
1133+ MCTextChunkIterator_Tokenized::MCTextChunkIterator_Tokenized (MCStringRef p_text, MCChunkType p_chunk_type) : MCTextChunkIterator(p_text, p_chunk_type)
1134+ {
1135+ m_sp = new MCScriptPoint (p_text);
1136+ }
1137+
1138+ MCTextChunkIterator_Tokenized::MCTextChunkIterator_Tokenized (MCStringRef p_text, MCChunkType p_chunk_type, MCRange p_restriction) : MCTextChunkIterator(p_text, p_chunk_type, p_restriction)
1139+ {
1140+ MCAutoStringRef t_substring;
1141+ MCStringCopySubstring (m_text, p_restriction, &t_substring);
1142+ MCValueAssign (m_text, *t_substring);
1143+ m_sp = new MCScriptPoint (m_text);
1144+ }
1145+
1146+ MCTextChunkIterator_Tokenized::~MCTextChunkIterator_Tokenized ()
1147+ {
1148+ delete m_sp;
1149+ }
1150+
1151+ bool MCTextChunkIterator_Tokenized::Next ()
1152+ {
1153+ MCerrorlock++;
1154+
1155+ bool t_found = true ;
1156+ uint2 t_pos;
1157+ Parse_stat ps = m_sp -> nexttoken ();
1158+ if (ps == PS_ERROR || ps == PS_EOF)
1159+ t_found = false ;
1160+
1161+ if (t_found)
1162+ {
1163+ m_range . offset = m_sp -> getindex ();
1164+ m_range . length = MCStringGetLength (m_sp -> gettoken_stringref ());
1165+ }
1166+
1167+ return t_found;
1168+ }
1169+
1170+
1171+ MCTextChunkIterator *MCStringsTextChunkIteratorCreate (MCExecContext& ctxt, MCStringRef p_text, Chunk_term p_chunk_type)
1172+ {
1173+ if (p_chunk_type == CT_TOKEN)
1174+ {
1175+ MCTextChunkIterator *tci;
1176+ tci = new MCTextChunkIterator_Tokenized (p_text, MCChunkTypeFromChunkTerm (p_chunk_type));
1177+ return tci;
1178+ }
1179+
1180+ return MCChunkCreateTextChunkIterator (p_text, MCChunkTypeFromChunkTerm (p_chunk_type), p_chunk_type == CT_LINE ? ctxt . GetLineDelimiter () : ctxt . GetItemDelimiter (), ctxt . GetStringComparisonType ());
1181+ }
1182+
1183+ bool MCStringsTextChunkIteratorNext (MCExecContext& ctxt, MCTextChunkIterator *tci)
1184+ {
1185+ tci -> SetOptions (ctxt . GetStringComparisonType ());
1186+
1187+ MCChunkType t_type;
1188+ t_type = tci -> GetType ();
1189+
1190+ if (t_type == kMCChunkTypeLine || t_type == kMCChunkTypeItem )
1191+ {
1192+ MCStringRef t_delimiter;
1193+ t_delimiter = t_type == kMCChunkTypeLine ? ctxt . GetLineDelimiter () : ctxt . GetItemDelimiter ();
1194+ reinterpret_cast <MCTextChunkIterator_Delimited *>(tci) -> SetDelimiter (t_delimiter);
1195+ }
1196+
1197+ return tci -> Next ();
1198+ }
1199+
1200+ // //////////////////////////////////////////////////////////////////////////////
0 commit comments