Hi John, On 2009-12-31 at 09:30:41 [+0100], John Scipione <jscipione@xxxxxxxxx> wrote: > > I rewrote my DeskCalc changes so that I would not be doing any char* > > manipulation. To achieve this had to extend the ExpressionParser Class > > with two new methods: EvaluateToStandard() and EvaluateToScientific(). > > Each of these methods takes an int32 argument to specify the number of > > digits to grab. Trailing zeros after the decimal point are removed. > > Please review my patch below. Should patch from the haiku/ directory. > > > > Index: headers/private/shared/ExpressionParser.h > > =================================================================== > > --- headers/private/shared/ExpressionParser.h (revision 34828) > > +++ headers/private/shared/ExpressionParser.h (working copy) > > @@ -45,6 +45,11 @@ > > void > > SetSupportHexInput(bool enabled); > > > > BString Evaluate(const > > char* expressionString); > > + BString > > EvaluateToStandard( > > + const char* expressionString, > > + int32 decimalPlaces); > > + BString > > EvaluateToScientific(const char* > > + expressionString, int32 > > decimalPlaces); > > int64 > > EvaluateToInt64(const char* expressionString); > > double > > EvaluateToDouble(const char* expressionString); > > > > Index: src/apps/deskcalc/CalcView.cpp > > =================================================================== > > --- src/apps/deskcalc/CalcView.cpp (revision 34828) > > +++ src/apps/deskcalc/CalcView.cpp (working copy) > > @@ -894,6 +894,9 @@ > > void > > CalcView::Evaluate() > > { > > + const double STD_NOTATION_UPPER = 1e16; > > + const double STD_NOTATION_LOWER = 1e-16; > > + > > BString expression = fExpressionTextView->Text(); > > > > if (expression.Length() == 0) { > > @@ -903,21 +906,39 @@ > > > > _AudioFeedback(false); > > > > + ExpressionParser parser; > > + double value = 0.00; > > + BString result; > > + > > // evaluate expression > > - BString value; > > - > > try { > > - ExpressionParser parser; > > - value = parser.Evaluate(expression.String()); > > + value = parser.EvaluateToDouble(expression.String()); > > } catch (ParseException e) { > > BString error(e.message.String()); > > error << " at " << (e.position + 1); > > - fExpressionTextView->SetText(error.String()); > > - return; > > + // just print error > > + result.SetTo("error"); > > + fExpressionTextView->SetExpression(result.String()); > > + return; > > } > > > > + if (value == 0) { > > + result.SetTo("0"); > > + fExpressionTextView->SetExpression(result.String()); > > + return; > > + } else if (((value < STD_NOTATION_UPPER) > > + && (value > STD_NOTATION_LOWER)) > > + || ((value > -STD_NOTATION_UPPER) > > + && (value < -STD_NOTATION_LOWER))) { > > + // Standard Notation > > + result = parser.EvaluateToStandard(expression.String(), 16); > > + } else { > > + // Scientific Notation > > + result = parser.EvaluateToScientific(expression.String(), 12); > > + } > > + > > // render new result to display > > - fExpressionTextView->SetExpression(value.String()); > > + fExpressionTextView->SetExpression(result.String()); > > } > > > > > > Index: src/kits/shared/ExpressionParser.cpp > > =================================================================== > > --- src/kits/shared/ExpressionParser.cpp (revision 34828) > > +++ src/kits/shared/ExpressionParser.cpp (working copy) > > @@ -317,6 +317,14 @@ > > BString > > ExpressionParser::Evaluate(const char* expressionString) { > > + return EvaluateToStandard(expressionString, kMaxDecimalPlaces); > > +} > > + > > + > > +BString > > +ExpressionParser::EvaluateToStandard(const char* expressionString, > > + int32 decimalPlaces) > > +{ > > fTokenizer->SetTo(expressionString); > > > > MAPM value = _ParseBinary(); > > @@ -327,11 +335,14 @@ > > if (value == 0) > > return BString("0"); > > > > - char* buffer = value.toFixPtStringExp(kMaxDecimalPlaces, '.', > > 0, 0); > > + if (decimalPlaces <= 0) > > + decimalPlaces = kMaxDecimalPlaces; > > + > > + char* buffer = value.toFixPtStringExp(decimalPlaces, '.', 0, 0); > > if (buffer == NULL) > > throw ParseException("out of memory", 0); > > > > - // remove surplus zeros > > + // remove trailing decimal zeros > > int32 lastChar = strlen(buffer) - 1; > > if (strchr(buffer, '.')) { > > while (buffer[lastChar] == '0') > > @@ -343,6 +354,50 @@ > > BString result(buffer, lastChar + 1); > > free(buffer); > > return result; > > +} > > + > > + > > +BString > > +ExpressionParser::EvaluateToScientific(const char* expressionString, > > + int32 decimalPlaces) > > +{ > > + fTokenizer->SetTo(expressionString); > > + > > + MAPM value = _ParseBinary(); > > + Token token = fTokenizer->NextToken(); > > + if (token.type != TOKEN_END_OF_LINE) > > + throw ParseException("parse error", token.position); > > + > > + if (value == 0) > > + return BString("0"); > > + > > + if (decimalPlaces <= 0) > > + decimalPlaces = kMaxDecimalPlaces; > > + > > + // max number of characters possible for 32 bits of decimal places > > is > > + // decimal places + 15 for -0.9999999....E+2147483647 > > + // 3 + decimal digits + 2 + 10 = decimalPlaces + 15 > > + char buffer[decimalPlaces + 15]; > > + value.toString(buffer, decimalPlaces); > > + if (buffer == NULL) > > + throw ParseException("out of memory", 0); "buffer" is stack allocated, the allocation check should be "copy&paste left-over". :-) > > + > > + BString result(buffer, decimalPlaces + 15); > > + > > + // remove trailing decimal zeros > > + if (result.FindFirst('.') != B_ERROR) { > > + int32 offset = result.FindLast('E'); > > + if (offset != B_ERROR) { > > + offset--; // go to character before 'E' > > + while(result[offset] == '0') { > > + result = result.Remove(offset, sizeof(char)); > > + offset--; > > + } > > + if(result[offset] == '.') > > + result = result.Remove(offset, sizeof(char)); > > + } > > + } > > + return result; > > } > > > > Minor bug in patch: > if (decimalPlaces <= 0) > decimalPlaces = kMaxDecimalPlaces; > should read: > if (decimalPlaces < 0) > decimalPlaces = kMaxDecimalPlaces; > > Not worth posting another patch, but 0 decimal places is valid. Thanks for your work! Can you post another version where you use spaces instead of tabs? (Maybe it's just an editor setting?) Best regards, -Stephan