Breakpad processor: Support evaluating a postfix expression to produce a value.

This adds an EvaluateForValue member function to PostfixEvaluator, and
along with appropriate unit tests.

a=jimblandy, r=nealsid


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@511 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
jimblandy 2010-02-05 17:51:35 +00:00
parent 6a9ffff696
commit 89e07bf2c7
3 changed files with 151 additions and 14 deletions

View file

@ -1,3 +1,5 @@
// -*- mode: c++ -*-
// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
@ -64,11 +66,9 @@ class AutoStackClearer {
template<typename ValueType>
bool PostfixEvaluator<ValueType>::Evaluate(const string &expression,
DictionaryValidityType *assigned) {
// Ensure that the stack is cleared before returning.
AutoStackClearer clearer(&stack_);
bool PostfixEvaluator<ValueType>::EvaluateInternal(
const string &expression,
DictionaryValidityType *assigned) {
// Tokenize, splitting on whitespace.
istringstream stream(expression);
string token;
@ -194,13 +194,46 @@ bool PostfixEvaluator<ValueType>::Evaluate(const string &expression,
}
}
return true;
}
template<typename ValueType>
bool PostfixEvaluator<ValueType>::Evaluate(const string &expression,
DictionaryValidityType *assigned) {
// Ensure that the stack is cleared before returning.
AutoStackClearer clearer(&stack_);
if (!EvaluateInternal(expression, assigned))
return false;
// If there's anything left on the stack, it indicates incomplete execution.
// This is a failure case. If the stack is empty, evalution was complete
// and successful.
BPLOG_IF(ERROR, !stack_.empty()) << "Incomplete execution: " << expression;
return stack_.empty();
if (stack_.empty())
return true;
BPLOG(ERROR) << "Incomplete execution: " << expression;
return false;
}
template<typename ValueType>
bool PostfixEvaluator<ValueType>::EvaluateForValue(const string &expression,
ValueType *result) {
// Ensure that the stack is cleared before returning.
AutoStackClearer clearer(&stack_);
if (!EvaluateInternal(expression, NULL))
return false;
// A successful execution should leave exactly one value on the stack.
if (stack_.size() != 1) {
BPLOG(ERROR) << "Expression yielded bad number of results: "
<< "'" << expression << "'";
return false;
}
return PopValue(result);
}
template<typename ValueType>
typename PostfixEvaluator<ValueType>::PopResult