@@ -23,6 +23,14 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
2323
2424// //////////////////////////////////////////////////////////////////////////////
2525
26+ // Forward declarations of internal utility functions
27+
28+ static bool __MCNumberParseNativeString (const char *p_string, uindex_t p_length, bool p_full_string, bool p_integer_only, uindex_t &r_length_used, MCNumberRef &r_number);
29+ static bool __MCNumberParseOffset (MCStringRef p_string, uindex_t offset, uindex_t char_count, bool p_integer_only, MCNumberRef &r_number);
30+ static bool __MCNumberParseUnicodeChars (const unichar_t *p_chars, uindex_t p_char_count, bool p_integer_only, MCNumberRef& r_number);
31+
32+ // //////////////////////////////////////////////////////////////////////////////
33+
2634MC_DLLEXPORT_DEF
2735bool MCNumberCreateWithInteger (integer_t p_value, MCNumberRef& r_number)
2836{
@@ -126,31 +134,101 @@ compare_t MCNumberCompareTo(MCNumberRef self, MCNumberRef p_other_self)
126134 return 0 ;
127135}
128136
129- bool __MCNumberParseNativeString (const char *p_string, uindex_t p_length, bool p_full_string, uindex_t &r_length_used, MCNumberRef &r_number)
137+ // ///////////////////////////////////////////////////////////////////////////////
138+
139+ MC_DLLEXPORT_DEF
140+ bool MCNumberParseOffset (MCStringRef p_string, uindex_t offset, uindex_t char_count, bool p_integer_only, MCNumberRef &r_number)
141+ {
142+ return __MCNumberParseOffset (p_string, offset, char_count, p_integer_only, r_number);
143+ }
144+
145+ MC_DLLEXPORT_DEF
146+ bool MCNumberParse (MCStringRef p_string, MCNumberRef &r_number)
147+ {
148+ return MCNumberParseOffset (p_string, 0 , MCStringGetLength (p_string), false , r_number);
149+ }
150+
151+ MC_DLLEXPORT_DEF
152+ bool MCNumberParseInteger (MCStringRef p_string, MCNumberRef &r_number)
153+ {
154+ return MCNumberParseOffset (p_string, 0 , MCStringGetLength (p_string), true , r_number);
155+ }
156+
157+ MC_DLLEXPORT_DEF
158+ bool MCNumberParseUnicodeChars (const unichar_t *p_chars, uindex_t p_char_count, MCNumberRef& r_number)
159+ {
160+ return __MCNumberParseUnicodeChars (p_chars, p_char_count, false , r_number);
161+ }
162+
163+ MC_DLLEXPORT_DEF
164+ bool MCNumberParseOffsetPartial (MCStringRef p_string, uindex_t offset, uindex_t &r_chars_used, MCNumberRef &r_number)
130165{
131166 bool t_success;
132167 t_success = true ;
133168
134- MCNumberRef t_number;
135- t_number = nil;
169+ char *t_buffer;
170+ t_buffer = nil;
171+
172+ const char *t_native_string;
173+ t_native_string = nil;
174+
175+ uindex_t t_length;
176+ t_length = MCStringGetLength (p_string);
177+
178+ if (offset > t_length)
179+ offset = t_length;
180+
181+ if (MCStringIsNative (p_string))
182+ t_native_string = (const char *)MCStringGetNativeCharPtr (p_string) + offset;
183+ else
184+ {
185+ t_success = MCMemoryNewArray (t_length - offset + 1 , t_buffer);
186+
187+ uindex_t t_native_char_count;
188+ if (t_success)
189+ t_success = MCUnicodeCharsMapToNative (MCStringGetCharPtr (p_string) + offset, t_length - offset, (char_t *)t_buffer, t_native_char_count, ' ?' );
190+
191+ t_native_string = t_buffer;
192+ }
193+
194+ if (t_success)
195+ t_success = __MCNumberParseNativeString (t_native_string, t_length - offset, false , false , r_chars_used, r_number);
196+
197+ MCMemoryDeleteArray (t_buffer);
136198
199+ return t_success;
200+ }
201+
202+ // //////////////////////////////////////////////////////////////////////////////
203+
204+ static bool __MCNumberParseNativeString (const char *p_string, uindex_t p_length, bool p_full_string, bool p_integer_only, uindex_t &r_length_used, MCNumberRef &r_number)
205+ {
206+ bool t_success;
207+ t_success = true ;
208+
209+ MCNumberRef t_number;
210+ t_number = nil;
211+
137212 uinteger_t t_base;
138213 t_base = 10 ;
139214
140215 const char *t_string;
141216 t_string = p_string;
142217
143- if (p_length > 2 &&
144- p_string[0 ] == ' 0' &&
145- (p_string[1 ] == ' x' || p_string[1 ] == ' X' ))
146- {
147- // If the string begins with 0x then parse as hex, and discard first two chars
148- t_base = 16 ;
149- t_string += 2 ;
218+ if (!p_integer_only)
219+ {
220+ if (p_length > 2 &&
221+ p_string[0 ] == ' 0' &&
222+ (p_string[1 ] == ' x' || p_string[1 ] == ' X' ))
223+ {
224+ // If the string begins with 0x then parse as hex, and discard first two chars
225+ t_base = 16 ;
226+ t_string += 2 ;
227+ }
150228 }
151229
152230 errno = 0 ;
153-
231+
154232 char *t_end;
155233 t_end = nil;
156234
@@ -166,13 +244,17 @@ bool __MCNumberParseNativeString(const char *p_string, uindex_t p_length, bool p
166244#endif
167245
168246 t_success = (errno != ERANGE) && (p_full_string ? (t_end - p_string == (ptrdiff_t )p_length) : (t_end != t_string));
247+
248+ if (!t_success && p_integer_only)
249+ return false ;
250+
169251 if (t_success)
170252 t_success = MCNumberCreateWithInteger (t_integer, t_number);
171253 // If parsing as base 10 unsigned integer failed, try to parse as real.
172254 else if (t_base == 10 )
173255 {
174256 errno = 0 ;
175-
257+
176258 real64_t t_real;
177259 t_real = strtod (p_string, &t_end);
178260
@@ -181,18 +263,17 @@ bool __MCNumberParseNativeString(const char *p_string, uindex_t p_length, bool p
181263 if (t_success)
182264 t_success = MCNumberCreateWithReal (t_real, t_number);
183265 }
184-
185- if (t_success)
186- {
187- r_number = t_number;
188- r_length_used = t_end - p_string;
189- }
190-
191- return t_success;
266+
267+ if (t_success)
268+ {
269+ r_number = t_number;
270+ r_length_used = t_end - p_string;
271+ }
272+
273+ return t_success;
192274}
193275
194- MC_DLLEXPORT_DEF
195- bool MCNumberParseOffset (MCStringRef p_string, uindex_t offset, uindex_t char_count, MCNumberRef &r_number)
276+ static bool __MCNumberParseOffset (MCStringRef p_string, uindex_t offset, uindex_t char_count, bool p_integer_only, MCNumberRef &r_number)
196277{
197278 uindex_t length = MCStringGetLength (p_string);
198279 if (offset > length)
@@ -207,83 +288,37 @@ bool MCNumberParseOffset(MCStringRef p_string, uindex_t offset, uindex_t char_co
207288 bool t_success;
208289 t_success = false ;
209290
210- uindex_t t_length_used;
211- t_length_used = 0 ;
212-
213- t_success = __MCNumberParseNativeString ((const char *)MCStringGetNativeCharPtr (p_string) + offset, char_count, true , t_length_used, r_number);
214-
215- return t_success;
216- }
217-
218- MC_DLLEXPORT_DEF
219- bool MCNumberParse (MCStringRef p_string, MCNumberRef &r_number)
220- {
221- return MCNumberParseOffset (p_string, 0 , MCStringGetLength (p_string), r_number);
291+ uindex_t t_length_used;
292+ t_length_used = 0 ;
293+
294+ t_success = __MCNumberParseNativeString ((const char *)MCStringGetNativeCharPtr (p_string) + offset, char_count, true , p_integer_only, t_length_used, r_number);
295+
296+ return t_success;
222297}
223298
224- MC_DLLEXPORT_DEF
225- bool MCNumberParseUnicodeChars (const unichar_t *p_chars, uindex_t p_char_count, MCNumberRef& r_number)
299+ static bool __MCNumberParseUnicodeChars (const unichar_t *p_chars, uindex_t p_char_count, bool p_integer_only, MCNumberRef& r_number)
226300{
227- char *t_native_chars;
228- if (!MCMemoryNewArray (p_char_count + 1 , t_native_chars))
229- return false ;
301+ char *t_native_chars;
302+ if (!MCMemoryNewArray (p_char_count + 1 , t_native_chars))
303+ return false ;
230304
231- uindex_t t_native_char_count;
232- MCUnicodeCharsMapToNative (p_chars, p_char_count, (char_t *)t_native_chars, t_native_char_count, ' ?' );
305+ uindex_t t_native_char_count;
306+ MCUnicodeCharsMapToNative (p_chars, p_char_count, (char_t *)t_native_chars, t_native_char_count, ' ?' );
233307
234- bool t_success;
235- t_success = false ;
236-
237- uindex_t t_length_used;
238- t_length_used = 0 ;
239-
240- t_success = __MCNumberParseNativeString (t_native_chars, p_char_count, true , t_length_used, r_number);
308+ bool t_success;
309+ t_success = false ;
241310
242- MCMemoryDeleteArray (t_native_chars);
311+ uindex_t t_length_used;
312+ t_length_used = 0 ;
243313
244- return t_success;
245- }
246-
247- MC_DLLEXPORT_DEF
248- bool MCNumberParseOffsetPartial (MCStringRef p_string, uindex_t offset, uindex_t &r_chars_used, MCNumberRef &r_number)
249- {
250- bool t_success;
251- t_success = true ;
252-
253- char *t_buffer;
254- t_buffer = nil;
255-
256- const char *t_native_string;
257- t_native_string = nil;
258-
259- uindex_t t_length;
260- t_length = MCStringGetLength (p_string);
261-
262- if (offset > t_length)
263- offset = t_length;
264-
265- if (MCStringIsNative (p_string))
266- t_native_string = (const char *)MCStringGetNativeCharPtr (p_string) + offset;
267- else
268- {
269- t_success = MCMemoryNewArray (t_length - offset + 1 , t_buffer);
270-
271- uindex_t t_native_char_count;
272- if (t_success)
273- t_success = MCUnicodeCharsMapToNative (MCStringGetCharPtr (p_string) + offset, t_length - offset, (char_t *)t_buffer, t_native_char_count, ' ?' );
274-
275- t_native_string = t_buffer;
276- }
277-
278- if (t_success)
279- t_success = __MCNumberParseNativeString (t_native_string, t_length - offset, false , r_chars_used, r_number);
280-
281- MCMemoryDeleteArray (t_buffer);
282-
283- return t_success;
314+ t_success = __MCNumberParseNativeString (t_native_chars, p_char_count, true , p_integer_only, t_length_used, r_number);
315+
316+ MCMemoryDeleteArray (t_native_chars);
317+
318+ return t_success;
284319}
285320
286- // //////////////////////////////////////////////////////////////////////////////
321+ // //////////////////////////////////////////////////////////////////////////////////////////////
287322
288323bool __MCNumberCopyDescription (__MCNumber *self, MCStringRef& r_string)
289324{
0 commit comments