Evaluate the given expression string with the given context.

    .. WARNING:
        This runs eval() on a user string. This is unsafe.

def _evaluate(expression, defines):
    """Evaluate the given expression string with the given context.

    .. WARNING:
        This runs eval() on a user string. This is unsafe.
    """
    #interpolated = _interpolate(s, defines)
    try:
        defined = {'defined': (lambda v: v in defines)}
        return_value = eval(expression, defined, defines)
    except Exception, ex:
        message = str(ex)
        if message.startswith("name '") and message.endswith("' is not defined"):
            # A common error (at least this is presumed:) is to have
            #   defined(FOO)   instead of   defined('FOO')
            # We should give a little insight into what might be wrong.
            # message == "name 'FOO' is not defined"
            #    -->  variable_name == "FOO"
            variable_name = message[len("name '"):-len("' is not defined")]
            if expression.find("defined(%s)" % variable_name) > -1:
                # "defined(FOO)" in expr instead of "defined('FOO')"
                message += ''' (perhaps you want `defined('%s')` instead of `defined(%s)`)''' % (variable_name, variable_name)
        elif message.startswith("invalid syntax"):
            message = "invalid syntax: `%s`" % expression
        raise PreprocessorError(message, defines['__FILE__'], defines['__LINE__'])

    logger.debug("evaluate %r -> %s (defines=%r)", expression, return_value, defines)
    return return_value