Daily bump.
[official-gcc.git] / gcc / m2 / mc-boot / GStringConvert.cc
blobe552244fec553831f2c81a90e04042a14e0efd28
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)
12 any later version.
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/>. */
28 #include "config.h"
29 #include "system.h"
30 #include <stdbool.h>
31 # if !defined (PROC_D)
32 # define PROC_D
33 typedef void (*PROC_t) (void);
34 typedef struct { PROC_t proc; } PROC;
35 # endif
37 # if !defined (TRUE)
38 # define TRUE (1==1)
39 # endif
41 # if !defined (FALSE)
42 # define FALSE (1==0)
43 # endif
45 #if defined(__cplusplus)
46 # undef NULL
47 # define NULL 0
48 #endif
49 #define _StringConvert_C
51 #include "GStringConvert.h"
52 # include "GSYSTEM.h"
53 # include "Glibc.h"
54 # include "Glibm.h"
55 # include "GM2RTS.h"
56 # include "GDynamicStrings.h"
57 # include "Gldtoa.h"
58 # include "Gdtoa.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
68 are used.
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
79 are used.
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
88 numeral is found.
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
98 numeral is found.
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
122 numeral is found.
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
145 numeral is found.
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
168 numeral is found.
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.
245 So for example:
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
253 becomes truncated.
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.
285 So: 12.345
287 rounded to the following significant figures yields
289 5 12.345
290 4 12.34
291 3 12.3
292 2 12
293 1 10
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
304 the .
306 So: 12.345
308 rounded to the following decimal places yields
310 5 12.34500
311 4 12.3450
312 3 12.345
313 2 12.34
314 1 12.3
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);
326 Max -
329 static unsigned int Max (unsigned int a, unsigned int b);
332 Min -
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);
407 rtos -
410 static DynamicStrings_String rtos (double r, unsigned int TotalWidth, unsigned int FractionWidth);
413 lrtos -
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);
454 if (! b)
456 M2RTS_ErrorMessage ((const char *) "assert failed", 13, (const char *) file, _file_high, line, (const char *) func, _func_high);
462 Max -
465 static unsigned int Max (unsigned int a, unsigned int b)
467 if (a > b)
469 return a;
471 else
473 return b;
475 /* static analysis guarentees a RETURN statement will be used before here. */
476 __builtin_unreachable ();
481 Min -
484 static unsigned int Min (unsigned int a, unsigned int b)
486 if (a < b)
488 return a;
490 else
492 return 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)
505 if (a < b)
507 return a;
509 else
511 return 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')));
540 return true;
542 else
544 return false;
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);
561 return true;
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);
567 return true;
569 else
571 /* avoid dangling else. */
572 return false;
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')))));
589 return true;
591 else
593 return false;
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)));
610 return true;
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)));
616 return true;
618 else
620 /* avoid dangling else. */
621 return false;
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')))));
638 return true;
640 else
642 return false;
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)));
659 return true;
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)));
665 return true;
667 else
669 /* avoid dangling else. */
670 return false;
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)
683 int i;
685 i = 0;
686 if (power > 0)
688 while (i < power)
690 v = v*10.0;
691 i += 1;
694 else
696 while (i > power)
698 v = v/10.0;
699 i -= 1;
702 return v;
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);
721 LogPower = 0;
722 while ((MaxPowerOfTen*10.0) < ((double) ((INT_MAX) / 10)))
724 MaxPowerOfTen = MaxPowerOfTen*10.0;
725 LogPower += 1;
727 return LogPower;
728 /* static analysis guarentees a RETURN statement will be used before here. */
729 __builtin_unreachable ();
734 rtos -
737 static DynamicStrings_String rtos (double r, unsigned int TotalWidth, unsigned int FractionWidth)
739 M2RTS_HALT (-1);
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 ();
748 lrtos -
751 static DynamicStrings_String lrtos (long double r, unsigned int TotalWidth, unsigned int FractionWidth)
753 M2RTS_HALT (-1);
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)
769 int i;
770 int l;
771 int point;
772 DynamicStrings_String t;
773 DynamicStrings_String tenths;
774 DynamicStrings_String hundreths;
776 l = DynamicStrings_Length (s);
777 i = 0;
778 /* remove '.' */
779 point = DynamicStrings_Index (s, '.', 0);
780 if (point == 0)
782 s = DynamicStrings_Slice (DynamicStrings_Mark (s), 1, 0);
784 else if (point < l)
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)));
789 else
791 /* avoid dangling else. */
792 s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, point);
794 l = DynamicStrings_Length (s);
795 i = 0;
796 if (l > 0)
798 /* skip over leading zeros */
799 while ((i < l) && ((DynamicStrings_char (s, i)) == '0'))
801 i += 1;
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)));
808 return s;
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))
818 n -= 1;
819 i += 1;
821 if ((i+3) <= l)
823 t = DynamicStrings_Dup (s);
824 hundreths = DynamicStrings_Slice (DynamicStrings_Mark (s), i+1, i+3);
825 s = t;
826 if ((StringConvert_stoc (hundreths)) >= 50)
828 s = carryOne (DynamicStrings_Mark (s), static_cast<unsigned int> (i));
830 hundreths = DynamicStrings_KillString (hundreths);
832 else if ((i+2) <= l)
834 /* avoid dangling else. */
835 t = DynamicStrings_Dup (s);
836 tenths = DynamicStrings_Slice (DynamicStrings_Mark (s), i+1, i+2);
837 s = t;
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);
848 l -= 1;
849 point -= 1;
851 if (i < l)
853 s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, i);
854 l = DynamicStrings_Length (s);
855 if (l < point)
857 s = DynamicStrings_ConCat (s, DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), static_cast<unsigned int> (point-l)));
860 /* re-insert the point */
861 if (point >= 0)
863 /* avoid gcc warning by using compound statement even if not strictly necessary. */
864 if (point == 0)
866 s = DynamicStrings_ConCat (DynamicStrings_InitStringChar ('.'), DynamicStrings_Mark (s));
868 else
870 s = DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s), 0, point), '.'), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), point, 0)));
873 return s;
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)
887 int i;
888 int l;
889 int z;
890 int point;
891 DynamicStrings_String t;
892 DynamicStrings_String tenths;
893 DynamicStrings_String hundreths;
895 l = DynamicStrings_Length (s);
896 i = 0;
897 /* remove '.' */
898 point = DynamicStrings_Index (s, '.', 0);
899 if (point >= 0)
901 if (point == 0)
903 s = DynamicStrings_Slice (DynamicStrings_Mark (s), 1, 0);
905 else if (point < l)
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)));
910 else
912 /* avoid dangling else. */
913 s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, point);
916 else
918 s = DynamicStrings_Dup (DynamicStrings_Mark (s));
920 l = DynamicStrings_Length (s);
921 i = 0;
922 if (l > 0)
924 /* skip over leading zeros */
925 while ((i < l) && ((DynamicStrings_char (s, i)) == '0'))
927 i += 1;
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));
934 i = 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));
943 else
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))
951 n -= 1;
952 i += 1;
954 if ((i+3) <= l)
956 t = DynamicStrings_Dup (s);
957 hundreths = DynamicStrings_Slice (DynamicStrings_Mark (s), i+1, i+3);
958 s = t;
959 if ((StringConvert_stoc (hundreths)) >= 50)
961 s = carryOne (DynamicStrings_Mark (s), static_cast<unsigned int> (i));
963 hundreths = DynamicStrings_KillString (hundreths);
965 else if ((i+2) <= l)
967 /* avoid dangling else. */
968 t = DynamicStrings_Dup (s);
969 tenths = DynamicStrings_Slice (DynamicStrings_Mark (s), i+1, i+2);
970 s = t;
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')
980 if (z == 0)
982 s = DynamicStrings_Slice (DynamicStrings_Mark (s), z+1, 0);
984 else
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);
990 else
992 point += 1;
994 if (i < l)
996 s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, i);
997 l = DynamicStrings_Length (s);
998 if (l < point)
1000 s = DynamicStrings_ConCat (s, DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), static_cast<unsigned int> (point-l)));
1003 /* re-insert the point */
1004 if (point >= 0)
1006 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1007 if (point == 0)
1009 s = DynamicStrings_ConCat (DynamicStrings_InitStringChar ('.'), DynamicStrings_Mark (s));
1011 else
1013 s = DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s), 0, point), '.'), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), point, 0)));
1016 return s;
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)
1028 if (i >= 0)
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')
1035 if (i == 0)
1037 s = DynamicStrings_ConCat (DynamicStrings_InitStringChar ('1'), DynamicStrings_Mark (s));
1038 return s;
1040 else
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);
1046 else
1048 if (i == 0)
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)));
1052 else
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)));
1059 return s;
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
1072 are used.
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;
1078 unsigned int c;
1080 if (i < 0)
1082 if (i == (INT_MIN))
1084 /* remember that -15 MOD 4 = 1 in Modula-2 */
1085 c = ((unsigned int ) (abs (i+1)))+1;
1086 if (width > 0)
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)));
1090 else
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)));
1095 else
1097 s = DynamicStrings_InitString ((const char *) "-", 1);
1099 i = -i;
1101 else
1103 if (sign)
1105 s = DynamicStrings_InitString ((const char *) "+", 1);
1107 else
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)));
1116 else
1118 if (i <= 9)
1120 s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (i))+ ((unsigned int) ('0')))))));
1122 else
1124 if (lower)
1126 s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (i))+ ((unsigned int) ('a')))-10)))));
1128 else
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));
1138 return 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
1150 are used.
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);
1158 if (c > (base-1))
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)));
1162 else
1164 if (c <= 9)
1166 s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) (c+ ((unsigned int) ('0')))))));
1168 else
1170 if (lower)
1172 s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((c+ ((unsigned int) ('a')))-10)))));
1174 else
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);
1184 return 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
1194 numeral is found.
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)
1200 unsigned int n;
1201 unsigned int l;
1202 unsigned int c;
1203 bool negative;
1205 s = DynamicStrings_RemoveWhitePrefix (s); /* returns a new string, s */
1206 l = DynamicStrings_Length (s); /* returns a new string, s */
1207 c = 0;
1208 n = 0;
1209 negative = false;
1210 if (n < l)
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;
1219 n += 1;
1221 while ((n < l) && ((IsDecimalDigitValid (DynamicStrings_char (s, static_cast<int> (n)), base, &c)) || (IsHexidecimalDigitValid (DynamicStrings_char (s, static_cast<int> (n)), base, &c))))
1223 (*found) = true;
1224 n += 1;
1227 s = DynamicStrings_KillString (s);
1228 if (negative)
1230 return -((int ) (Min (((unsigned int ) (INT_MAX))+1, c)));
1232 else
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
1245 numeral is found.
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)
1251 unsigned int n;
1252 unsigned int l;
1253 unsigned int c;
1255 s = DynamicStrings_RemoveWhitePrefix (s); /* returns a new string, s */
1256 l = DynamicStrings_Length (s); /* returns a new string, s */
1257 c = 0;
1258 n = 0;
1259 if (n < l)
1261 /* parse leading + */
1262 while ((DynamicStrings_char (s, static_cast<int> (n))) == '+')
1264 n += 1;
1266 while ((n < l) && ((IsDecimalDigitValid (DynamicStrings_char (s, static_cast<int> (n)), base, &c)) || (IsHexidecimalDigitValid (DynamicStrings_char (s, static_cast<int> (n)), base, &c))))
1268 (*found) = true;
1269 n += 1;
1272 s = DynamicStrings_KillString (s);
1273 return c;
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;
1296 if (i < 0)
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;
1303 if (width > 0)
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)));
1307 else
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)));
1312 else
1314 s = DynamicStrings_InitString ((const char *) "-", 1);
1316 i = -i;
1318 else
1320 if (sign)
1322 s = DynamicStrings_InitString ((const char *) "+", 1);
1324 else
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)));
1333 else
1335 if (i <= 9)
1337 s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (i))+ ((unsigned int) ('0')))))));
1339 else
1341 if (lower)
1343 s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (i))+ ((unsigned int) ('a')))-10)))));
1345 else
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);
1355 return 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
1365 numeral is found.
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)
1371 unsigned int n;
1372 unsigned int l;
1373 long unsigned int c;
1374 bool negative;
1376 s = DynamicStrings_RemoveWhitePrefix (s); /* returns a new string, s */
1377 l = DynamicStrings_Length (s); /* returns a new string, s */
1378 c = 0;
1379 n = 0;
1380 negative = false;
1381 if (n < l)
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;
1390 n += 1;
1392 while ((n < l) && ((IsDecimalDigitValidLong (DynamicStrings_char (s, static_cast<int> (n)), base, &c)) || (IsHexidecimalDigitValidLong (DynamicStrings_char (s, static_cast<int> (n)), base, &c))))
1394 (*found) = true;
1395 n += 1;
1398 s = DynamicStrings_KillString (s);
1399 if (negative)
1401 return -((long int ) (LongMin (((long unsigned int ) (LONG_MAX))+1, c)));
1403 else
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));
1432 else
1434 if (c <= 9)
1436 s = DynamicStrings_ConCat (s, DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (c))+ ((unsigned int) ('0'))))));
1438 else
1440 if (lower)
1442 s = DynamicStrings_ConCat (s, DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (c))+ ((unsigned int) ('a')))-10))));
1444 else
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);
1454 return 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
1464 numeral is found.
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)
1470 unsigned int n;
1471 unsigned int l;
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 */
1476 c = 0;
1477 n = 0;
1478 if (n < l)
1480 /* parse leading + */
1481 while ((DynamicStrings_char (s, static_cast<int> (n))) == '+')
1483 n += 1;
1485 while ((n < l) && ((IsDecimalDigitValidLong (DynamicStrings_char (s, static_cast<int> (n)), base, &c)) || (IsHexidecimalDigitValidLong (DynamicStrings_char (s, static_cast<int> (n)), base, &c))))
1487 (*found) = true;
1488 n += 1;
1491 s = DynamicStrings_KillString (s);
1492 return c;
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));
1518 else
1520 if (c <= 9)
1522 s = DynamicStrings_ConCat (s, DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (c))+ ((unsigned int) ('0'))))));
1524 else
1526 if (lower)
1528 s = DynamicStrings_ConCat (s, DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (c))+ ((unsigned int) ('a')))-10))));
1530 else
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);
1540 return 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
1550 numeral is found.
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)
1556 unsigned int n;
1557 unsigned int l;
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 */
1562 c = 0;
1563 n = 0;
1564 if (n < l)
1566 /* parse leading + */
1567 while ((DynamicStrings_char (s, static_cast<int> (n))) == '+')
1569 n += 1;
1571 while ((n < l) && ((IsDecimalDigitValidShort (DynamicStrings_char (s, static_cast<int> (n)), base, &c)) || (IsHexidecimalDigitValidShort (DynamicStrings_char (s, static_cast<int> (n)), base, &c))))
1573 (*found) = true;
1574 n += 1;
1577 s = DynamicStrings_KillString (s);
1578 return c;
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)
1590 bool found;
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)
1628 bool found;
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)
1642 bool found;
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)
1656 bool found;
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)
1670 bool found;
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)
1684 bool found;
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)
1698 bool found;
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)
1712 bool found;
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)
1726 bool error;
1727 long double value;
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);
1732 (*found) = ! error;
1733 return value;
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.
1744 So for example:
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
1752 becomes truncated.
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)
1765 bool maxprecision;
1766 DynamicStrings_String s;
1767 void * r;
1768 int point;
1769 bool sign;
1770 int l;
1772 if (TotalWidth == 0)
1774 maxprecision = true;
1775 r = ldtoa_ldtoa (x, static_cast<int> (ldtoa_decimaldigits), 100, &point, &sign);
1777 else
1779 r = ldtoa_ldtoa (x, static_cast<int> (ldtoa_decimaldigits), 100, &point, &sign);
1781 s = DynamicStrings_InitStringCharStar (r);
1782 libc_free (r);
1783 l = DynamicStrings_Length (s);
1784 if (point > l)
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))
1791 FractionWidth -= 1;
1792 if (((int ) (FractionWidth)) > (point-l))
1794 s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "0", 1)), FractionWidth)));
1798 else if (point < 0)
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))));
1809 else
1811 /* avoid dangling else. */
1812 if (point == 0)
1814 s = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "0.", 2), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), point, 0)));
1816 else
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. */
1828 if (TotalWidth > 0)
1830 if (sign)
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));
1834 sign = false;
1836 else
1838 /* minus 1 because all results will include a '.' */
1839 s = DynamicStrings_Slice (DynamicStrings_Mark (StringConvert_ToDecimalPlaces (s, FractionWidth)), 0, static_cast<int> (TotalWidth));
1842 else
1844 if (sign)
1846 s = StringConvert_ToDecimalPlaces (s, FractionWidth);
1847 s = DynamicStrings_ConCat (DynamicStrings_InitStringChar ('-'), DynamicStrings_Mark (s));
1848 sign = false;
1850 else
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));
1861 return 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)
1873 bool found;
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)
1887 bool found;
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.
1902 So: 12.345
1904 rounded to the following significant figures yields
1906 5 12.345
1907 4 12.34
1908 3 12.3
1909 2 12
1910 1 10
1913 extern "C" DynamicStrings_String StringConvert_ToSigFig (DynamicStrings_String s, unsigned int n)
1915 int point;
1916 unsigned int poTen;
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);
1920 if (point < 0)
1922 poTen = DynamicStrings_Length (s);
1924 else
1926 poTen = point;
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);
1934 else
1936 if (poTen > (DynamicStrings_Length (s)))
1938 s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), poTen-(DynamicStrings_Length (s)))));
1940 return 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
1953 the .
1955 So: 12.345
1957 rounded to the following decimal places yields
1959 5 12.34500
1960 4 12.3450
1961 3 12.345
1962 2 12.34
1963 1 12.3
1966 extern "C" DynamicStrings_String StringConvert_ToDecimalPlaces (DynamicStrings_String s, unsigned int n)
1968 int point;
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);
1972 if (point < 0)
1974 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1975 if (n > 0)
1977 return DynamicStrings_ConCat (DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ('.'))), DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), n));
1979 else
1981 return s;
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);
1990 else
1992 return s;
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[])