diff --git a/src/core/FRDecimal.cpp b/src/core/FRDecimal.cpp index 55030972..deb5c521 100644 --- a/src/core/FRDecimal.cpp +++ b/src/core/FRDecimal.cpp @@ -482,10 +482,11 @@ wxString Dec34DPDToString(dec34_t value) return DecInfoToString(CDec34DPDDef, info); } -// input definition + src -// ouput dstInfo +// input def + srcStr +// ouput dstInfo + errMsg bool StringToDecParse(const DECFLOAT_DEFINITION& def, - const wxString& srcStr, DECFLOAT_DECINFO* dstInfo) + const wxString& srcStr, DECFLOAT_DECINFO* dstInfo, + wxString& errMsg) { wxString valueStr; wxString expStr; @@ -501,7 +502,10 @@ bool StringToDecParse(const DECFLOAT_DEFINITION& def, *dstInfo = {0}; if (srcStr.IsEmpty()) + { + errMsg = _("SrcStr is empty!"); return false; + } srcStrL = srcStr.Lower(); if (srcStrL == _("nan")) @@ -535,7 +539,12 @@ bool StringToDecParse(const DECFLOAT_DEFINITION& def, { // more than one dot? if (DecimalSeparatorPos != -1) + { + errMsg = wxString::Format( + _("Not numeric. Found 2nd decimalseparator (%c) at position %d."), + DecimalSeparator, i1+1); return false; + } DecimalSeparatorPos = i1 - iStart; continue; } @@ -550,7 +559,12 @@ bool StringToDecParse(const DECFLOAT_DEFINITION& def, } // not numeric if ((ch < '0') || (ch > '9')) + { + errMsg = wxString::Format( + _("Not numeric. Invalid char (%c) at position %d."), + ch, i1+1); return false; + } valueStr = valueStr + ch; } if (iStart < i1) @@ -560,7 +574,10 @@ bool StringToDecParse(const DECFLOAT_DEFINITION& def, { // exponent expected (e.g becase trailing space like "123 ") if (NeedExponent) + { + errMsg = "Not numeric. Exponent expected or invalid trailing space."; return false; + } expStr = _("0"); } else @@ -584,14 +601,24 @@ bool StringToDecParse(const DECFLOAT_DEFINITION& def, } // numeric? if ((ch < '0') || (ch > '9')) + { + errMsg = wxString::Format( + _("Not numeric. Invalid char (%c) at position %d."), + ch, i1+1); return false; + } expStr += ch; } } if (!expStr.ToLong(&tmpVal, 10)) + { + errMsg = wxString::Format( + _("Not numeric. Invalid exponent (%c)."), + tmpVal); return false; + } // Add decimaldigits to exponent DecimalDigits = valueStr.Length() - DecimalSeparatorPos; @@ -714,7 +741,7 @@ uint16_t Str3ToDeclet(const wxString& str, int& offset) return declet; } -bool DecInfoToDec34DPD(const DECFLOAT_DECINFO &info, dec34_t* dst) +bool DecInfoToDec34DPD(const DECFLOAT_DECINFO &info, dec34_t* dst, wxString& errMsg) { DECFLOAT128_UNION dfu = {0}; DECFLOAT_DEFINITION def = CDec34DPDDef; @@ -739,7 +766,11 @@ bool DecInfoToDec34DPD(const DECFLOAT_DECINFO &info, dec34_t* dst) // exponent in range? if ((info.exp < -def.minExp) || (info.exp > def.maxExp)) + { + errMsg = wxString::Format( + _("Exponent (%d) out of range!"), info.exp); return false; + } uint32_t exp = info.exp + def.minExp; @@ -778,7 +809,7 @@ bool DecInfoToDec34DPD(const DECFLOAT_DECINFO &info, dec34_t* dst) return true; } -bool DecInfoToDec16DPD(const DECFLOAT_DECINFO &info, dec16_t* dst) +bool DecInfoToDec16DPD(const DECFLOAT_DECINFO &info, dec16_t* dst, wxString& errMsg) { DECFLOAT64_UNION dfu = {0}; DECFLOAT_DEFINITION def = CDec16DPDDef; @@ -803,7 +834,11 @@ bool DecInfoToDec16DPD(const DECFLOAT_DECINFO &info, dec16_t* dst) // exponent in range? if ((info.exp < -def.minExp) || (info.exp > def.maxExp)) + { + errMsg = wxString::Format( + _("Exponent (%d) out of range!"), info.exp); return false; + } uint32_t exp = info.exp + def.minExp; @@ -830,12 +865,12 @@ bool DecInfoToDec16DPD(const DECFLOAT_DECINFO &info, dec16_t* dst) return true; } -bool StringToDec34DPD(const wxString& src, dec34_t* dst) +bool StringToDec34DPD(const wxString& src, dec34_t* dst, wxString& errMsg) { DECFLOAT_DECINFO info; - if (!StringToDecParse(CDec34DPDDef, src, &info)) + if (!StringToDecParse(CDec34DPDDef, src, &info, errMsg)) return false; - if (!DecInfoToDec34DPD(info, dst)) + if (!DecInfoToDec34DPD(info, dst, errMsg)) return false; return true; } @@ -848,12 +883,12 @@ wxString Dec16DPDToString(dec16_t value) return DecInfoToString(CDec16DPDDef, info); } -bool StringToDec16DPD(const wxString& src, dec16_t* dst) +bool StringToDec16DPD(const wxString& src, dec16_t* dst, wxString& errMsg) { DECFLOAT_DECINFO info; - if (!StringToDecParse(CDec34DPDDef, src, &info)) + if (!StringToDecParse(CDec34DPDDef, src, &info, errMsg)) return false; - if (!DecInfoToDec16DPD(info, dst)) + if (!DecInfoToDec16DPD(info, dst, errMsg)) return false; return true; } diff --git a/src/core/FRDecimal.h b/src/core/FRDecimal.h index 12b0c8bc..f26c36e7 100644 --- a/src/core/FRDecimal.h +++ b/src/core/FRDecimal.h @@ -31,8 +31,8 @@ typedef IBPP::ibpp_dec16_t dec16_t; typedef IBPP::ibpp_dec34_t dec34_t; wxString Dec34DPDToString(dec34_t value); -bool StringToDec34DPD(const wxString& src, dec34_t* dst); +bool StringToDec34DPD(const wxString& src, dec34_t* dst, wxString& errMsg); wxString Dec16DPDToString(dec16_t value); -bool StringToDec16DPD(const wxString& src, dec16_t* dst); +bool StringToDec16DPD(const wxString& src, dec16_t* dst, wxString& errMsg); #endif // FR_FRDECIMAL_H diff --git a/src/core/FRInt128.cpp b/src/core/FRInt128.cpp index c41ad169..51be9a62 100644 --- a/src/core/FRInt128.cpp +++ b/src/core/FRInt128.cpp @@ -31,6 +31,7 @@ #endif #include "core/FRInt128.h" +#include // enable only for debugging //#define DEBUG_DDU @@ -90,11 +91,12 @@ void DDUdbg(DOUBLE_DABBLE_UNION& ddu) #define DDUdbg(x) #endif -bool DDUinitFromStr(DOUBLE_DABBLE_UNION& ddu, bool &isNegative, const wxString &src) +bool DDUinitFromStr(DOUBLE_DABBLE_UNION& ddu, bool &isNegative, const wxString &src, wxString& errMsg) { wxString src2; int i1, iByte; uint8_t ch; + wxChar sep1000; isNegative = (src.GetChar(0) == _("-")); if (isNegative) @@ -102,10 +104,30 @@ bool DDUinitFromStr(DOUBLE_DABBLE_UNION& ddu, bool &isNegative, const wxString & else src2 = src; + // replace thousand separators - if used + if (wxNumberFormatter::GetThousandsSeparatorIfUsed(&sep1000)) + src2.Replace(_(sep1000), _("")); + + // Check: numeric? + for (i1 = 0; i1 < src2.Length(); i1++) + { + ch = src2.GetChar(i1); + if ((ch < '0') || (ch > '9')) + { + errMsg = wxString::Format( + _("Not numeric. Invalid char (%c) at position %d."), + ch, i1+1); + return false; + } + } + // Check: number to big? // Its not really precise but prevents a buffer overflow. if (src2.Length() > (DOUBLE_DABBLE_BCD_LEN * 2)) + { + errMsg = _("Int128: Value to big."); return false; + } for (i1 = 0; i1 < src2.Length(); i1++) { @@ -207,7 +229,7 @@ void DDUadd(DOUBLE_DABBLE_UNION& ddu) } } -bool StringToInt128(const wxString& src, int128_t* dst) +bool StringToInt128(const wxString& src, int128_t* dst, wxString& errMsg) { DOUBLE_DABBLE_UNION ddu = {0}; int i1; @@ -215,7 +237,7 @@ bool StringToInt128(const wxString& src, int128_t* dst) // use double dabbl algorithm (reverse) // initialization - if (!DDUinitFromStr(ddu, isNegative, src)) + if (!DDUinitFromStr(ddu, isNegative, src, errMsg)) return false; for (i1 = 0; i1 < 128; i1++) @@ -228,7 +250,10 @@ bool StringToInt128(const wxString& src, int128_t* dst) // So we have to check if all bits could be moved into the 128-bit // result. if (ddu.shift.bcd[DOUBLE_DABBLE_BCD_LEN - 1] != 0) + { + errMsg = _("Int128: Value to big."); return false; + } if (isNegative) { @@ -237,13 +262,19 @@ bool StringToInt128(const wxString& src, int128_t* dst) ddu.shift.lowPart = ddu.shift.lowPart ^ 0xFFFFFFFFFFFFFFFF; // value to small? if (ddu.shift.highPart < 0x8000000000000000) + { + errMsg = _("Int128: Value to small."); return false; + } } else { // value to big? if (ddu.shift.highPart >= 0x8000000000000000) + { + errMsg = _("Int128: Value to big."); return false; + } } *dst = ddu.s.i128; diff --git a/src/core/FRInt128.h b/src/core/FRInt128.h index 35ea6d03..66eb183f 100644 --- a/src/core/FRInt128.h +++ b/src/core/FRInt128.h @@ -30,6 +30,6 @@ typedef IBPP::ibpp_int128_t int128_t; wxString Int128ToString(int128_t value); -bool StringToInt128(const wxString& src, int128_t* dst); +bool StringToInt128(const wxString& src, int128_t* dst, wxString& errMsg); #endif // FR_FRINT128_H diff --git a/src/gui/controls/DataGridRows.cpp b/src/gui/controls/DataGridRows.cpp index be1e3775..793203d0 100644 --- a/src/gui/controls/DataGridRows.cpp +++ b/src/gui/controls/DataGridRows.cpp @@ -725,10 +725,39 @@ void Int128ColumnDef::setFromString(DataGridRowBuffer* buffer, const wxString& source) { wxASSERT(buffer); - int128_t v128 = 0; - if (!StringToInt128(source, &v128)) - throw FRError(_("Invalid int128 numeric value")); + int i1, decimalSeparatorIdx, localSourceScale; + wxString errMsg; + wxString localSource = source; + wxChar ch; + wxChar decimalSeparator; + + if (scaleM > 0) + { + decimalSeparator = wxNumberFormatter::GetDecimalSeparator(); + decimalSeparatorIdx = localSource.rfind(decimalSeparator); + + if (decimalSeparatorIdx > -1) + { + localSource.erase(decimalSeparatorIdx,1); + localSourceScale = localSource.Length() - decimalSeparatorIdx; + } + else + localSourceScale = 0; + + // remove numbers if we are to big + if (localSourceScale > scaleM) + localSource.erase(localSource.Length() - localSourceScale + scaleM); + // add 0 if we are to small + while (localSourceScale < scaleM) + { + localSource = localSource + _("0"); + localSourceScale++; + } + } + + if (!StringToInt128(localSource, &v128, errMsg)) + throw FRError(errMsg); buffer->setValue(offsetM, v128); } @@ -1349,8 +1378,9 @@ void Dec16ColumnDef::setFromString(DataGridRowBuffer* buffer, { wxASSERT(buffer); dec16_t value; - if (!StringToDec16DPD(source, &value)) - throw FRError(_("Invalid decimal34 numeric value")); + wxString errMsg; + if (!StringToDec16DPD(source, &value, errMsg)) + throw FRError(errMsg); buffer->setValue(offsetM, value); } @@ -1410,8 +1440,9 @@ void Dec34ColumnDef::setFromString(DataGridRowBuffer* buffer, { wxASSERT(buffer); dec34_t value; - if (!StringToDec34DPD(source, &value)) - throw FRError(_("Invalid decimal34 numeric value")); + wxString errMsg; + if (!StringToDec34DPD(source, &value, errMsg)) + throw FRError(errMsg); buffer->setValue(offsetM, value); }