# Path: fmodpy/parsing/util.py
# def pop_group(list_str, open_with="(", close_with=")"):
#     group = []
#     # Get the first element of the string (open the group, if matched).
#     if ((len(list_str) > 0) and (list_str[0] == open_with)):
#         list_str.pop(0)
#         num_open = 1
#     else: num_open = 0
#     # Search until the started group is closed.
#     while (num_open > 0):
#         # TOOD: Might need to raise parsing error when this happens.
#         if (len(list_str) == 0): raise(NotImplementedError)
#         next_value = list_str.pop(0)
#         if   (next_value == open_with):  num_open += 1
#         elif (next_value == close_with): num_open -= 1
#         if (num_open != 0): group.append(next_value)
#     # Return the captured portion and the remaining.
#     return group, list_str


from . import pop_group
        import re # <- use regular expressions to capture SIZE(...) syntax.
                import warnings
        for attr in dir(self):
            # Skip hidden attributes.
            if (attr[:1] == "_"): continue
            # TODO: Come up with better general way to handle these special cases.
            if (attr in {"c_type", "c_type_array", "py_type"}): continue
            value = getattr(self, attr)
            # Skip executable attributes.
            if (hasattr(value, "__call__")): continue
            # If this attribute has a ".copy" function, then use it.
            if (hasattr(value, "copy") and hasattr(value.copy, "__call__")):
                value = value.copy()
            # Set the attribute in the new argument.
            setattr(arg, attr, value)
        return arg
    

    # Default initialization, process standard Fortran specifications.
    # Expects to be given list of strings that comes from a declaration
    # line, but with the ":: name1, ..." stripped off the end.
    def __init__(self, line, parent=None):
        if (len(line) == 0): raise(NotImplementedError)
        # Make sure this line matches the expected type.
        if (line.pop(0) != self.type): raise(NotImplementedError)
        # Set the parent.
        self.parent = parent
        # If the line is empty now, then we're done (use defaults).
        if (len(line) == 0): return
        # Parse the remainder of the declaration line.
        # 
        # Get the KIND declaration, if it was given.

# Path: fmodpy/parsing/util.py
# def pop_group(list_str, open_with="(", close_with=")"):
#     group = []
#     # Get the first element of the string (open the group, if matched).
#     if ((len(list_str) > 0) and (list_str[0] == open_with)):
#         list_str.pop(0)
#         num_open = 1
#     else: num_open = 0
#     # Search until the started group is closed.
#     while (num_open > 0):
#         # TOOD: Might need to raise parsing error when this happens.
#         if (len(list_str) == 0): raise(NotImplementedError)
#         next_value = list_str.pop(0)
#         if   (next_value == open_with):  num_open += 1
#         elif (next_value == close_with): num_open -= 1
#         if (num_open != 0): group.append(next_value)
#     # Return the captured portion and the remaining.
#     return group, list_str


# Path: fmodpy/parsing/argument.py
from . import pop_group
        import re # <- use regular expressions to capture SIZE(...) syntax.
                import warnings

        for attr in dir(self):
            # Skip hidden attributes.
            if (attr[:1] == "_"): continue
            # TODO: Come up with better general way to handle these special cases.
            if (attr in {"c_type", "c_type_array", "py_type"}): continue
            value = getattr(self, attr)
            # Skip executable attributes.
            if (hasattr(value, "__call__")): continue
            # If this attribute has a ".copy" function, then use it.
            if (hasattr(value, "copy") and hasattr(value.copy, "__call__")):
                value = value.copy()
            # Set the attribute in the new argument.
            setattr(arg, attr, value)
        return arg
    

    # Default initialization, process standard Fortran specifications.
    # Expects to be given list of strings that comes from a declaration
    # line, but with the ":: name1, ..." stripped off the end.
    def __init__(self, line, parent=None):
        if (len(line) == 0): raise(NotImplementedError)
        # Make sure this line matches the expected type.
        if (line.pop(0) != self.type): raise(NotImplementedError)
        # Set the parent.
        self.parent = parent
        # If the line is empty now, then we're done (use defaults).
        if (len(line) == 0): return
        # Parse the remainder of the declaration line.
        # 
        # Get the KIND declaration, if it was given.

        group, line = pop_group(line)