Ejemplo n.º 1
0
def value(entry, expr, params=None, magic_expression=None, magic_name=None, ref_name=None):
  """
  Convert an expression object to a valid C expression.

  entry -- The entry that will use this value.
  expr -- The bdec.expression.Expression instance to represent in C code.
  params -- The parameters to use for finding variables. If None, it will use
    the decode parameters (decode_params).
  magic_expression -- If the 'magic_expression' is found it will be replaced
    with the 'magic_name'.
  magic_name -- The 'magic' name to use when 'magic_expression' is found.
  """
  ref_name = ref_name or local_reference_name
  if params is None:
      params = decode_params
  if expr is magic_expression:
      return magic_name
  elif isinstance(expr, int):
      return str(expr)
  elif isinstance(expr, Constant):
      if int(expr.value) >= (1 << 61):
          return "%iULL" % expr.value
      if int(expr.value) >= (1 << 32):
          return "%iLL" % expr.value
      elif int(expr.value) > (1 << 31):
          return "%iU" % expr.value
      else:
          return int(expr.value)
  elif isinstance(expr, ReferenceExpression):
      return ref_name(entry, expr, params)[1]
  elif isinstance(expr, ArithmeticExpression):
      left = value(entry, expr.left, params, magic_expression, magic_name, ref_name)
      right = value(entry, expr.right, params, magic_expression, magic_name, ref_name)

      cast = ""
      left_type = type_from_range(expression_range(expr.left, entry, raw_params))
      right_type = type_from_range(expression_range(expr.right, entry, raw_params))
      result_type = type_from_range(expression_range(expr, entry, raw_params))

      types = unsigned_types.copy()
      types.update(signed_types)
      if types[result_type][0] > max(types[left_type][0], types[right_type][0]):
          # If the result will be bigger than both left and right, we will
          # explicitly cast to make sure the operation is valid. For example,
          # '1 << 63' is invalid, but '(long long)1 << 63' is ok.
          cast = "(%s)" % result_type
      return "(%s%s %s %s)" % (cast, left, _OPERATORS[expr.op], right)
  elif isinstance(expr, RoundUpDivisionExpression):
      left = value(entry, expr.numerator, params, magic_expression, magic_name, ref_name)
      right = value(entry, expr.denominator, params, magic_expression, magic_name, ref_name)
      rounding = '1' if expr.should_round_up else '0'
      return function('divide with rounding') + '(%s, %s, %s)' % (left, right, rounding)
  else:
      raise Exception('Unknown length value', expr)
Ejemplo n.º 2
0
def sequenceof_count_ctype(entry):
    assert isinstance(entry, SequenceOf)
    assert len(entry.children) == 1
    if entry.count is not None:
        return type_from_range(expression_range(entry.count, entry, raw_params))
    if entry.length is not None:
        range = expression_range(entry.length, entry, raw_params) / \
                EntryLengthType(entry.children[0].entry).range(raw_params)
        return type_from_range(range)
    # No count, no type, so use the longest possible.
    return type_from_range(Range(0, None))
Ejemplo n.º 3
0
 def test_subtract_range(self):
     a = parse('95 - (100 - 20)')
     self.assertEqual(15, expression_range(a).min)
     self.assertEqual(15, expression_range(a).max)
Ejemplo n.º 4
0
 def test_add_range(self):
     a = parse('(10 + 3) + 7')
     self.assertEqual(20, expression_range(a).min)
     self.assertEqual(20, expression_range(a).max)
Ejemplo n.º 5
0
 def test_mod_range(self):
     a = parse('100 % 2')
     self.assertEqual(Range(0, 1), expression_range(a))
Ejemplo n.º 6
0
 def test_divide_range(self):
     a = parse('16 / 2 / 4')
     self.assertEqual(2, expression_range(a).min)
     self.assertEqual(2, expression_range(a).max)
Ejemplo n.º 7
0
 def test_multiple_range(self):
     a = parse('8 * 1 * 4')
     self.assertEqual(32, expression_range(a).min)
     self.assertEqual(32, expression_range(a).max)
Ejemplo n.º 8
0
 def test_constant_range(self):
     a = parse('8')
     self.assertEqual(8, expression_range(a).min)
     self.assertEqual(8, expression_range(a).max)