diff options
Diffstat (limited to 'gcc/m2/mc-boot/GStringConvert.c')
-rw-r--r-- | gcc/m2/mc-boot/GStringConvert.c | 2005 |
1 files changed, 2005 insertions, 0 deletions
diff --git a/gcc/m2/mc-boot/GStringConvert.c b/gcc/m2/mc-boot/GStringConvert.c new file mode 100644 index 0000000..75ad8fd --- /dev/null +++ b/gcc/m2/mc-boot/GStringConvert.c @@ -0,0 +1,2005 @@ +/* do not edit automatically generated by mc from StringConvert. */ +/* StringConvert.mod provides functions to convert numbers to and from strings. + +Copyright (C) 2001-2021 Free Software Foundation, Inc. +Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>. + +This file is part of GNU Modula-2. + +GNU Modula-2 is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GNU Modula-2 is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +# if !defined (PROC_D) +# define PROC_D + typedef void (*PROC_t) (void); + typedef struct { PROC_t proc; } PROC; +# endif + +# if !defined (TRUE) +# define TRUE (1==1) +# endif + +# if !defined (FALSE) +# define FALSE (1==0) +# endif + +#if defined(__cplusplus) +# undef NULL +# define NULL 0 +#endif +#define _StringConvert_H +#define _StringConvert_C + +# include "GSYSTEM.h" +# include "Glibc.h" +# include "Glibm.h" +# include "GM2RTS.h" +# include "GDynamicStrings.h" +# include "Gldtoa.h" +# include "Gdtoa.h" + + +/* + IntegerToString - converts INTEGER, i, into a String. The field with can be specified + if non zero. Leading characters are defined by padding and this + function will prepend a + if sign is set to TRUE. + The base allows the caller to generate binary, octal, decimal, hexidecimal + numbers. The value of lower is only used when hexidecimal numbers are + generated and if TRUE then digits abcdef are used, and if FALSE then ABCDEF + are used. +*/ + +extern "C" DynamicStrings_String StringConvert_IntegerToString (int i, unsigned int width, char padding, unsigned int sign, unsigned int base, unsigned int lower); + +/* + CardinalToString - converts CARDINAL, c, into a String. The field with can be specified + if non zero. Leading characters are defined by padding. + The base allows the caller to generate binary, octal, decimal, hexidecimal + numbers. The value of lower is only used when hexidecimal numbers are + generated and if TRUE then digits abcdef are used, and if FALSE then ABCDEF + are used. +*/ + +extern "C" DynamicStrings_String StringConvert_CardinalToString (unsigned int c, unsigned int width, char padding, unsigned int base, unsigned int lower); + +/* + StringToInteger - converts a string, s, of, base, into an INTEGER. + Leading white space is ignored. It stops converting + when either the string is exhausted or if an illegal + numeral is found. + The parameter found is set TRUE if a number was found. +*/ + +extern "C" int StringConvert_StringToInteger (DynamicStrings_String s, unsigned int base, unsigned int *found); + +/* + StringToCardinal - converts a string, s, of, base, into a CARDINAL. + Leading white space is ignored. It stops converting + when either the string is exhausted or if an illegal + numeral is found. + The parameter found is set TRUE if a number was found. +*/ + +extern "C" unsigned int StringConvert_StringToCardinal (DynamicStrings_String s, unsigned int base, unsigned int *found); + +/* + LongIntegerToString - converts LONGINT, i, into a String. The field with + can be specified if non zero. Leading characters + are defined by padding and this function will + prepend a + if sign is set to TRUE. + The base allows the caller to generate binary, + octal, decimal, hexidecimal numbers. + The value of lower is only used when hexidecimal + numbers are generated and if TRUE then digits + abcdef are used, and if FALSE then ABCDEF are used. +*/ + +extern "C" DynamicStrings_String StringConvert_LongIntegerToString (long int i, unsigned int width, char padding, unsigned int sign, unsigned int base, unsigned int lower); + +/* + StringToLongInteger - converts a string, s, of, base, into an LONGINT. + Leading white space is ignored. It stops converting + when either the string is exhausted or if an illegal + numeral is found. + The parameter found is set TRUE if a number was found. +*/ + +extern "C" long int StringConvert_StringToLongInteger (DynamicStrings_String s, unsigned int base, unsigned int *found); + +/* + LongCardinalToString - converts LONGCARD, c, into a String. The field + width can be specified if non zero. Leading + characters are defined by padding. + The base allows the caller to generate binary, + octal, decimal, hexidecimal numbers. + The value of lower is only used when hexidecimal + numbers are generated and if TRUE then digits + abcdef are used, and if FALSE then ABCDEF are used. +*/ + +extern "C" DynamicStrings_String StringConvert_LongCardinalToString (long unsigned int c, unsigned int width, char padding, unsigned int base, unsigned int lower); + +/* + StringToLongCardinal - converts a string, s, of, base, into a LONGCARD. + Leading white space is ignored. It stops converting + when either the string is exhausted or if an illegal + numeral is found. + The parameter found is set TRUE if a number was found. +*/ + +extern "C" long unsigned int StringConvert_StringToLongCardinal (DynamicStrings_String s, unsigned int base, unsigned int *found); + +/* + ShortCardinalToString - converts SHORTCARD, c, into a String. The field + width can be specified if non zero. Leading + characters are defined by padding. + The base allows the caller to generate binary, + octal, decimal, hexidecimal numbers. + The value of lower is only used when hexidecimal + numbers are generated and if TRUE then digits + abcdef are used, and if FALSE then ABCDEF are used. +*/ + +extern "C" DynamicStrings_String StringConvert_ShortCardinalToString (short unsigned int c, unsigned int width, char padding, unsigned int base, unsigned int lower); + +/* + StringToShortCardinal - converts a string, s, of, base, into a SHORTCARD. + Leading white space is ignored. It stops converting + when either the string is exhausted or if an illegal + numeral is found. + The parameter found is set TRUE if a number was found. +*/ + +extern "C" short unsigned int StringConvert_StringToShortCardinal (DynamicStrings_String s, unsigned int base, unsigned int *found); + +/* + stoi - decimal string to INTEGER +*/ + +extern "C" int StringConvert_stoi (DynamicStrings_String s); + +/* + itos - integer to decimal string. +*/ + +extern "C" DynamicStrings_String StringConvert_itos (int i, unsigned int width, char padding, unsigned int sign); + +/* + ctos - cardinal to decimal string. +*/ + +extern "C" DynamicStrings_String StringConvert_ctos (unsigned int c, unsigned int width, char padding); + +/* + stoc - decimal string to CARDINAL +*/ + +extern "C" unsigned int StringConvert_stoc (DynamicStrings_String s); + +/* + hstoi - hexidecimal string to INTEGER +*/ + +extern "C" int StringConvert_hstoi (DynamicStrings_String s); + +/* + ostoi - octal string to INTEGER +*/ + +extern "C" int StringConvert_ostoi (DynamicStrings_String s); + +/* + bstoi - binary string to INTEGER +*/ + +extern "C" int StringConvert_bstoi (DynamicStrings_String s); + +/* + hstoc - hexidecimal string to CARDINAL +*/ + +extern "C" unsigned int StringConvert_hstoc (DynamicStrings_String s); + +/* + ostoc - octal string to CARDINAL +*/ + +extern "C" unsigned int StringConvert_ostoc (DynamicStrings_String s); + +/* + bstoc - binary string to CARDINAL +*/ + +extern "C" unsigned int StringConvert_bstoc (DynamicStrings_String s); + +/* + StringToLongreal - returns a LONGREAL and sets found to TRUE if a legal number is seen. +*/ + +extern "C" long double StringConvert_StringToLongreal (DynamicStrings_String s, unsigned int *found); + +/* + LongrealToString - converts a LONGREAL number, Real, which has, + TotalWidth, and FractionWidth into a string. + It uses decimal notation. + + So for example: + + LongrealToString(1.0, 4, 2) -> '1.00' + LongrealToString(12.3, 5, 2) -> '12.30' + LongrealToString(12.3, 6, 2) -> ' 12.30' + LongrealToString(12.3, 6, 3) -> '12.300' + + if total width is too small then the fraction + becomes truncated. + + LongrealToString(12.3, 5, 3) -> '12.30' + + Positive numbers do not have a '+' prepended. + Negative numbers will have a '-' prepended and + the TotalWidth will need to be large enough + to contain the sign, whole number, '.' and + fractional components. +*/ + +extern "C" DynamicStrings_String StringConvert_LongrealToString (long double x, unsigned int TotalWidth, unsigned int FractionWidth); + +/* + stor - returns a REAL given a string. +*/ + +extern "C" double StringConvert_stor (DynamicStrings_String s); + +/* + stolr - returns a LONGREAL given a string. +*/ + +extern "C" long double StringConvert_stolr (DynamicStrings_String s); + +/* + ToSigFig - returns a floating point or base 10 integer + string which is accurate to, n, significant + figures. It will return a new String + and, s, will be destroyed. + + + So: 12.345 + + rounded to the following significant figures yields + + 5 12.345 + 4 12.34 + 3 12.3 + 2 12 + 1 10 +*/ + +extern "C" DynamicStrings_String StringConvert_ToSigFig (DynamicStrings_String s, unsigned int n); + +/* + ToDecimalPlaces - returns a floating point or base 10 integer + string which is accurate to, n, decimal + places. It will return a new String + and, s, will be destroyed. + Decimal places yields, n, digits after + the . + + So: 12.345 + + rounded to the following decimal places yields + + 5 12.34500 + 4 12.3450 + 3 12.345 + 2 12.34 + 1 12.3 +*/ + +extern "C" DynamicStrings_String StringConvert_ToDecimalPlaces (DynamicStrings_String s, unsigned int n); + +/* + Assert - implement a simple assert. +*/ + +static void Assert (unsigned int b, const char *file_, unsigned int _file_high, unsigned int line, const char *func_, unsigned int _func_high); + +/* + Max - +*/ + +static unsigned int Max (unsigned int a, unsigned int b); + +/* + Min - +*/ + +static unsigned int Min (unsigned int a, unsigned int b); + +/* + LongMin - returns the smallest LONGCARD +*/ + +static long unsigned int LongMin (long unsigned int a, long unsigned int b); + +/* + IsDigit - returns TRUE if, ch, lies between '0'..'9'. +*/ + +static unsigned int IsDigit (char ch); + +/* + IsDecimalDigitValid - returns the TRUE if, ch, is a base legal decimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsDecimalDigitValid (char ch, unsigned int base, unsigned int *c); + +/* + IsHexidecimalDigitValid - returns the TRUE if, ch, is a base legal hexidecimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsHexidecimalDigitValid (char ch, unsigned int base, unsigned int *c); + +/* + IsDecimalDigitValidLong - returns the TRUE if, ch, is a base legal decimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsDecimalDigitValidLong (char ch, unsigned int base, long unsigned int *c); + +/* + IsHexidecimalDigitValidLong - returns the TRUE if, ch, is a base legal hexidecimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsHexidecimalDigitValidLong (char ch, unsigned int base, long unsigned int *c); + +/* + IsDecimalDigitValidShort - returns the TRUE if, ch, is a base legal decimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsDecimalDigitValidShort (char ch, unsigned int base, short unsigned int *c); + +/* + IsHexidecimalDigitValidShort - returns the TRUE if, ch, is a base legal hexidecimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsHexidecimalDigitValidShort (char ch, unsigned int base, short unsigned int *c); + +/* + ToThePower10 - returns a LONGREAL containing the value of v * 10^power. +*/ + +static long double ToThePower10 (long double v, int power); + +/* + DetermineSafeTruncation - we wish to use TRUNC when converting REAL/LONGREAL + into a string for the non fractional component. + However we need a simple method to + determine the maximum safe truncation value. +*/ + +static unsigned int DetermineSafeTruncation (void); + +/* + rtos - +*/ + +static DynamicStrings_String rtos (double r, unsigned int TotalWidth, unsigned int FractionWidth); + +/* + lrtos - +*/ + +static DynamicStrings_String lrtos (long double r, unsigned int TotalWidth, unsigned int FractionWidth); + +/* + doDecimalPlaces - returns a string which is accurate to + n decimal places. It returns a new String + and, s, will be destroyed. +*/ + +static DynamicStrings_String doDecimalPlaces (DynamicStrings_String s, unsigned int n); + +/* + doSigFig - returns a string which is accurate to + n decimal places. It returns a new String + and, s, will be destroyed. +*/ + +static DynamicStrings_String doSigFig (DynamicStrings_String s, unsigned int n); + +/* + carryOne - add a carry at position, i. +*/ + +static DynamicStrings_String carryOne (DynamicStrings_String s, unsigned int i); + + +/* + Assert - implement a simple assert. +*/ + +static void Assert (unsigned int b, const char *file_, unsigned int _file_high, unsigned int line, const char *func_, unsigned int _func_high) +{ + char file[_file_high+1]; + char func[_func_high+1]; + + /* make a local copy of each unbounded array. */ + memcpy (file, file_, _file_high+1); + memcpy (func, func_, _func_high+1); + + if (! b) + { + M2RTS_ErrorMessage ((const char *) "assert failed", 13, (const char *) file, _file_high, line, (const char *) func, _func_high); + } +} + + +/* + Max - +*/ + +static unsigned int Max (unsigned int a, unsigned int b) +{ + if (a > b) + { + return a; + } + else + { + return b; + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + Min - +*/ + +static unsigned int Min (unsigned int a, unsigned int b) +{ + if (a < b) + { + return a; + } + else + { + return b; + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + LongMin - returns the smallest LONGCARD +*/ + +static long unsigned int LongMin (long unsigned int a, long unsigned int b) +{ + if (a < b) + { + return a; + } + else + { + return b; + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + IsDigit - returns TRUE if, ch, lies between '0'..'9'. +*/ + +static unsigned int IsDigit (char ch) +{ + return (ch >= '0') && (ch <= '9'); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + IsDecimalDigitValid - returns the TRUE if, ch, is a base legal decimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsDecimalDigitValid (char ch, unsigned int base, unsigned int *c) +{ + if ((IsDigit (ch)) && (( ((unsigned int) (ch))- ((unsigned int) ('0'))) < base)) + { + (*c) = ((*c)*base)+( ((unsigned int) (ch))- ((unsigned int) ('0'))); + return TRUE; + } + else + { + return FALSE; + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + IsHexidecimalDigitValid - returns the TRUE if, ch, is a base legal hexidecimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsHexidecimalDigitValid (char ch, unsigned int base, unsigned int *c) +{ + if (((ch >= 'a') && (ch <= 'f')) && ((( ((unsigned int) (ch))- ((unsigned int) ('a')))+10) < base)) + { + (*c) = ((*c)*base)+(( ((unsigned int) (ch))- ((unsigned int) ('a')))+10); + return TRUE; + } + else if (((ch >= 'A') && (ch <= 'F')) && ((( ((unsigned int) (ch))- ((unsigned int) ('F')))+10) < base)) + { + /* avoid dangling else. */ + (*c) = ((*c)*base)+(( ((unsigned int) (ch))- ((unsigned int) ('A')))+10); + return TRUE; + } + else + { + /* avoid dangling else. */ + return FALSE; + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + IsDecimalDigitValidLong - returns the TRUE if, ch, is a base legal decimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsDecimalDigitValidLong (char ch, unsigned int base, long unsigned int *c) +{ + if ((IsDigit (ch)) && (( ((unsigned int) (ch))- ((unsigned int) ('0'))) < base)) + { + (*c) = (*c)*((long unsigned int ) (base+( ((unsigned int) (ch))- ((unsigned int) ('0'))))); + return TRUE; + } + else + { + return FALSE; + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + IsHexidecimalDigitValidLong - returns the TRUE if, ch, is a base legal hexidecimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsHexidecimalDigitValidLong (char ch, unsigned int base, long unsigned int *c) +{ + if (((ch >= 'a') && (ch <= 'f')) && ((( ((unsigned int) (ch))- ((unsigned int) ('a')))+10) < base)) + { + (*c) = (*c)*((long unsigned int ) (base+(( ((unsigned int) (ch))- ((unsigned int) ('a')))+10))); + return TRUE; + } + else if (((ch >= 'A') && (ch <= 'F')) && ((( ((unsigned int) (ch))- ((unsigned int) ('F')))+10) < base)) + { + /* avoid dangling else. */ + (*c) = (*c)*((long unsigned int ) (base+(( ((unsigned int) (ch))- ((unsigned int) ('A')))+10))); + return TRUE; + } + else + { + /* avoid dangling else. */ + return FALSE; + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + IsDecimalDigitValidShort - returns the TRUE if, ch, is a base legal decimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsDecimalDigitValidShort (char ch, unsigned int base, short unsigned int *c) +{ + if ((IsDigit (ch)) && (( ((unsigned int) (ch))- ((unsigned int) ('0'))) < base)) + { + (*c) = (*c)*((short unsigned int ) (base+( ((unsigned int) (ch))- ((unsigned int) ('0'))))); + return TRUE; + } + else + { + return FALSE; + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + IsHexidecimalDigitValidShort - returns the TRUE if, ch, is a base legal hexidecimal digit. + If legal then the value is appended numerically onto, c. +*/ + +static unsigned int IsHexidecimalDigitValidShort (char ch, unsigned int base, short unsigned int *c) +{ + if (((ch >= 'a') && (ch <= 'f')) && ((( ((unsigned int) (ch))- ((unsigned int) ('a')))+10) < base)) + { + (*c) = (*c)*((short unsigned int ) (base+(( ((unsigned int) (ch))- ((unsigned int) ('a')))+10))); + return TRUE; + } + else if (((ch >= 'A') && (ch <= 'F')) && ((( ((unsigned int) (ch))- ((unsigned int) ('F')))+10) < base)) + { + /* avoid dangling else. */ + (*c) = (*c)*((short unsigned int ) (base+(( ((unsigned int) (ch))- ((unsigned int) ('A')))+10))); + return TRUE; + } + else + { + /* avoid dangling else. */ + return FALSE; + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + ToThePower10 - returns a LONGREAL containing the value of v * 10^power. +*/ + +static long double ToThePower10 (long double v, int power) +{ + int i; + + i = 0; + if (power > 0) + { + while (i < power) + { + v = v*10.0; + i += 1; + } + } + else + { + while (i > power) + { + v = v/10.0; + i -= 1; + } + } + return v; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + DetermineSafeTruncation - we wish to use TRUNC when converting REAL/LONGREAL + into a string for the non fractional component. + However we need a simple method to + determine the maximum safe truncation value. +*/ + +static unsigned int DetermineSafeTruncation (void) +{ + double MaxPowerOfTen; + unsigned int LogPower; + + MaxPowerOfTen = static_cast<double> (1.0); + LogPower = 0; + while ((MaxPowerOfTen*10.0) < ((double) ((INT_MAX) / 10))) + { + MaxPowerOfTen = MaxPowerOfTen*10.0; + LogPower += 1; + } + return LogPower; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + rtos - +*/ + +static DynamicStrings_String rtos (double r, unsigned int TotalWidth, unsigned int FractionWidth) +{ + M2RTS_HALT (-1); + __builtin_unreachable (); + return static_cast<DynamicStrings_String> (NULL); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + lrtos - +*/ + +static DynamicStrings_String lrtos (long double r, unsigned int TotalWidth, unsigned int FractionWidth) +{ + M2RTS_HALT (-1); + __builtin_unreachable (); + return static_cast<DynamicStrings_String> (NULL); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + doDecimalPlaces - returns a string which is accurate to + n decimal places. It returns a new String + and, s, will be destroyed. +*/ + +static DynamicStrings_String doDecimalPlaces (DynamicStrings_String s, unsigned int n) +{ + int i; + int l; + int point; + DynamicStrings_String t; + DynamicStrings_String whole; + DynamicStrings_String fraction; + DynamicStrings_String tenths; + DynamicStrings_String hundreths; + + l = DynamicStrings_Length (s); + i = 0; + /* remove '.' */ + point = DynamicStrings_Index (s, '.', 0); + if (point == 0) + { + s = DynamicStrings_Slice (DynamicStrings_Mark (s), 1, 0); + } + else if (point < l) + { + /* avoid dangling else. */ + s = DynamicStrings_ConCat (DynamicStrings_Slice (DynamicStrings_Mark (s), 0, point), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), point+1, 0))); + } + else + { + /* avoid dangling else. */ + s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, point); + } + l = DynamicStrings_Length (s); + i = 0; + if (l > 0) + { + /* skip over leading zeros */ + while ((i < l) && ((DynamicStrings_char (s, i)) == '0')) + { + i += 1; + } + /* was the string full of zeros? */ + if ((i == l) && ((DynamicStrings_char (s, i-1)) == '0')) + { + s = DynamicStrings_KillString (s); + s = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "0.", 2), DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), n))); + return s; + } + } + /* insert leading zero */ + s = DynamicStrings_ConCat (DynamicStrings_InitStringChar ('0'), DynamicStrings_Mark (s)); + point += 1; /* and move point position to correct place */ + l = DynamicStrings_Length (s); /* update new length */ + i = point; /* update new length */ + while ((n > 1) && (i < l)) + { + n -= 1; + i += 1; + } + if ((i+3) <= l) + { + t = DynamicStrings_Dup (s); + hundreths = DynamicStrings_Slice (DynamicStrings_Mark (s), i+1, i+3); + s = t; + if ((StringConvert_stoc (hundreths)) >= 50) + { + s = carryOne (DynamicStrings_Mark (s), static_cast<unsigned int> (i)); + } + hundreths = DynamicStrings_KillString (hundreths); + } + else if ((i+2) <= l) + { + /* avoid dangling else. */ + t = DynamicStrings_Dup (s); + tenths = DynamicStrings_Slice (DynamicStrings_Mark (s), i+1, i+2); + s = t; + if ((StringConvert_stoc (tenths)) >= 5) + { + s = carryOne (DynamicStrings_Mark (s), static_cast<unsigned int> (i)); + } + tenths = DynamicStrings_KillString (tenths); + } + /* check whether we need to remove the leading zero */ + if ((DynamicStrings_char (s, 0)) == '0') + { + s = DynamicStrings_Slice (DynamicStrings_Mark (s), 1, 0); + l -= 1; + point -= 1; + } + if (i < l) + { + s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, i); + l = DynamicStrings_Length (s); + if (l < point) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), static_cast<unsigned int> (point-l))); + } + } + /* re-insert the point */ + if (point >= 0) + { + /* avoid gcc warning by using compound statement even if not strictly necessary. */ + if (point == 0) + { + s = DynamicStrings_ConCat (DynamicStrings_InitStringChar ('.'), DynamicStrings_Mark (s)); + } + else + { + s = DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s), 0, point), '.'), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), point, 0))); + } + } + return s; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + doSigFig - returns a string which is accurate to + n decimal places. It returns a new String + and, s, will be destroyed. +*/ + +static DynamicStrings_String doSigFig (DynamicStrings_String s, unsigned int n) +{ + int i; + int l; + int z; + int point; + DynamicStrings_String t; + DynamicStrings_String tenths; + DynamicStrings_String hundreths; + + l = DynamicStrings_Length (s); + i = 0; + /* remove '.' */ + point = DynamicStrings_Index (s, '.', 0); + if (point >= 0) + { + if (point == 0) + { + s = DynamicStrings_Slice (DynamicStrings_Mark (s), 1, 0); + } + else if (point < l) + { + /* avoid dangling else. */ + s = DynamicStrings_ConCat (DynamicStrings_Slice (DynamicStrings_Mark (s), 0, point), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), point+1, 0))); + } + else + { + /* avoid dangling else. */ + s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, point); + } + } + else + { + s = DynamicStrings_Dup (DynamicStrings_Mark (s)); + } + l = DynamicStrings_Length (s); + i = 0; + if (l > 0) + { + /* skip over leading zeros */ + while ((i < l) && ((DynamicStrings_char (s, i)) == '0')) + { + i += 1; + } + /* was the string full of zeros? */ + if ((i == l) && ((DynamicStrings_char (s, i-1)) == '0')) + { + /* truncate string */ + s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, static_cast<int> (n)); + i = n; + } + } + /* add a leading zero in case we need to overflow the carry */ + z = i; /* remember where we inserted zero */ + if (z == 0) /* remember where we inserted zero */ + { + s = DynamicStrings_ConCat (DynamicStrings_InitStringChar ('0'), DynamicStrings_Mark (s)); + } + else + { + s = DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s), 0, i), '0'), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), i, 0))); + } + n += 1; /* and increase the number of sig figs needed */ + l = DynamicStrings_Length (s); /* and increase the number of sig figs needed */ + while ((n > 1) && (i < l)) + { + n -= 1; + i += 1; + } + if ((i+3) <= l) + { + t = DynamicStrings_Dup (s); + hundreths = DynamicStrings_Slice (DynamicStrings_Mark (s), i+1, i+3); + s = t; + if ((StringConvert_stoc (hundreths)) >= 50) + { + s = carryOne (DynamicStrings_Mark (s), static_cast<unsigned int> (i)); + } + hundreths = DynamicStrings_KillString (hundreths); + } + else if ((i+2) <= l) + { + /* avoid dangling else. */ + t = DynamicStrings_Dup (s); + tenths = DynamicStrings_Slice (DynamicStrings_Mark (s), i+1, i+2); + s = t; + if ((StringConvert_stoc (tenths)) >= 5) + { + s = carryOne (DynamicStrings_Mark (s), static_cast<unsigned int> (i)); + } + tenths = DynamicStrings_KillString (tenths); + } + /* check whether we need to remove the leading zero */ + if ((DynamicStrings_char (s, z)) == '0') + { + if (z == 0) + { + s = DynamicStrings_Slice (DynamicStrings_Mark (s), z+1, 0); + } + else + { + s = DynamicStrings_ConCat (DynamicStrings_Slice (DynamicStrings_Mark (s), 0, z), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), z+1, 0))); + } + l = DynamicStrings_Length (s); + } + else + { + point += 1; + } + if (i < l) + { + s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, i); + l = DynamicStrings_Length (s); + if (l < point) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), static_cast<unsigned int> (point-l))); + } + } + /* re-insert the point */ + if (point >= 0) + { + /* avoid gcc warning by using compound statement even if not strictly necessary. */ + if (point == 0) + { + s = DynamicStrings_ConCat (DynamicStrings_InitStringChar ('.'), DynamicStrings_Mark (s)); + } + else + { + s = DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s), 0, point), '.'), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), point, 0))); + } + } + return s; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + carryOne - add a carry at position, i. +*/ + +static DynamicStrings_String carryOne (DynamicStrings_String s, unsigned int i) +{ + if (i >= 0) + { + if (IsDigit (DynamicStrings_char (s, static_cast<int> (i)))) + { + /* avoid gcc warning by using compound statement even if not strictly necessary. */ + if ((DynamicStrings_char (s, static_cast<int> (i))) == '9') + { + if (i == 0) + { + s = DynamicStrings_ConCat (DynamicStrings_InitStringChar ('1'), DynamicStrings_Mark (s)); + return s; + } + else + { + 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))); + return carryOne (s, i-1); + } + } + else + { + if (i == 0) + { + 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))); + } + else + { + 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))); + } + } + } + } + return s; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + IntegerToString - converts INTEGER, i, into a String. The field with can be specified + if non zero. Leading characters are defined by padding and this + function will prepend a + if sign is set to TRUE. + The base allows the caller to generate binary, octal, decimal, hexidecimal + numbers. The value of lower is only used when hexidecimal numbers are + generated and if TRUE then digits abcdef are used, and if FALSE then ABCDEF + are used. +*/ + +extern "C" DynamicStrings_String StringConvert_IntegerToString (int i, unsigned int width, char padding, unsigned int sign, unsigned int base, unsigned int lower) +{ + DynamicStrings_String s; + unsigned int c; + + if (i < 0) + { + if (i == (INT_MIN)) + { + /* remember that -15 MOD 4 = 1 in Modula-2 */ + c = ((unsigned int ) (abs (i+1)))+1; + if (width > 0) + { + 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))); + } + else + { + 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))); + } + } + else + { + s = DynamicStrings_InitString ((const char *) "-", 1); + } + i = -i; + } + else + { + if (sign) + { + s = DynamicStrings_InitString ((const char *) "+", 1); + } + else + { + s = DynamicStrings_InitString ((const char *) "", 0); + } + } + if (i > (((int ) (base))-1)) + { + 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))); + } + else + { + if (i <= 9) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (i))+ ((unsigned int) ('0'))))))); + } + else + { + if (lower) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (i))+ ((unsigned int) ('a')))-10))))); + } + else + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (i))+ ((unsigned int) ('A')))-10))))); + } + } + } + if (width > (DynamicStrings_Length (s))) + { + return DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (padding)), width-(DynamicStrings_Length (s))), DynamicStrings_Mark (s)); + } + return s; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + CardinalToString - converts CARDINAL, c, into a String. The field with can be specified + if non zero. Leading characters are defined by padding. + The base allows the caller to generate binary, octal, decimal, hexidecimal + numbers. The value of lower is only used when hexidecimal numbers are + generated and if TRUE then digits abcdef are used, and if FALSE then ABCDEF + are used. +*/ + +extern "C" DynamicStrings_String StringConvert_CardinalToString (unsigned int c, unsigned int width, char padding, unsigned int base, unsigned int lower) +{ + DynamicStrings_String s; + + s = DynamicStrings_InitString ((const char *) "", 0); + if (c > (base-1)) + { + s = DynamicStrings_ConCat (DynamicStrings_ConCat (s, DynamicStrings_Mark (StringConvert_CardinalToString (c / base, 0, ' ', base, lower))), DynamicStrings_Mark (StringConvert_CardinalToString (c % base, 0, ' ', base, lower))); + } + else + { + if (c <= 9) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) (c+ ((unsigned int) ('0'))))))); + } + else + { + if (lower) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((c+ ((unsigned int) ('a')))-10))))); + } + else + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((c+ ((unsigned int) ('A')))-10))))); + } + } + } + if (width > (DynamicStrings_Length (s))) + { + return DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (padding)), width-(DynamicStrings_Length (s))), s); + } + return s; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + StringToInteger - converts a string, s, of, base, into an INTEGER. + Leading white space is ignored. It stops converting + when either the string is exhausted or if an illegal + numeral is found. + The parameter found is set TRUE if a number was found. +*/ + +extern "C" int StringConvert_StringToInteger (DynamicStrings_String s, unsigned int base, unsigned int *found) +{ + unsigned int n; + unsigned int l; + unsigned int c; + unsigned int negative; + + s = DynamicStrings_RemoveWhitePrefix (s); /* returns a new string, s */ + l = DynamicStrings_Length (s); /* returns a new string, s */ + c = 0; + n = 0; + negative = FALSE; + if (n < l) + { + /* parse leading + and - */ + while (((DynamicStrings_char (s, static_cast<int> (n))) == '-') || ((DynamicStrings_char (s, static_cast<int> (n))) == '+')) + { + if ((DynamicStrings_char (s, static_cast<int> (n))) == '-') + { + negative = ! negative; + } + n += 1; + } + while ((n < l) && ((IsDecimalDigitValid (DynamicStrings_char (s, static_cast<int> (n)), base, &c)) || (IsHexidecimalDigitValid (DynamicStrings_char (s, static_cast<int> (n)), base, &c)))) + { + (*found) = TRUE; + n += 1; + } + } + s = DynamicStrings_KillString (s); + if (negative) + { + return -((int ) (Min (((unsigned int ) (INT_MAX))+1, c))); + } + else + { + return (int ) (Min (static_cast<unsigned int> (INT_MAX), c)); + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + StringToCardinal - converts a string, s, of, base, into a CARDINAL. + Leading white space is ignored. It stops converting + when either the string is exhausted or if an illegal + numeral is found. + The parameter found is set TRUE if a number was found. +*/ + +extern "C" unsigned int StringConvert_StringToCardinal (DynamicStrings_String s, unsigned int base, unsigned int *found) +{ + unsigned int n; + unsigned int l; + unsigned int c; + + s = DynamicStrings_RemoveWhitePrefix (s); /* returns a new string, s */ + l = DynamicStrings_Length (s); /* returns a new string, s */ + c = 0; + n = 0; + if (n < l) + { + /* parse leading + */ + while ((DynamicStrings_char (s, static_cast<int> (n))) == '+') + { + n += 1; + } + while ((n < l) && ((IsDecimalDigitValid (DynamicStrings_char (s, static_cast<int> (n)), base, &c)) || (IsHexidecimalDigitValid (DynamicStrings_char (s, static_cast<int> (n)), base, &c)))) + { + (*found) = TRUE; + n += 1; + } + } + s = DynamicStrings_KillString (s); + return c; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + LongIntegerToString - converts LONGINT, i, into a String. The field with + can be specified if non zero. Leading characters + are defined by padding and this function will + prepend a + if sign is set to TRUE. + The base allows the caller to generate binary, + octal, decimal, hexidecimal numbers. + The value of lower is only used when hexidecimal + numbers are generated and if TRUE then digits + abcdef are used, and if FALSE then ABCDEF are used. +*/ + +extern "C" DynamicStrings_String StringConvert_LongIntegerToString (long int i, unsigned int width, char padding, unsigned int sign, unsigned int base, unsigned int lower) +{ + DynamicStrings_String s; + long unsigned int c; + + if (i < 0) + { + if (i == (LONG_MIN)) + { + /* remember that -15 MOD 4 is 1 in Modula-2, and although ABS(MIN(LONGINT)+1) + is very likely MAX(LONGINT), it is safer not to assume this is the case */ + c = ((long unsigned int ) (labs (i+1)))+1; + if (width > 0) + { + 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))); + } + else + { + 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))); + } + } + else + { + s = DynamicStrings_InitString ((const char *) "-", 1); + } + i = -i; + } + else + { + if (sign) + { + s = DynamicStrings_InitString ((const char *) "+", 1); + } + else + { + s = DynamicStrings_InitString ((const char *) "", 0); + } + } + if (i > ((long int ) (base-1))) + { + 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))); + } + else + { + if (i <= 9) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (i))+ ((unsigned int) ('0'))))))); + } + else + { + if (lower) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (i))+ ((unsigned int) ('a')))-10))))); + } + else + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (i))+ ((unsigned int) ('A')))-10))))); + } + } + } + if (width > (DynamicStrings_Length (s))) + { + return DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (padding)), width-(DynamicStrings_Length (s))), s); + } + return s; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + StringToLongInteger - converts a string, s, of, base, into an LONGINT. + Leading white space is ignored. It stops converting + when either the string is exhausted or if an illegal + numeral is found. + The parameter found is set TRUE if a number was found. +*/ + +extern "C" long int StringConvert_StringToLongInteger (DynamicStrings_String s, unsigned int base, unsigned int *found) +{ + unsigned int n; + unsigned int l; + long unsigned int c; + unsigned int negative; + + s = DynamicStrings_RemoveWhitePrefix (s); /* returns a new string, s */ + l = DynamicStrings_Length (s); /* returns a new string, s */ + c = 0; + n = 0; + negative = FALSE; + if (n < l) + { + /* parse leading + and - */ + while (((DynamicStrings_char (s, static_cast<int> (n))) == '-') || ((DynamicStrings_char (s, static_cast<int> (n))) == '+')) + { + if ((DynamicStrings_char (s, static_cast<int> (n))) == '-') + { + negative = ! negative; + } + n += 1; + } + while ((n < l) && ((IsDecimalDigitValidLong (DynamicStrings_char (s, static_cast<int> (n)), base, &c)) || (IsHexidecimalDigitValidLong (DynamicStrings_char (s, static_cast<int> (n)), base, &c)))) + { + (*found) = TRUE; + n += 1; + } + } + s = DynamicStrings_KillString (s); + if (negative) + { + return -((long int ) (LongMin (((long unsigned int ) (LONG_MAX))+1, c))); + } + else + { + return (long int ) (LongMin (static_cast<long unsigned int> (LONG_MAX), c)); + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + LongCardinalToString - converts LONGCARD, c, into a String. The field + width can be specified if non zero. Leading + characters are defined by padding. + The base allows the caller to generate binary, + octal, decimal, hexidecimal numbers. + The value of lower is only used when hexidecimal + numbers are generated and if TRUE then digits + abcdef are used, and if FALSE then ABCDEF are used. +*/ + +extern "C" DynamicStrings_String StringConvert_LongCardinalToString (long unsigned int c, unsigned int width, char padding, unsigned int base, unsigned int lower) +{ + DynamicStrings_String s; + + s = DynamicStrings_InitString ((const char *) "", 0); + if (c > ((long unsigned int ) (base-1))) + { + 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)); + } + else + { + if (c <= 9) + { + s = DynamicStrings_ConCat (s, DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (c))+ ((unsigned int) ('0')))))); + } + else + { + if (lower) + { + s = DynamicStrings_ConCat (s, DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (c))+ ((unsigned int) ('a')))-10)))); + } + else + { + s = DynamicStrings_ConCat (s, DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (c))+ ((unsigned int) ('A')))-10)))); + } + } + } + if (width > (DynamicStrings_Length (s))) + { + return DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (padding)), width-(DynamicStrings_Length (s))), s); + } + return s; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + StringToLongCardinal - converts a string, s, of, base, into a LONGCARD. + Leading white space is ignored. It stops converting + when either the string is exhausted or if an illegal + numeral is found. + The parameter found is set TRUE if a number was found. +*/ + +extern "C" long unsigned int StringConvert_StringToLongCardinal (DynamicStrings_String s, unsigned int base, unsigned int *found) +{ + unsigned int n; + unsigned int l; + long unsigned int c; + + s = DynamicStrings_RemoveWhitePrefix (s); /* returns a new string, s */ + l = DynamicStrings_Length (s); /* returns a new string, s */ + c = 0; + n = 0; + if (n < l) + { + /* parse leading + */ + while ((DynamicStrings_char (s, static_cast<int> (n))) == '+') + { + n += 1; + } + while ((n < l) && ((IsDecimalDigitValidLong (DynamicStrings_char (s, static_cast<int> (n)), base, &c)) || (IsHexidecimalDigitValidLong (DynamicStrings_char (s, static_cast<int> (n)), base, &c)))) + { + (*found) = TRUE; + n += 1; + } + } + s = DynamicStrings_KillString (s); + return c; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + ShortCardinalToString - converts SHORTCARD, c, into a String. The field + width can be specified if non zero. Leading + characters are defined by padding. + The base allows the caller to generate binary, + octal, decimal, hexidecimal numbers. + The value of lower is only used when hexidecimal + numbers are generated and if TRUE then digits + abcdef are used, and if FALSE then ABCDEF are used. +*/ + +extern "C" DynamicStrings_String StringConvert_ShortCardinalToString (short unsigned int c, unsigned int width, char padding, unsigned int base, unsigned int lower) +{ + DynamicStrings_String s; + + s = DynamicStrings_InitString ((const char *) "", 0); + if (((unsigned int ) (c)) > (base-1)) + { + 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)); + } + else + { + if (c <= 9) + { + s = DynamicStrings_ConCat (s, DynamicStrings_InitStringChar ( ((char) (((unsigned int ) (c))+ ((unsigned int) ('0')))))); + } + else + { + if (lower) + { + s = DynamicStrings_ConCat (s, DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (c))+ ((unsigned int) ('a')))-10)))); + } + else + { + s = DynamicStrings_ConCat (s, DynamicStrings_InitStringChar ( ((char) ((((unsigned int ) (c))+ ((unsigned int) ('A')))-10)))); + } + } + } + if (width > (DynamicStrings_Length (s))) + { + return DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (padding)), width-(DynamicStrings_Length (s))), s); + } + return s; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + StringToShortCardinal - converts a string, s, of, base, into a SHORTCARD. + Leading white space is ignored. It stops converting + when either the string is exhausted or if an illegal + numeral is found. + The parameter found is set TRUE if a number was found. +*/ + +extern "C" short unsigned int StringConvert_StringToShortCardinal (DynamicStrings_String s, unsigned int base, unsigned int *found) +{ + unsigned int n; + unsigned int l; + short unsigned int c; + + s = DynamicStrings_RemoveWhitePrefix (s); /* returns a new string, s */ + l = DynamicStrings_Length (s); /* returns a new string, s */ + c = 0; + n = 0; + if (n < l) + { + /* parse leading + */ + while ((DynamicStrings_char (s, static_cast<int> (n))) == '+') + { + n += 1; + } + while ((n < l) && ((IsDecimalDigitValidShort (DynamicStrings_char (s, static_cast<int> (n)), base, &c)) || (IsHexidecimalDigitValidShort (DynamicStrings_char (s, static_cast<int> (n)), base, &c)))) + { + (*found) = TRUE; + n += 1; + } + } + s = DynamicStrings_KillString (s); + return c; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + stoi - decimal string to INTEGER +*/ + +extern "C" int StringConvert_stoi (DynamicStrings_String s) +{ + unsigned int found; + + return StringConvert_StringToInteger (s, 10, &found); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + itos - integer to decimal string. +*/ + +extern "C" DynamicStrings_String StringConvert_itos (int i, unsigned int width, char padding, unsigned int sign) +{ + return StringConvert_IntegerToString (i, width, padding, sign, 10, FALSE); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + ctos - cardinal to decimal string. +*/ + +extern "C" DynamicStrings_String StringConvert_ctos (unsigned int c, unsigned int width, char padding) +{ + return StringConvert_CardinalToString (c, width, padding, 10, FALSE); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + stoc - decimal string to CARDINAL +*/ + +extern "C" unsigned int StringConvert_stoc (DynamicStrings_String s) +{ + unsigned int found; + + return StringConvert_StringToCardinal (s, 10, &found); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + hstoi - hexidecimal string to INTEGER +*/ + +extern "C" int StringConvert_hstoi (DynamicStrings_String s) +{ + unsigned int found; + + return StringConvert_StringToInteger (s, 16, &found); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + ostoi - octal string to INTEGER +*/ + +extern "C" int StringConvert_ostoi (DynamicStrings_String s) +{ + unsigned int found; + + return StringConvert_StringToInteger (s, 8, &found); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + bstoi - binary string to INTEGER +*/ + +extern "C" int StringConvert_bstoi (DynamicStrings_String s) +{ + unsigned int found; + + return StringConvert_StringToInteger (s, 2, &found); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + hstoc - hexidecimal string to CARDINAL +*/ + +extern "C" unsigned int StringConvert_hstoc (DynamicStrings_String s) +{ + unsigned int found; + + return StringConvert_StringToCardinal (s, 16, &found); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + ostoc - octal string to CARDINAL +*/ + +extern "C" unsigned int StringConvert_ostoc (DynamicStrings_String s) +{ + unsigned int found; + + return StringConvert_StringToCardinal (s, 8, &found); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + bstoc - binary string to CARDINAL +*/ + +extern "C" unsigned int StringConvert_bstoc (DynamicStrings_String s) +{ + unsigned int found; + + return StringConvert_StringToCardinal (s, 2, &found); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + StringToLongreal - returns a LONGREAL and sets found to TRUE if a legal number is seen. +*/ + +extern "C" long double StringConvert_StringToLongreal (DynamicStrings_String s, unsigned int *found) +{ + unsigned int error; + long double value; + + s = DynamicStrings_RemoveWhitePrefix (s); /* new string is created */ + value = ldtoa_strtold (DynamicStrings_string (s), &error); /* new string is created */ + s = DynamicStrings_KillString (s); + (*found) = ! error; + return value; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + LongrealToString - converts a LONGREAL number, Real, which has, + TotalWidth, and FractionWidth into a string. + It uses decimal notation. + + So for example: + + LongrealToString(1.0, 4, 2) -> '1.00' + LongrealToString(12.3, 5, 2) -> '12.30' + LongrealToString(12.3, 6, 2) -> ' 12.30' + LongrealToString(12.3, 6, 3) -> '12.300' + + if total width is too small then the fraction + becomes truncated. + + LongrealToString(12.3, 5, 3) -> '12.30' + + Positive numbers do not have a '+' prepended. + Negative numbers will have a '-' prepended and + the TotalWidth will need to be large enough + to contain the sign, whole number, '.' and + fractional components. +*/ + +extern "C" DynamicStrings_String StringConvert_LongrealToString (long double x, unsigned int TotalWidth, unsigned int FractionWidth) +{ + unsigned int maxprecision; + DynamicStrings_String s; + void * r; + int point; + unsigned int sign; + int l; + + if (TotalWidth == 0) + { + maxprecision = TRUE; + r = ldtoa_ldtoa (x, ldtoa_decimaldigits, 100, &point, &sign); + } + else + { + r = ldtoa_ldtoa (x, ldtoa_decimaldigits, 100, &point, &sign); + } + s = DynamicStrings_InitStringCharStar (r); + libc_free (r); + l = DynamicStrings_Length (s); + if (point > l) + { + /* avoid dangling else. */ + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), static_cast<unsigned int> (point-l)))); + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ".0", 2))); + if (! maxprecision && (FractionWidth > 0)) + { + FractionWidth -= 1; + if (((int ) (FractionWidth)) > (point-l)) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "0", 1)), FractionWidth))); + } + } + } + else if (point < 0) + { + /* avoid dangling else. */ + s = DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), static_cast<unsigned int> (-point)), DynamicStrings_Mark (s)); + l = DynamicStrings_Length (s); + s = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "0.", 2), DynamicStrings_Mark (s)); + if (! maxprecision && (l < ((int ) (FractionWidth)))) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "0", 1)), static_cast<unsigned int> (((int ) (FractionWidth))-l)))); + } + } + else + { + /* avoid dangling else. */ + if (point == 0) + { + s = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "0.", 2), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), point, 0))); + } + else + { + s = DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Slice (DynamicStrings_Mark (s), 0, point), '.'), DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), point, 0))); + } + if (! maxprecision && ((l-point) < ((int ) (FractionWidth)))) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "0", 1)), static_cast<unsigned int> (((int ) (FractionWidth))-(l-point))))); + } + } + if ((DynamicStrings_Length (s)) > TotalWidth) + { + /* avoid gcc warning by using compound statement even if not strictly necessary. */ + if (TotalWidth > 0) + { + if (sign) + { + s = DynamicStrings_Slice (DynamicStrings_Mark (StringConvert_ToDecimalPlaces (s, FractionWidth)), 0, static_cast<int> (TotalWidth-1)); + s = DynamicStrings_ConCat (DynamicStrings_InitStringChar ('-'), DynamicStrings_Mark (s)); + sign = FALSE; + } + else + { + /* minus 1 because all results will include a '.' */ + s = DynamicStrings_Slice (DynamicStrings_Mark (StringConvert_ToDecimalPlaces (s, FractionWidth)), 0, static_cast<int> (TotalWidth)); + } + } + else + { + if (sign) + { + s = StringConvert_ToDecimalPlaces (s, FractionWidth); + s = DynamicStrings_ConCat (DynamicStrings_InitStringChar ('-'), DynamicStrings_Mark (s)); + sign = FALSE; + } + else + { + /* minus 1 because all results will include a '.' */ + s = StringConvert_ToDecimalPlaces (s, FractionWidth); + } + } + } + if ((DynamicStrings_Length (s)) < TotalWidth) + { + s = DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar (' ')), TotalWidth-(DynamicStrings_Length (s))), DynamicStrings_Mark (s)); + } + return s; + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + stor - returns a REAL given a string. +*/ + +extern "C" double StringConvert_stor (DynamicStrings_String s) +{ + unsigned int found; + + return (double ) (StringConvert_StringToLongreal (s, &found)); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + stolr - returns a LONGREAL given a string. +*/ + +extern "C" long double StringConvert_stolr (DynamicStrings_String s) +{ + unsigned int found; + + return StringConvert_StringToLongreal (s, &found); + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + ToSigFig - returns a floating point or base 10 integer + string which is accurate to, n, significant + figures. It will return a new String + and, s, will be destroyed. + + + So: 12.345 + + rounded to the following significant figures yields + + 5 12.345 + 4 12.34 + 3 12.3 + 2 12 + 1 10 +*/ + +extern "C" DynamicStrings_String StringConvert_ToSigFig (DynamicStrings_String s, unsigned int n) +{ + int point; + unsigned int poTen; + + Assert ((IsDigit (DynamicStrings_char (s, 0))) || ((DynamicStrings_char (s, 0)) == '.'), (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/StringConvert.mod", 61, 1222, (const char *) "ToSigFig", 8); + point = DynamicStrings_Index (s, '.', 0); + if (point < 0) + { + poTen = DynamicStrings_Length (s); + } + else + { + poTen = point; + } + s = doSigFig (s, n); + /* if the last character is '.' remove it */ + if (((DynamicStrings_Length (s)) > 0) && ((DynamicStrings_char (s, -1)) == '.')) + { + return DynamicStrings_Slice (DynamicStrings_Mark (s), 0, -1); + } + else + { + if (poTen > (DynamicStrings_Length (s))) + { + s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), poTen-(DynamicStrings_Length (s))))); + } + return s; + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + + +/* + ToDecimalPlaces - returns a floating point or base 10 integer + string which is accurate to, n, decimal + places. It will return a new String + and, s, will be destroyed. + Decimal places yields, n, digits after + the . + + So: 12.345 + + rounded to the following decimal places yields + + 5 12.34500 + 4 12.3450 + 3 12.345 + 2 12.34 + 1 12.3 +*/ + +extern "C" DynamicStrings_String StringConvert_ToDecimalPlaces (DynamicStrings_String s, unsigned int n) +{ + int point; + + Assert ((IsDigit (DynamicStrings_char (s, 0))) || ((DynamicStrings_char (s, 0)) == '.'), (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/StringConvert.mod", 61, 1069, (const char *) "ToDecimalPlaces", 15); + point = DynamicStrings_Index (s, '.', 0); + if (point < 0) + { + /* avoid gcc warning by using compound statement even if not strictly necessary. */ + if (n > 0) + { + return DynamicStrings_ConCat (DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringChar ('.'))), DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitStringChar ('0')), n)); + } + else + { + return s; + } + } + s = doDecimalPlaces (s, n); + /* if the last character is '.' remove it */ + if (((DynamicStrings_Length (s)) > 0) && ((DynamicStrings_char (s, -1)) == '.')) + { + return DynamicStrings_Slice (DynamicStrings_Mark (s), 0, -1); + } + else + { + return s; + } + /* static analysis guarentees a RETURN statement will be used before here. */ + __builtin_unreachable (); +} + +extern "C" void _M2_StringConvert_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) +{ +} + +extern "C" void _M2_StringConvert_finish (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) +{ +} |