1 /* do not edit automatically generated by mc from StringConvert. */
2 /* StringConvert.mod provides functions to convert numbers to and from strings.
4 Copyright (C) 2001-2025 Free Software Foundation, Inc.
5 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
7 This file is part of GNU Modula-2.
9 GNU Modula-2 is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GNU Modula-2 is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
31 # if !defined (PROC_D)
33 typedef void (*PROC_t
) (void);
34 typedef struct { PROC_t proc
; } PROC
;
45 #if defined(__cplusplus)
49 #define _StringConvert_C
51 #include "GStringConvert.h"
56 # include "GDynamicStrings.h"
62 IntegerToString - converts INTEGER, i, into a String. The field with can be specified
63 if non zero. Leading characters are defined by padding and this
64 function will prepend a + if sign is set to TRUE.
65 The base allows the caller to generate binary, octal, decimal, hexidecimal
66 numbers. The value of lower is only used when hexidecimal numbers are
67 generated and if TRUE then digits abcdef are used, and if FALSE then ABCDEF
71 extern "C" DynamicStrings_String
StringConvert_IntegerToString (int i
, unsigned int width
, char padding
, bool sign
, unsigned int base
, bool lower
);
74 CardinalToString - converts CARDINAL, c, into a String. The field with can be specified
75 if non zero. Leading characters are defined by padding.
76 The base allows the caller to generate binary, octal, decimal, hexidecimal
77 numbers. The value of lower is only used when hexidecimal numbers are
78 generated and if TRUE then digits abcdef are used, and if FALSE then ABCDEF
82 extern "C" DynamicStrings_String
StringConvert_CardinalToString (unsigned int c
, unsigned int width
, char padding
, unsigned int base
, bool lower
);
85 StringToInteger - converts a string, s, of, base, into an INTEGER.
86 Leading white space is ignored. It stops converting
87 when either the string is exhausted or if an illegal
89 The parameter found is set TRUE if a number was found.
92 extern "C" int StringConvert_StringToInteger (DynamicStrings_String s
, unsigned int base
, bool *found
);
95 StringToCardinal - converts a string, s, of, base, into a CARDINAL.
96 Leading white space is ignored. It stops converting
97 when either the string is exhausted or if an illegal
99 The parameter found is set TRUE if a number was found.
102 extern "C" unsigned int StringConvert_StringToCardinal (DynamicStrings_String s
, unsigned int base
, bool *found
);
105 LongIntegerToString - converts LONGINT, i, into a String. The field with
106 can be specified if non zero. Leading characters
107 are defined by padding and this function will
108 prepend a + if sign is set to TRUE.
109 The base allows the caller to generate binary,
110 octal, decimal, hexidecimal numbers.
111 The value of lower is only used when hexidecimal
112 numbers are generated and if TRUE then digits
113 abcdef are used, and if FALSE then ABCDEF are used.
116 extern "C" DynamicStrings_String
StringConvert_LongIntegerToString (long int i
, unsigned int width
, char padding
, bool sign
, unsigned int base
, bool lower
);
119 StringToLongInteger - converts a string, s, of, base, into an LONGINT.
120 Leading white space is ignored. It stops converting
121 when either the string is exhausted or if an illegal
123 The parameter found is set TRUE if a number was found.
126 extern "C" long int StringConvert_StringToLongInteger (DynamicStrings_String s
, unsigned int base
, bool *found
);
129 LongCardinalToString - converts LONGCARD, c, into a String. The field
130 width can be specified if non zero. Leading
131 characters are defined by padding.
132 The base allows the caller to generate binary,
133 octal, decimal, hexidecimal numbers.
134 The value of lower is only used when hexidecimal
135 numbers are generated and if TRUE then digits
136 abcdef are used, and if FALSE then ABCDEF are used.
139 extern "C" DynamicStrings_String
StringConvert_LongCardinalToString (long unsigned int c
, unsigned int width
, char padding
, unsigned int base
, bool lower
);
142 StringToLongCardinal - converts a string, s, of, base, into a LONGCARD.
143 Leading white space is ignored. It stops converting
144 when either the string is exhausted or if an illegal
146 The parameter found is set TRUE if a number was found.
149 extern "C" long unsigned int StringConvert_StringToLongCardinal (DynamicStrings_String s
, unsigned int base
, bool *found
);
152 ShortCardinalToString - converts SHORTCARD, c, into a String. The field
153 width can be specified if non zero. Leading
154 characters are defined by padding.
155 The base allows the caller to generate binary,
156 octal, decimal, hexidecimal numbers.
157 The value of lower is only used when hexidecimal
158 numbers are generated and if TRUE then digits
159 abcdef are used, and if FALSE then ABCDEF are used.
162 extern "C" DynamicStrings_String
StringConvert_ShortCardinalToString (short unsigned int c
, unsigned int width
, char padding
, unsigned int base
, bool lower
);
165 StringToShortCardinal - converts a string, s, of, base, into a SHORTCARD.
166 Leading white space is ignored. It stops converting
167 when either the string is exhausted or if an illegal
169 The parameter found is set TRUE if a number was found.
172 extern "C" short unsigned int StringConvert_StringToShortCardinal (DynamicStrings_String s
, unsigned int base
, bool *found
);
175 stoi - decimal string to INTEGER
178 extern "C" int StringConvert_stoi (DynamicStrings_String s
);
181 itos - integer to decimal string.
184 extern "C" DynamicStrings_String
StringConvert_itos (int i
, unsigned int width
, char padding
, bool sign
);
187 ctos - cardinal to decimal string.
190 extern "C" DynamicStrings_String
StringConvert_ctos (unsigned int c
, unsigned int width
, char padding
);
193 stoc - decimal string to CARDINAL
196 extern "C" unsigned int StringConvert_stoc (DynamicStrings_String s
);
199 hstoi - hexidecimal string to INTEGER
202 extern "C" int StringConvert_hstoi (DynamicStrings_String s
);
205 ostoi - octal string to INTEGER
208 extern "C" int StringConvert_ostoi (DynamicStrings_String s
);
211 bstoi - binary string to INTEGER
214 extern "C" int StringConvert_bstoi (DynamicStrings_String s
);
217 hstoc - hexidecimal string to CARDINAL
220 extern "C" unsigned int StringConvert_hstoc (DynamicStrings_String s
);
223 ostoc - octal string to CARDINAL
226 extern "C" unsigned int StringConvert_ostoc (DynamicStrings_String s
);
229 bstoc - binary string to CARDINAL
232 extern "C" unsigned int StringConvert_bstoc (DynamicStrings_String s
);
235 StringToLongreal - returns a LONGREAL and sets found to TRUE if a legal number is seen.
238 extern "C" long double StringConvert_StringToLongreal (DynamicStrings_String s
, bool *found
);
241 LongrealToString - converts a LONGREAL number, Real, which has,
242 TotalWidth, and FractionWidth into a string.
243 It uses decimal notation.
247 LongrealToString(1.0, 4, 2) -> '1.00'
248 LongrealToString(12.3, 5, 2) -> '12.30'
249 LongrealToString(12.3, 6, 2) -> ' 12.30'
250 LongrealToString(12.3, 6, 3) -> '12.300'
252 if total width is too small then the fraction
255 LongrealToString(12.3, 5, 3) -> '12.30'
257 Positive numbers do not have a '+' prepended.
258 Negative numbers will have a '-' prepended and
259 the TotalWidth will need to be large enough
260 to contain the sign, whole number, '.' and
261 fractional components.
264 extern "C" DynamicStrings_String
StringConvert_LongrealToString (long double x
, unsigned int TotalWidth
, unsigned int FractionWidth
);
267 stor - returns a REAL given a string.
270 extern "C" double StringConvert_stor (DynamicStrings_String s
);
273 stolr - returns a LONGREAL given a string.
276 extern "C" long double StringConvert_stolr (DynamicStrings_String s
);
279 ToSigFig - returns a floating point or base 10 integer
280 string which is accurate to, n, significant
281 figures. It will return a new String
282 and, s, will be destroyed.
287 rounded to the following significant figures yields
296 extern "C" DynamicStrings_String
StringConvert_ToSigFig (DynamicStrings_String s
, unsigned int n
);
299 ToDecimalPlaces - returns a floating point or base 10 integer
300 string which is accurate to, n, decimal
301 places. It will return a new String
302 and, s, will be destroyed.
303 Decimal places yields, n, digits after
308 rounded to the following decimal places yields
317 extern "C" DynamicStrings_String
StringConvert_ToDecimalPlaces (DynamicStrings_String s
, unsigned int n
);
320 Assert - implement a simple assert.
323 static void Assert (bool b
, const char *file_
, unsigned int _file_high
, unsigned int line
, const char *func_
, unsigned int _func_high
);
329 static unsigned int Max (unsigned int a
, unsigned int b
);
335 static unsigned int Min (unsigned int a
, unsigned int b
);
338 LongMin - returns the smallest LONGCARD
341 static long unsigned int LongMin (long unsigned int a
, long unsigned int b
);
344 IsDigit - returns TRUE if, ch, lies between '0'..'9'.
347 static bool IsDigit (char ch
);
350 IsDecimalDigitValid - returns the TRUE if, ch, is a base legal decimal digit.
351 If legal then the value is appended numerically onto, c.
354 static bool IsDecimalDigitValid (char ch
, unsigned int base
, unsigned int *c
);
357 IsHexidecimalDigitValid - returns the TRUE if, ch, is a base legal hexidecimal digit.
358 If legal then the value is appended numerically onto, c.
361 static bool IsHexidecimalDigitValid (char ch
, unsigned int base
, unsigned int *c
);
364 IsDecimalDigitValidLong - returns the TRUE if, ch, is a base legal decimal digit.
365 If legal then the value is appended numerically onto, c.
368 static bool IsDecimalDigitValidLong (char ch
, unsigned int base
, long unsigned int *c
);
371 IsHexidecimalDigitValidLong - returns the TRUE if, ch, is a base legal hexidecimal digit.
372 If legal then the value is appended numerically onto, c.
375 static bool IsHexidecimalDigitValidLong (char ch
, unsigned int base
, long unsigned int *c
);
378 IsDecimalDigitValidShort - returns the TRUE if, ch, is a base legal decimal digit.
379 If legal then the value is appended numerically onto, c.
382 static bool IsDecimalDigitValidShort (char ch
, unsigned int base
, short unsigned int *c
);
385 IsHexidecimalDigitValidShort - returns the TRUE if, ch, is a base legal hexidecimal digit.
386 If legal then the value is appended numerically onto, c.
389 static bool IsHexidecimalDigitValidShort (char ch
, unsigned int base
, short unsigned int *c
);
392 ToThePower10 - returns a LONGREAL containing the value of v * 10^power.
395 static long double ToThePower10 (long double v
, int power
);
398 DetermineSafeTruncation - we wish to use TRUNC when converting REAL/LONGREAL
399 into a string for the non fractional component.
400 However we need a simple method to
401 determine the maximum safe truncation value.
404 static unsigned int DetermineSafeTruncation (void);
410 static DynamicStrings_String
rtos (double r
, unsigned int TotalWidth
, unsigned int FractionWidth
);
416 static DynamicStrings_String
lrtos (long double r
, unsigned int TotalWidth
, unsigned int FractionWidth
);
419 doDecimalPlaces - returns a string which is accurate to
420 n decimal places. It returns a new String
421 and, s, will be destroyed.
424 static DynamicStrings_String
doDecimalPlaces (DynamicStrings_String s
, unsigned int n
);
427 doSigFig - returns a string which is accurate to
428 n decimal places. It returns a new String
429 and, s, will be destroyed.
432 static DynamicStrings_String
doSigFig (DynamicStrings_String s
, unsigned int n
);
435 carryOne - add a carry at position, i.
438 static DynamicStrings_String
carryOne (DynamicStrings_String s
, unsigned int i
);
442 Assert - implement a simple assert.
445 static void Assert (bool b
, const char *file_
, unsigned int _file_high
, unsigned int line
, const char *func_
, unsigned int _func_high
)
447 char file
[_file_high
+1];
448 char func
[_func_high
+1];
450 /* make a local copy of each unbounded array. */
451 memcpy (file
, file_
, _file_high
+1);
452 memcpy (func
, func_
, _func_high
+1);
456 M2RTS_ErrorMessage ((const char *) "assert failed", 13, (const char *) file
, _file_high
, line
, (const char *) func
, _func_high
);
465 static unsigned int Max (unsigned int a
, unsigned int b
)
475 /* static analysis guarentees a RETURN statement will be used before here. */
476 __builtin_unreachable ();
484 static unsigned int Min (unsigned int a
, unsigned int b
)
494 /* static analysis guarentees a RETURN statement will be used before here. */
495 __builtin_unreachable ();
500 LongMin - returns the smallest LONGCARD
503 static long unsigned int LongMin (long unsigned int a
, long unsigned int b
)
513 /* static analysis guarentees a RETURN statement will be used before here. */
514 __builtin_unreachable ();
519 IsDigit - returns TRUE if, ch, lies between '0'..'9'.
522 static bool IsDigit (char ch
)
524 return (ch
>= '0') && (ch
<= '9');
525 /* static analysis guarentees a RETURN statement will be used before here. */
526 __builtin_unreachable ();
531 IsDecimalDigitValid - returns the TRUE if, ch, is a base legal decimal digit.
532 If legal then the value is appended numerically onto, c.
535 static bool IsDecimalDigitValid (char ch
, unsigned int base
, unsigned int *c
)
537 if ((IsDigit (ch
)) && (( ((unsigned int) (ch
))- ((unsigned int) ('0'))) < base
))
539 (*c
) = ((*c
)*base
)+( ((unsigned int) (ch
))- ((unsigned int) ('0')));
546 /* static analysis guarentees a RETURN statement will be used before here. */
547 __builtin_unreachable ();
552 IsHexidecimalDigitValid - returns the TRUE if, ch, is a base legal hexidecimal digit.
553 If legal then the value is appended numerically onto, c.
556 static bool IsHexidecimalDigitValid (char ch
, unsigned int base
, unsigned int *c
)
558 if (((ch
>= 'a') && (ch
<= 'f')) && ((( ((unsigned int) (ch
))- ((unsigned int) ('a')))+10) < base
))
560 (*c
) = ((*c
)*base
)+(( ((unsigned int) (ch
))- ((unsigned int) ('a')))+10);
563 else if (((ch
>= 'A') && (ch
<= 'F')) && ((( ((unsigned int) (ch
))- ((unsigned int) ('F')))+10) < base
))
565 /* avoid dangling else. */
566 (*c
) = ((*c
)*base
)+(( ((unsigned int) (ch
))- ((unsigned int) ('A')))+10);
571 /* avoid dangling else. */
574 /* static analysis guarentees a RETURN statement will be used before here. */
575 __builtin_unreachable ();
580 IsDecimalDigitValidLong - returns the TRUE if, ch, is a base legal decimal digit.
581 If legal then the value is appended numerically onto, c.
584 static bool IsDecimalDigitValidLong (char ch
, unsigned int base
, long unsigned int *c
)
586 if ((IsDigit (ch
)) && (( ((unsigned int) (ch
))- ((unsigned int) ('0'))) < base
))
588 (*c
) = (*c
)*((long unsigned int ) (base
+( ((unsigned int) (ch
))- ((unsigned int) ('0')))));
595 /* static analysis guarentees a RETURN statement will be used before here. */
596 __builtin_unreachable ();
601 IsHexidecimalDigitValidLong - returns the TRUE if, ch, is a base legal hexidecimal digit.
602 If legal then the value is appended numerically onto, c.
605 static bool IsHexidecimalDigitValidLong (char ch
, unsigned int base
, long unsigned int *c
)
607 if (((ch
>= 'a') && (ch
<= 'f')) && ((( ((unsigned int) (ch
))- ((unsigned int) ('a')))+10) < base
))
609 (*c
) = (*c
)*((long unsigned int ) (base
+(( ((unsigned int) (ch
))- ((unsigned int) ('a')))+10)));
612 else if (((ch
>= 'A') && (ch
<= 'F')) && ((( ((unsigned int) (ch
))- ((unsigned int) ('F')))+10) < base
))
614 /* avoid dangling else. */
615 (*c
) = (*c
)*((long unsigned int ) (base
+(( ((unsigned int) (ch
))- ((unsigned int) ('A')))+10)));
620 /* avoid dangling else. */
623 /* static analysis guarentees a RETURN statement will be used before here. */
624 __builtin_unreachable ();
629 IsDecimalDigitValidShort - returns the TRUE if, ch, is a base legal decimal digit.
630 If legal then the value is appended numerically onto, c.
633 static bool IsDecimalDigitValidShort (char ch
, unsigned int base
, short unsigned int *c
)
635 if ((IsDigit (ch
)) && (( ((unsigned int) (ch
))- ((unsigned int) ('0'))) < base
))
637 (*c
) = (*c
)*((short unsigned int ) (base
+( ((unsigned int) (ch
))- ((unsigned int) ('0')))));
644 /* static analysis guarentees a RETURN statement will be used before here. */
645 __builtin_unreachable ();
650 IsHexidecimalDigitValidShort - returns the TRUE if, ch, is a base legal hexidecimal digit.
651 If legal then the value is appended numerically onto, c.
654 static bool IsHexidecimalDigitValidShort (char ch
, unsigned int base
, short unsigned int *c
)
656 if (((ch
>= 'a') && (ch
<= 'f')) && ((( ((unsigned int) (ch
))- ((unsigned int) ('a')))+10) < base
))
658 (*c
) = (*c
)*((short unsigned int ) (base
+(( ((unsigned int) (ch
))- ((unsigned int) ('a')))+10)));
661 else if (((ch
>= 'A') && (ch
<= 'F')) && ((( ((unsigned int) (ch
))- ((unsigned int) ('F')))+10) < base
))
663 /* avoid dangling else. */
664 (*c
) = (*c
)*((short unsigned int ) (base
+(( ((unsigned int) (ch
))- ((unsigned int) ('A')))+10)));
669 /* avoid dangling else. */
672 /* static analysis guarentees a RETURN statement will be used before here. */
673 __builtin_unreachable ();
678 ToThePower10 - returns a LONGREAL containing the value of v * 10^power.
681 static long double ToThePower10 (long double v
, int power
)
703 /* static analysis guarentees a RETURN statement will be used before here. */
704 __builtin_unreachable ();
709 DetermineSafeTruncation - we wish to use TRUNC when converting REAL/LONGREAL
710 into a string for the non fractional component.
711 However we need a simple method to
712 determine the maximum safe truncation value.
715 static unsigned int DetermineSafeTruncation (void)
717 double MaxPowerOfTen
;
718 unsigned int LogPower
;
720 MaxPowerOfTen
= static_cast<double> (1.0);
722 while ((MaxPowerOfTen
*10.0) < ((double) ((INT_MAX
) / 10)))
724 MaxPowerOfTen
= MaxPowerOfTen
*10.0;
728 /* static analysis guarentees a RETURN statement will be used before here. */
729 __builtin_unreachable ();
737 static DynamicStrings_String
rtos (double r
, unsigned int TotalWidth
, unsigned int FractionWidth
)
740 __builtin_unreachable ();
741 return static_cast<DynamicStrings_String
> (NULL
);
742 /* static analysis guarentees a RETURN statement will be used before here. */
743 __builtin_unreachable ();
751 static DynamicStrings_String
lrtos (long double r
, unsigned int TotalWidth
, unsigned int FractionWidth
)
754 __builtin_unreachable ();
755 return static_cast<DynamicStrings_String
> (NULL
);
756 /* static analysis guarentees a RETURN statement will be used before here. */
757 __builtin_unreachable ();
762 doDecimalPlaces - returns a string which is accurate to
763 n decimal places. It returns a new String
764 and, s, will be destroyed.
767 static DynamicStrings_String
doDecimalPlaces (DynamicStrings_String s
, unsigned int n
)
772 DynamicStrings_String t
;
773 DynamicStrings_String tenths
;
774 DynamicStrings_String hundreths
;
776 l
= DynamicStrings_Length (s
);
779 point
= DynamicStrings_Index (s
, '.', 0);
782 s
= DynamicStrings_Slice (DynamicStrings_Mark (s
), 1, 0);
786 /* avoid dangling else. */
787 s
= DynamicStrings_ConCat (DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, point
), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s
), point
+1, 0)));
791 /* avoid dangling else. */
792 s
= DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, point
);
794 l
= DynamicStrings_Length (s
);
798 /* skip over leading zeros */
799 while ((i
< l
) && ((DynamicStrings_char (s
, i
)) == '0'))
803 /* was the string full of zeros? */
804 if ((i
== l
) && ((DynamicStrings_char (s
, i
-1)) == '0'))
806 s
= DynamicStrings_KillString (s
);
807 s
= DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "0.", 2), DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), n
)));
811 /* insert leading zero */
812 s
= DynamicStrings_ConCat (DynamicStrings_InitStringChar ('0'), DynamicStrings_Mark (s
));
813 point
+= 1; /* and move point position to correct place */
814 l
= DynamicStrings_Length (s
); /* update new length */
815 i
= point
; /* update new length */
816 while ((n
> 1) && (i
< l
))
823 t
= DynamicStrings_Dup (s
);
824 hundreths
= DynamicStrings_Slice (DynamicStrings_Mark (s
), i
+1, i
+3);
826 if ((StringConvert_stoc (hundreths
)) >= 50)
828 s
= carryOne (DynamicStrings_Mark (s
), static_cast<unsigned int> (i
));
830 hundreths
= DynamicStrings_KillString (hundreths
);
834 /* avoid dangling else. */
835 t
= DynamicStrings_Dup (s
);
836 tenths
= DynamicStrings_Slice (DynamicStrings_Mark (s
), i
+1, i
+2);
838 if ((StringConvert_stoc (tenths
)) >= 5)
840 s
= carryOne (DynamicStrings_Mark (s
), static_cast<unsigned int> (i
));
842 tenths
= DynamicStrings_KillString (tenths
);
844 /* check whether we need to remove the leading zero */
845 if ((DynamicStrings_char (s
, 0)) == '0')
847 s
= DynamicStrings_Slice (DynamicStrings_Mark (s
), 1, 0);
853 s
= DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, i
);
854 l
= DynamicStrings_Length (s
);
857 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), static_cast<unsigned int> (point
-l
)));
860 /* re-insert the point */
863 /* avoid gcc warning by using compound statement even if not strictly necessary. */
866 s
= DynamicStrings_ConCat (DynamicStrings_InitStringChar ('.'), DynamicStrings_Mark (s
));
870 s
= DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, point
), '.'), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s
), point
, 0)));
874 /* static analysis guarentees a RETURN statement will be used before here. */
875 __builtin_unreachable ();
880 doSigFig - returns a string which is accurate to
881 n decimal places. It returns a new String
882 and, s, will be destroyed.
885 static DynamicStrings_String
doSigFig (DynamicStrings_String s
, unsigned int n
)
891 DynamicStrings_String t
;
892 DynamicStrings_String tenths
;
893 DynamicStrings_String hundreths
;
895 l
= DynamicStrings_Length (s
);
898 point
= DynamicStrings_Index (s
, '.', 0);
903 s
= DynamicStrings_Slice (DynamicStrings_Mark (s
), 1, 0);
907 /* avoid dangling else. */
908 s
= DynamicStrings_ConCat (DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, point
), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s
), point
+1, 0)));
912 /* avoid dangling else. */
913 s
= DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, point
);
918 s
= DynamicStrings_Dup (DynamicStrings_Mark (s
));
920 l
= DynamicStrings_Length (s
);
924 /* skip over leading zeros */
925 while ((i
< l
) && ((DynamicStrings_char (s
, i
)) == '0'))
929 /* was the string full of zeros? */
930 if ((i
== l
) && ((DynamicStrings_char (s
, i
-1)) == '0'))
932 /* truncate string */
933 s
= DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, static_cast<int> (n
));
937 /* add a leading zero in case we need to overflow the carry */
938 z
= i
; /* remember where we inserted zero */
939 if (z
== 0) /* remember where we inserted zero */
941 s
= DynamicStrings_ConCat (DynamicStrings_InitStringChar ('0'), DynamicStrings_Mark (s
));
945 s
= DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, i
), '0'), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s
), i
, 0)));
947 n
+= 1; /* and increase the number of sig figs needed */
948 l
= DynamicStrings_Length (s
); /* and increase the number of sig figs needed */
949 while ((n
> 1) && (i
< l
))
956 t
= DynamicStrings_Dup (s
);
957 hundreths
= DynamicStrings_Slice (DynamicStrings_Mark (s
), i
+1, i
+3);
959 if ((StringConvert_stoc (hundreths
)) >= 50)
961 s
= carryOne (DynamicStrings_Mark (s
), static_cast<unsigned int> (i
));
963 hundreths
= DynamicStrings_KillString (hundreths
);
967 /* avoid dangling else. */
968 t
= DynamicStrings_Dup (s
);
969 tenths
= DynamicStrings_Slice (DynamicStrings_Mark (s
), i
+1, i
+2);
971 if ((StringConvert_stoc (tenths
)) >= 5)
973 s
= carryOne (DynamicStrings_Mark (s
), static_cast<unsigned int> (i
));
975 tenths
= DynamicStrings_KillString (tenths
);
977 /* check whether we need to remove the leading zero */
978 if ((DynamicStrings_char (s
, z
)) == '0')
982 s
= DynamicStrings_Slice (DynamicStrings_Mark (s
), z
+1, 0);
986 s
= DynamicStrings_ConCat (DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, z
), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s
), z
+1, 0)));
988 l
= DynamicStrings_Length (s
);
996 s
= DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, i
);
997 l
= DynamicStrings_Length (s
);
1000 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), static_cast<unsigned int> (point
-l
)));
1003 /* re-insert the point */
1006 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1009 s
= DynamicStrings_ConCat (DynamicStrings_InitStringChar ('.'), DynamicStrings_Mark (s
));
1013 s
= DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, point
), '.'), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s
), point
, 0)));
1017 /* static analysis guarentees a RETURN statement will be used before here. */
1018 __builtin_unreachable ();
1023 carryOne - add a carry at position, i.
1026 static DynamicStrings_String
carryOne (DynamicStrings_String s
, unsigned int i
)
1030 if (IsDigit (DynamicStrings_char (s
, static_cast<int> (i
))))
1032 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1033 if ((DynamicStrings_char (s
, static_cast<int> (i
))) == '9')
1037 s
= DynamicStrings_ConCat (DynamicStrings_InitStringChar ('1'), DynamicStrings_Mark (s
));
1042 s
= DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, static_cast<int> (i
)), '0'), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s
), static_cast<int> (i
+1), 0)));
1043 return carryOne (s
, i
-1);
1050 s
= DynamicStrings_ConCat (DynamicStrings_InitStringChar ( ((char) ( ((unsigned int) (DynamicStrings_char (s
, static_cast<int> (i
))))+1))), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s
), static_cast<int> (i
+1), 0)));
1054 s
= DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, static_cast<int> (i
)), ((char) ( ((unsigned int) (DynamicStrings_char (s
, static_cast<int> (i
))))+1))), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s
), static_cast<int> (i
+1), 0)));
1060 /* static analysis guarentees a RETURN statement will be used before here. */
1061 __builtin_unreachable ();
1066 IntegerToString - converts INTEGER, i, into a String. The field with can be specified
1067 if non zero. Leading characters are defined by padding and this
1068 function will prepend a + if sign is set to TRUE.
1069 The base allows the caller to generate binary, octal, decimal, hexidecimal
1070 numbers. The value of lower is only used when hexidecimal numbers are
1071 generated and if TRUE then digits abcdef are used, and if FALSE then ABCDEF
1075 extern "C" DynamicStrings_String
StringConvert_IntegerToString (int i
, unsigned int width
, char padding
, bool sign
, unsigned int base
, bool lower
)
1077 DynamicStrings_String s
;
1084 /* remember that -15 MOD 4 = 1 in Modula-2 */
1085 c
= ((unsigned int ) (abs (i
+1)))+1;
1088 return DynamicStrings_ConCat (StringConvert_IntegerToString (-((int ) (c
/ base
)), width
-1, padding
, sign
, base
, lower
), DynamicStrings_Mark (StringConvert_IntegerToString (static_cast<int> (c
% base
), 0, ' ', false, base
, lower
)));
1092 return DynamicStrings_ConCat (StringConvert_IntegerToString (-((int ) (c
/ base
)), 0, padding
, sign
, base
, lower
), DynamicStrings_Mark (StringConvert_IntegerToString (static_cast<int> (c
% base
), 0, ' ', false, base
, lower
)));
1097 s
= DynamicStrings_InitString ((const char *) "-", 1);
1105 s
= DynamicStrings_InitString ((const char *) "+", 1);
1109 s
= DynamicStrings_InitString ((const char *) "", 0);
1112 if (i
> (((int ) (base
))-1))
1114 s
= DynamicStrings_ConCat (DynamicStrings_ConCat (s
, DynamicStrings_Mark (StringConvert_IntegerToString (static_cast<int> (((unsigned int ) (i
)) / base
), 0, ' ', false, base
, lower
))), DynamicStrings_Mark (StringConvert_IntegerToString (static_cast<int> (((unsigned int ) (i
)) % base
), 0, ' ', false, base
, lower
)));
1120 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (i
))+ ((unsigned int) ('0')))))));
1126 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (i
))+ ((unsigned int) ('a')))-10)))));
1130 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (i
))+ ((unsigned int) ('A')))-10)))));
1134 if (width
> (DynamicStrings_Length (s
)))
1136 return DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (padding
)), width
-(DynamicStrings_Length (s
))), DynamicStrings_Mark (s
));
1139 /* static analysis guarentees a RETURN statement will be used before here. */
1140 __builtin_unreachable ();
1145 CardinalToString - converts CARDINAL, c, into a String. The field with can be specified
1146 if non zero. Leading characters are defined by padding.
1147 The base allows the caller to generate binary, octal, decimal, hexidecimal
1148 numbers. The value of lower is only used when hexidecimal numbers are
1149 generated and if TRUE then digits abcdef are used, and if FALSE then ABCDEF
1153 extern "C" DynamicStrings_String
StringConvert_CardinalToString (unsigned int c
, unsigned int width
, char padding
, unsigned int base
, bool lower
)
1155 DynamicStrings_String s
;
1157 s
= DynamicStrings_InitString ((const char *) "", 0);
1160 s
= DynamicStrings_ConCat (DynamicStrings_ConCat (s
, DynamicStrings_Mark (StringConvert_CardinalToString (c
/ base
, 0, ' ', base
, lower
))), DynamicStrings_Mark (StringConvert_CardinalToString (c
% base
, 0, ' ', base
, lower
)));
1166 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) (c
+ ((unsigned int) ('0')))))));
1172 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((c
+ ((unsigned int) ('a')))-10)))));
1176 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((c
+ ((unsigned int) ('A')))-10)))));
1180 if (width
> (DynamicStrings_Length (s
)))
1182 return DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (padding
)), width
-(DynamicStrings_Length (s
))), s
);
1185 /* static analysis guarentees a RETURN statement will be used before here. */
1186 __builtin_unreachable ();
1191 StringToInteger - converts a string, s, of, base, into an INTEGER.
1192 Leading white space is ignored. It stops converting
1193 when either the string is exhausted or if an illegal
1195 The parameter found is set TRUE if a number was found.
1198 extern "C" int StringConvert_StringToInteger (DynamicStrings_String s
, unsigned int base
, bool *found
)
1205 s
= DynamicStrings_RemoveWhitePrefix (s
); /* returns a new string, s */
1206 l
= DynamicStrings_Length (s
); /* returns a new string, s */
1212 /* parse leading + and - */
1213 while (((DynamicStrings_char (s
, static_cast<int> (n
))) == '-') || ((DynamicStrings_char (s
, static_cast<int> (n
))) == '+'))
1215 if ((DynamicStrings_char (s
, static_cast<int> (n
))) == '-')
1217 negative
= ! negative
;
1221 while ((n
< l
) && ((IsDecimalDigitValid (DynamicStrings_char (s
, static_cast<int> (n
)), base
, &c
)) || (IsHexidecimalDigitValid (DynamicStrings_char (s
, static_cast<int> (n
)), base
, &c
))))
1227 s
= DynamicStrings_KillString (s
);
1230 return -((int ) (Min (((unsigned int ) (INT_MAX
))+1, c
)));
1234 return (int ) (Min (static_cast<unsigned int> (INT_MAX
), c
));
1236 /* static analysis guarentees a RETURN statement will be used before here. */
1237 __builtin_unreachable ();
1242 StringToCardinal - converts a string, s, of, base, into a CARDINAL.
1243 Leading white space is ignored. It stops converting
1244 when either the string is exhausted or if an illegal
1246 The parameter found is set TRUE if a number was found.
1249 extern "C" unsigned int StringConvert_StringToCardinal (DynamicStrings_String s
, unsigned int base
, bool *found
)
1255 s
= DynamicStrings_RemoveWhitePrefix (s
); /* returns a new string, s */
1256 l
= DynamicStrings_Length (s
); /* returns a new string, s */
1261 /* parse leading + */
1262 while ((DynamicStrings_char (s
, static_cast<int> (n
))) == '+')
1266 while ((n
< l
) && ((IsDecimalDigitValid (DynamicStrings_char (s
, static_cast<int> (n
)), base
, &c
)) || (IsHexidecimalDigitValid (DynamicStrings_char (s
, static_cast<int> (n
)), base
, &c
))))
1272 s
= DynamicStrings_KillString (s
);
1274 /* static analysis guarentees a RETURN statement will be used before here. */
1275 __builtin_unreachable ();
1280 LongIntegerToString - converts LONGINT, i, into a String. The field with
1281 can be specified if non zero. Leading characters
1282 are defined by padding and this function will
1283 prepend a + if sign is set to TRUE.
1284 The base allows the caller to generate binary,
1285 octal, decimal, hexidecimal numbers.
1286 The value of lower is only used when hexidecimal
1287 numbers are generated and if TRUE then digits
1288 abcdef are used, and if FALSE then ABCDEF are used.
1291 extern "C" DynamicStrings_String
StringConvert_LongIntegerToString (long int i
, unsigned int width
, char padding
, bool sign
, unsigned int base
, bool lower
)
1293 DynamicStrings_String s
;
1294 long unsigned int c
;
1298 if (i
== (LONG_MIN
))
1300 /* remember that -15 MOD 4 is 1 in Modula-2, and although ABS(MIN(LONGINT)+1)
1301 is very likely MAX(LONGINT), it is safer not to assume this is the case */
1302 c
= ((long unsigned int ) (labs (i
+1)))+1;
1305 return DynamicStrings_ConCat (StringConvert_LongIntegerToString (-((long int ) (c
/ ((long unsigned int ) (base
)))), width
-1, padding
, sign
, base
, lower
), DynamicStrings_Mark (StringConvert_LongIntegerToString (static_cast<long int> (c
% ((long unsigned int ) (base
))), 0, ' ', false, base
, lower
)));
1309 return DynamicStrings_ConCat (StringConvert_LongIntegerToString (-((long int ) (c
/ ((long unsigned int ) (base
)))), 0, padding
, sign
, base
, lower
), DynamicStrings_Mark (StringConvert_LongIntegerToString (static_cast<long int> (c
% ((long unsigned int ) (base
))), 0, ' ', false, base
, lower
)));
1314 s
= DynamicStrings_InitString ((const char *) "-", 1);
1322 s
= DynamicStrings_InitString ((const char *) "+", 1);
1326 s
= DynamicStrings_InitString ((const char *) "", 0);
1329 if (i
> ((long int ) (base
-1)))
1331 s
= DynamicStrings_ConCat (DynamicStrings_ConCat (s
, DynamicStrings_Mark (StringConvert_LongIntegerToString (i
/ ((long int ) (base
)), 0, ' ', false, base
, lower
))), DynamicStrings_Mark (StringConvert_LongIntegerToString (i
% ((long int ) (base
)), 0, ' ', false, base
, lower
)));
1337 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (i
))+ ((unsigned int) ('0')))))));
1343 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (i
))+ ((unsigned int) ('a')))-10)))));
1347 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (i
))+ ((unsigned int) ('A')))-10)))));
1351 if (width
> (DynamicStrings_Length (s
)))
1353 return DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (padding
)), width
-(DynamicStrings_Length (s
))), s
);
1356 /* static analysis guarentees a RETURN statement will be used before here. */
1357 __builtin_unreachable ();
1362 StringToLongInteger - converts a string, s, of, base, into an LONGINT.
1363 Leading white space is ignored. It stops converting
1364 when either the string is exhausted or if an illegal
1366 The parameter found is set TRUE if a number was found.
1369 extern "C" long int StringConvert_StringToLongInteger (DynamicStrings_String s
, unsigned int base
, bool *found
)
1373 long unsigned int c
;
1376 s
= DynamicStrings_RemoveWhitePrefix (s
); /* returns a new string, s */
1377 l
= DynamicStrings_Length (s
); /* returns a new string, s */
1383 /* parse leading + and - */
1384 while (((DynamicStrings_char (s
, static_cast<int> (n
))) == '-') || ((DynamicStrings_char (s
, static_cast<int> (n
))) == '+'))
1386 if ((DynamicStrings_char (s
, static_cast<int> (n
))) == '-')
1388 negative
= ! negative
;
1392 while ((n
< l
) && ((IsDecimalDigitValidLong (DynamicStrings_char (s
, static_cast<int> (n
)), base
, &c
)) || (IsHexidecimalDigitValidLong (DynamicStrings_char (s
, static_cast<int> (n
)), base
, &c
))))
1398 s
= DynamicStrings_KillString (s
);
1401 return -((long int ) (LongMin (((long unsigned int ) (LONG_MAX
))+1, c
)));
1405 return (long int ) (LongMin (static_cast<long unsigned int> (LONG_MAX
), c
));
1407 /* static analysis guarentees a RETURN statement will be used before here. */
1408 __builtin_unreachable ();
1413 LongCardinalToString - converts LONGCARD, c, into a String. The field
1414 width can be specified if non zero. Leading
1415 characters are defined by padding.
1416 The base allows the caller to generate binary,
1417 octal, decimal, hexidecimal numbers.
1418 The value of lower is only used when hexidecimal
1419 numbers are generated and if TRUE then digits
1420 abcdef are used, and if FALSE then ABCDEF are used.
1423 extern "C" DynamicStrings_String
StringConvert_LongCardinalToString (long unsigned int c
, unsigned int width
, char padding
, unsigned int base
, bool lower
)
1425 DynamicStrings_String s
;
1427 s
= DynamicStrings_InitString ((const char *) "", 0);
1428 if (c
> ((long unsigned int ) (base
-1)))
1430 s
= DynamicStrings_ConCat (DynamicStrings_ConCat (s
, StringConvert_LongCardinalToString (c
/ ((long unsigned int ) (base
)), 0, ' ', base
, lower
)), StringConvert_LongCardinalToString (c
% ((long unsigned int ) (base
)), 0, ' ', base
, lower
));
1436 s
= DynamicStrings_ConCat (s
, DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (c
))+ ((unsigned int) ('0'))))));
1442 s
= DynamicStrings_ConCat (s
, DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (c
))+ ((unsigned int) ('a')))-10))));
1446 s
= DynamicStrings_ConCat (s
, DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (c
))+ ((unsigned int) ('A')))-10))));
1450 if (width
> (DynamicStrings_Length (s
)))
1452 return DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (padding
)), width
-(DynamicStrings_Length (s
))), s
);
1455 /* static analysis guarentees a RETURN statement will be used before here. */
1456 __builtin_unreachable ();
1461 StringToLongCardinal - converts a string, s, of, base, into a LONGCARD.
1462 Leading white space is ignored. It stops converting
1463 when either the string is exhausted or if an illegal
1465 The parameter found is set TRUE if a number was found.
1468 extern "C" long unsigned int StringConvert_StringToLongCardinal (DynamicStrings_String s
, unsigned int base
, bool *found
)
1472 long unsigned int c
;
1474 s
= DynamicStrings_RemoveWhitePrefix (s
); /* returns a new string, s */
1475 l
= DynamicStrings_Length (s
); /* returns a new string, s */
1480 /* parse leading + */
1481 while ((DynamicStrings_char (s
, static_cast<int> (n
))) == '+')
1485 while ((n
< l
) && ((IsDecimalDigitValidLong (DynamicStrings_char (s
, static_cast<int> (n
)), base
, &c
)) || (IsHexidecimalDigitValidLong (DynamicStrings_char (s
, static_cast<int> (n
)), base
, &c
))))
1491 s
= DynamicStrings_KillString (s
);
1493 /* static analysis guarentees a RETURN statement will be used before here. */
1494 __builtin_unreachable ();
1499 ShortCardinalToString - converts SHORTCARD, c, into a String. The field
1500 width can be specified if non zero. Leading
1501 characters are defined by padding.
1502 The base allows the caller to generate binary,
1503 octal, decimal, hexidecimal numbers.
1504 The value of lower is only used when hexidecimal
1505 numbers are generated and if TRUE then digits
1506 abcdef are used, and if FALSE then ABCDEF are used.
1509 extern "C" DynamicStrings_String
StringConvert_ShortCardinalToString (short unsigned int c
, unsigned int width
, char padding
, unsigned int base
, bool lower
)
1511 DynamicStrings_String s
;
1513 s
= DynamicStrings_InitString ((const char *) "", 0);
1514 if (((unsigned int ) (c
)) > (base
-1))
1516 s
= DynamicStrings_ConCat (DynamicStrings_ConCat (s
, StringConvert_ShortCardinalToString (c
/ ((short unsigned int ) (base
)), 0, ' ', base
, lower
)), StringConvert_ShortCardinalToString (c
% ((short unsigned int ) (base
)), 0, ' ', base
, lower
));
1522 s
= DynamicStrings_ConCat (s
, DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (c
))+ ((unsigned int) ('0'))))));
1528 s
= DynamicStrings_ConCat (s
, DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (c
))+ ((unsigned int) ('a')))-10))));
1532 s
= DynamicStrings_ConCat (s
, DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (c
))+ ((unsigned int) ('A')))-10))));
1536 if (width
> (DynamicStrings_Length (s
)))
1538 return DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (padding
)), width
-(DynamicStrings_Length (s
))), s
);
1541 /* static analysis guarentees a RETURN statement will be used before here. */
1542 __builtin_unreachable ();
1547 StringToShortCardinal - converts a string, s, of, base, into a SHORTCARD.
1548 Leading white space is ignored. It stops converting
1549 when either the string is exhausted or if an illegal
1551 The parameter found is set TRUE if a number was found.
1554 extern "C" short unsigned int StringConvert_StringToShortCardinal (DynamicStrings_String s
, unsigned int base
, bool *found
)
1558 short unsigned int c
;
1560 s
= DynamicStrings_RemoveWhitePrefix (s
); /* returns a new string, s */
1561 l
= DynamicStrings_Length (s
); /* returns a new string, s */
1566 /* parse leading + */
1567 while ((DynamicStrings_char (s
, static_cast<int> (n
))) == '+')
1571 while ((n
< l
) && ((IsDecimalDigitValidShort (DynamicStrings_char (s
, static_cast<int> (n
)), base
, &c
)) || (IsHexidecimalDigitValidShort (DynamicStrings_char (s
, static_cast<int> (n
)), base
, &c
))))
1577 s
= DynamicStrings_KillString (s
);
1579 /* static analysis guarentees a RETURN statement will be used before here. */
1580 __builtin_unreachable ();
1585 stoi - decimal string to INTEGER
1588 extern "C" int StringConvert_stoi (DynamicStrings_String s
)
1592 return StringConvert_StringToInteger (s
, 10, &found
);
1593 /* static analysis guarentees a RETURN statement will be used before here. */
1594 __builtin_unreachable ();
1599 itos - integer to decimal string.
1602 extern "C" DynamicStrings_String
StringConvert_itos (int i
, unsigned int width
, char padding
, bool sign
)
1604 return StringConvert_IntegerToString (i
, width
, padding
, sign
, 10, false);
1605 /* static analysis guarentees a RETURN statement will be used before here. */
1606 __builtin_unreachable ();
1611 ctos - cardinal to decimal string.
1614 extern "C" DynamicStrings_String
StringConvert_ctos (unsigned int c
, unsigned int width
, char padding
)
1616 return StringConvert_CardinalToString (c
, width
, padding
, 10, false);
1617 /* static analysis guarentees a RETURN statement will be used before here. */
1618 __builtin_unreachable ();
1623 stoc - decimal string to CARDINAL
1626 extern "C" unsigned int StringConvert_stoc (DynamicStrings_String s
)
1630 return StringConvert_StringToCardinal (s
, 10, &found
);
1631 /* static analysis guarentees a RETURN statement will be used before here. */
1632 __builtin_unreachable ();
1637 hstoi - hexidecimal string to INTEGER
1640 extern "C" int StringConvert_hstoi (DynamicStrings_String s
)
1644 return StringConvert_StringToInteger (s
, 16, &found
);
1645 /* static analysis guarentees a RETURN statement will be used before here. */
1646 __builtin_unreachable ();
1651 ostoi - octal string to INTEGER
1654 extern "C" int StringConvert_ostoi (DynamicStrings_String s
)
1658 return StringConvert_StringToInteger (s
, 8, &found
);
1659 /* static analysis guarentees a RETURN statement will be used before here. */
1660 __builtin_unreachable ();
1665 bstoi - binary string to INTEGER
1668 extern "C" int StringConvert_bstoi (DynamicStrings_String s
)
1672 return StringConvert_StringToInteger (s
, 2, &found
);
1673 /* static analysis guarentees a RETURN statement will be used before here. */
1674 __builtin_unreachable ();
1679 hstoc - hexidecimal string to CARDINAL
1682 extern "C" unsigned int StringConvert_hstoc (DynamicStrings_String s
)
1686 return StringConvert_StringToCardinal (s
, 16, &found
);
1687 /* static analysis guarentees a RETURN statement will be used before here. */
1688 __builtin_unreachable ();
1693 ostoc - octal string to CARDINAL
1696 extern "C" unsigned int StringConvert_ostoc (DynamicStrings_String s
)
1700 return StringConvert_StringToCardinal (s
, 8, &found
);
1701 /* static analysis guarentees a RETURN statement will be used before here. */
1702 __builtin_unreachable ();
1707 bstoc - binary string to CARDINAL
1710 extern "C" unsigned int StringConvert_bstoc (DynamicStrings_String s
)
1714 return StringConvert_StringToCardinal (s
, 2, &found
);
1715 /* static analysis guarentees a RETURN statement will be used before here. */
1716 __builtin_unreachable ();
1721 StringToLongreal - returns a LONGREAL and sets found to TRUE if a legal number is seen.
1724 extern "C" long double StringConvert_StringToLongreal (DynamicStrings_String s
, bool *found
)
1729 s
= DynamicStrings_RemoveWhitePrefix (s
); /* new string is created */
1730 value
= ldtoa_strtold (DynamicStrings_string (s
), &error
); /* new string is created */
1731 s
= DynamicStrings_KillString (s
);
1734 /* static analysis guarentees a RETURN statement will be used before here. */
1735 __builtin_unreachable ();
1740 LongrealToString - converts a LONGREAL number, Real, which has,
1741 TotalWidth, and FractionWidth into a string.
1742 It uses decimal notation.
1746 LongrealToString(1.0, 4, 2) -> '1.00'
1747 LongrealToString(12.3, 5, 2) -> '12.30'
1748 LongrealToString(12.3, 6, 2) -> ' 12.30'
1749 LongrealToString(12.3, 6, 3) -> '12.300'
1751 if total width is too small then the fraction
1754 LongrealToString(12.3, 5, 3) -> '12.30'
1756 Positive numbers do not have a '+' prepended.
1757 Negative numbers will have a '-' prepended and
1758 the TotalWidth will need to be large enough
1759 to contain the sign, whole number, '.' and
1760 fractional components.
1763 extern "C" DynamicStrings_String
StringConvert_LongrealToString (long double x
, unsigned int TotalWidth
, unsigned int FractionWidth
)
1766 DynamicStrings_String s
;
1772 if (TotalWidth
== 0)
1774 maxprecision
= true;
1775 r
= ldtoa_ldtoa (x
, static_cast<int> (ldtoa_decimaldigits
), 100, &point
, &sign
);
1779 r
= ldtoa_ldtoa (x
, static_cast<int> (ldtoa_decimaldigits
), 100, &point
, &sign
);
1781 s
= DynamicStrings_InitStringCharStar (r
);
1783 l
= DynamicStrings_Length (s
);
1786 /* avoid dangling else. */
1787 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), static_cast<unsigned int> (point
-l
))));
1788 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ".0", 2)));
1789 if (! maxprecision
&& (FractionWidth
> 0))
1792 if (((int ) (FractionWidth
)) > (point
-l
))
1794 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "0", 1)), FractionWidth
)));
1800 /* avoid dangling else. */
1801 s
= DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), static_cast<unsigned int> (-point
)), DynamicStrings_Mark (s
));
1802 l
= DynamicStrings_Length (s
);
1803 s
= DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "0.", 2), DynamicStrings_Mark (s
));
1804 if (! maxprecision
&& (l
< ((int ) (FractionWidth
))))
1806 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "0", 1)), static_cast<unsigned int> (((int ) (FractionWidth
))-l
))));
1811 /* avoid dangling else. */
1814 s
= DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "0.", 2), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s
), point
, 0)));
1818 s
= DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, point
), '.'), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s
), point
, 0)));
1820 if (! maxprecision
&& ((l
-point
) < ((int ) (FractionWidth
))))
1822 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "0", 1)), static_cast<unsigned int> (((int ) (FractionWidth
))-(l
-point
)))));
1825 if ((DynamicStrings_Length (s
)) > TotalWidth
)
1827 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1832 s
= DynamicStrings_Slice (DynamicStrings_Mark (StringConvert_ToDecimalPlaces (s
, FractionWidth
)), 0, static_cast<int> (TotalWidth
-1));
1833 s
= DynamicStrings_ConCat (DynamicStrings_InitStringChar ('-'), DynamicStrings_Mark (s
));
1838 /* minus 1 because all results will include a '.' */
1839 s
= DynamicStrings_Slice (DynamicStrings_Mark (StringConvert_ToDecimalPlaces (s
, FractionWidth
)), 0, static_cast<int> (TotalWidth
));
1846 s
= StringConvert_ToDecimalPlaces (s
, FractionWidth
);
1847 s
= DynamicStrings_ConCat (DynamicStrings_InitStringChar ('-'), DynamicStrings_Mark (s
));
1852 /* minus 1 because all results will include a '.' */
1853 s
= StringConvert_ToDecimalPlaces (s
, FractionWidth
);
1857 if ((DynamicStrings_Length (s
)) < TotalWidth
)
1859 s
= DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (' ')), TotalWidth
-(DynamicStrings_Length (s
))), DynamicStrings_Mark (s
));
1862 /* static analysis guarentees a RETURN statement will be used before here. */
1863 __builtin_unreachable ();
1868 stor - returns a REAL given a string.
1871 extern "C" double StringConvert_stor (DynamicStrings_String s
)
1875 return (double ) (StringConvert_StringToLongreal (s
, &found
));
1876 /* static analysis guarentees a RETURN statement will be used before here. */
1877 __builtin_unreachable ();
1882 stolr - returns a LONGREAL given a string.
1885 extern "C" long double StringConvert_stolr (DynamicStrings_String s
)
1889 return StringConvert_StringToLongreal (s
, &found
);
1890 /* static analysis guarentees a RETURN statement will be used before here. */
1891 __builtin_unreachable ();
1896 ToSigFig - returns a floating point or base 10 integer
1897 string which is accurate to, n, significant
1898 figures. It will return a new String
1899 and, s, will be destroyed.
1904 rounded to the following significant figures yields
1913 extern "C" DynamicStrings_String
StringConvert_ToSigFig (DynamicStrings_String s
, unsigned int n
)
1918 Assert ((IsDigit (DynamicStrings_char (s
, 0))) || ((DynamicStrings_char (s
, 0)) == '.'), (const char *) "../../gcc/m2/gm2-libs/StringConvert.mod", 39, 1220, (const char *) "ToSigFig", 8);
1919 point
= DynamicStrings_Index (s
, '.', 0);
1922 poTen
= DynamicStrings_Length (s
);
1928 s
= doSigFig (s
, n
);
1929 /* if the last character is '.' remove it */
1930 if (((DynamicStrings_Length (s
)) > 0) && ((DynamicStrings_char (s
, -1)) == '.'))
1932 return DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, -1);
1936 if (poTen
> (DynamicStrings_Length (s
)))
1938 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), poTen
-(DynamicStrings_Length (s
)))));
1942 /* static analysis guarentees a RETURN statement will be used before here. */
1943 __builtin_unreachable ();
1948 ToDecimalPlaces - returns a floating point or base 10 integer
1949 string which is accurate to, n, decimal
1950 places. It will return a new String
1951 and, s, will be destroyed.
1952 Decimal places yields, n, digits after
1957 rounded to the following decimal places yields
1966 extern "C" DynamicStrings_String
StringConvert_ToDecimalPlaces (DynamicStrings_String s
, unsigned int n
)
1970 Assert ((IsDigit (DynamicStrings_char (s
, 0))) || ((DynamicStrings_char (s
, 0)) == '.'), (const char *) "../../gcc/m2/gm2-libs/StringConvert.mod", 39, 1069, (const char *) "ToDecimalPlaces", 15);
1971 point
= DynamicStrings_Index (s
, '.', 0);
1974 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1977 return DynamicStrings_ConCat (DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_InitStringChar ('.'))), DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), n
));
1984 s
= doDecimalPlaces (s
, n
);
1985 /* if the last character is '.' remove it */
1986 if (((DynamicStrings_Length (s
)) > 0) && ((DynamicStrings_char (s
, -1)) == '.'))
1988 return DynamicStrings_Slice (DynamicStrings_Mark (s
), 0, -1);
1994 /* static analysis guarentees a RETURN statement will be used before here. */
1995 __builtin_unreachable ();
1998 extern "C" void _M2_StringConvert_init (__attribute__((unused
)) int argc
, __attribute__((unused
)) char *argv
[], __attribute__((unused
)) char *envp
[])
2002 extern "C" void _M2_StringConvert_fini (__attribute__((unused
)) int argc
, __attribute__((unused
)) char *argv
[], __attribute__((unused
)) char *envp
[])