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})
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, ))