Пример #1
0
 def recurse_into_conditionals(self, tokens):
     """Called recursively within nested #if(n)def... #else... #endif blocks."""
     for token in tokens:
         # Another nested conditional block
         if token.predicate:
             if (token.predicate in self.get_consts_and_enums()
                     and self.get_consts_and_enums()[token.predicate]):
                 self.recurse_into_conditionals(token.if_true)
             else:
                 self.recurse_into_conditionals(token.if_false)
         # One or more declarations
         else:
             # A type declaration for a function pointer.
             if token.arguments:
                 self.typedefs_dict.update(
                     {token.typename: header_parsing.CTYPES_FUNCTION_PTR})
             elif token.typename:
                 self.typedefs_dict.update({token.name: token.typename})
             elif token.value:
                 value = codegen_util.try_coerce_to_num(token.value)
                 # Avoid adding function aliases.
                 if isinstance(value, six.string_types):
                     continue
                 else:
                     self.consts_dict.update({token.name: value})
             else:
                 self.consts_dict.update({token.name: True})
Пример #2
0
    def resolve_size(self, old_size):
        """Resolves an array size identifier.

    The following conversions will be attempted:

      * If `old_size` is an integer it will be returned as-is.
      * If `old_size` is a string of the form `"3"` it will be cast to an int.
      * If `old_size` is a string in `self.consts_dict` then the value of the
        constant will be returned.
      * If `old_size` is a string of the form `"3*constant_name"` then the
        result of `3*constant_value` will be returned.
      * If `old_size` is a string that does not specify an int constant and
        cannot be cast to an int (e.g. an identifier for a dynamic dimension,
        such as `"ncontact"`) then it will be returned as-is.

    Args:
      old_size: An int or string.

    Returns:
      An int or string.
    """
        if isinstance(old_size, int):
            return old_size  # If it's already an int then there's nothing left to do
        elif "*" in old_size:
            # If it's a string specifying a product (such as "2*mjMAXLINEPNT"),
            # recursively resolve the components to ints and calculate the result.
            size = 1
            sizes = []
            is_int = True
            for part in old_size.split("*"):
                dim = self.resolve_size(part)
                sizes.append(dim)
                if not isinstance(dim, int):
                    is_int = False
                else:
                    size *= dim
            if is_int:
                return size
            else:
                return tuple(sizes)
        else:
            # Recursively dereference any sizes declared in header macros
            size = codegen_util.recursive_dict_lookup(
                old_size, self.get_consts_and_enums())
            # Try to coerce the result to an int, return a string if this fails
            return codegen_util.try_coerce_to_num(size, try_types=(int, ))