# Path: ronin/utils/strings.py
# def stringify(value):
#     """
#     Casts the value to a Unicode string. If the value is a function, calls it using
#     :func:`ronin.contexts.current_context` as its only argument, and recurses until a
#     non-FunctionType value is returned.
#     
#     None values are preserved, whether None is directly sent to this function or is the return
#     value of function argument.
#     
#     This function is the heart of Rōnin's deferred value capability, as it allows lambdas to be
#     passed around instead of strings.
#     
#     :param value: value or None
#     :type value: str|FunctionType
#     :returns: stringified value or None
#     :rtype: str
#     """
#     
#     if value is None:
#         return None
#     elif hasattr(value, '__call__'):
#         with current_context() as ctx:
#             value = value(ctx)
#         return stringify(value)
#     else:
#         try:
#             return to_str(value)
#         except UnicodeDecodeError:
#             return str(value).decode(_ENCODING)
# 
# def join_later(values, separator=' '):
#     """
#     Creates a lambda that calls :func:`stringify_list` and joins the results on ``separator``.
#     
#     :param values: values
#     :type values: []
#     :param separator: separator
#     :type separator: str|FunctionType
#     :returns: lambda returning the joined string
#     :rtype: FunctionType
#     """
#     
#     return lambda _: stringify(separator).join(stringify_list(values))
# 
# Path: ronin/utils/collections.py
# class StrictList(list):
#     """
#     A list that raises :class:`~exceptions.TypeError` exceptions when objects of the wrong type are
#     inserted.
#     
#     :param items: initial list
#     :type items: list
#     :param value_type: type(s) required for list values
#     :type value_type: :obj:`type` or :obj:`str` or (:obj:`type` or :obj:`str`)
#     :param wrapper_function: calls this optional function on all values before added to the list
#     :type wrapper_function: ~types.FunctionType
#     :param unwrapper_function: calls this optional function on all values when retrieved from the
#      list
#     :type unwrapper_function: ~types.FunctionType
#     """
# 
#     def __init__(self, items=None, value_type=None, wrapper_function=None, unwrapper_function=None):
#         super(StrictList, self).__init__()
#         if isinstance(items, StrictList):
#             self.value_type = items.value_type
#             self.wrapper_function = items.wrapper_function
#             self.unwrapper_function = items.unwrapper_function
#         self.value_type = _convert_type(value_type)
#         self.wrapper_function = wrapper_function
#         self.unwrapper_function = unwrapper_function
#         if items:
#             for item in items:
#                 self.append(item)
# 
#     def _wrap(self, value):
#         if (self.value_type is not None) and (not isinstance(value, self.value_type)):
#             raise TypeError('value must be a "{}": {!r}'.format(type_name(self.value_type), value))
#         if self.wrapper_function is not None:
#             value = self.wrapper_function(value)
#         return value
# 
#     def _unwrap(self, value):
#         if self.unwrapper_function is not None:
#             value = self.unwrapper_function(value)
#         return value
# 
#     def __getitem__(self, index):
#         value = super(StrictList, self).__getitem__(index)
#         value = self._unwrap(value)
#         return value
# 
#     def __setitem__(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).__setitem__(index, value)
# 
#     def __iadd__(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).__iadd__(values)
# 
#     def append(self, value):
#         value = self._wrap(value)
#         return super(StrictList, self).append(value)
# 
#     def extend(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).extend(values)
# 
#     def insert(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).insert(index, value)


from .utils.strings import stringify, join_later
from .utils.collections import StrictList
from io import StringIO
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import unicode_literals


class Executor(object):
    """
    Base class for executors.
    
    :ivar command: command
    :vartype command: str or ~types.FunctionType
    :ivar command_types: command types supported (used by extensions)
    :vartype command_types: [:obj:`str`]
    :ivar output_extension: when calculating outputs, change extension to this
    :vartype output_extension: str or ~types.FunctionType
    :ivar output_prefix: when calculating outputs, prefix this to filename
    :vartype output_prefix: str or ~types.FunctionType
    :ivar hooks: called when generating the Ninja file
    :vartype hooks: [:obj:`~types.FunctionType`]
    """
    
    def __init__(self):
        self.command = None
        self.command_types = StrictList(value_type=str)
        self.output_extension = None
        self.output_prefix = None
        self.output_type = 'binary'

# Path: ronin/utils/strings.py
# def stringify(value):
#     """
#     Casts the value to a Unicode string. If the value is a function, calls it using
#     :func:`ronin.contexts.current_context` as its only argument, and recurses until a
#     non-FunctionType value is returned.
#     
#     None values are preserved, whether None is directly sent to this function or is the return
#     value of function argument.
#     
#     This function is the heart of Rōnin's deferred value capability, as it allows lambdas to be
#     passed around instead of strings.
#     
#     :param value: value or None
#     :type value: str|FunctionType
#     :returns: stringified value or None
#     :rtype: str
#     """
#     
#     if value is None:
#         return None
#     elif hasattr(value, '__call__'):
#         with current_context() as ctx:
#             value = value(ctx)
#         return stringify(value)
#     else:
#         try:
#             return to_str(value)
#         except UnicodeDecodeError:
#             return str(value).decode(_ENCODING)
# 
# def join_later(values, separator=' '):
#     """
#     Creates a lambda that calls :func:`stringify_list` and joins the results on ``separator``.
#     
#     :param values: values
#     :type values: []
#     :param separator: separator
#     :type separator: str|FunctionType
#     :returns: lambda returning the joined string
#     :rtype: FunctionType
#     """
#     
#     return lambda _: stringify(separator).join(stringify_list(values))
# 
# Path: ronin/utils/collections.py
# class StrictList(list):
#     """
#     A list that raises :class:`~exceptions.TypeError` exceptions when objects of the wrong type are
#     inserted.
#     
#     :param items: initial list
#     :type items: list
#     :param value_type: type(s) required for list values
#     :type value_type: :obj:`type` or :obj:`str` or (:obj:`type` or :obj:`str`)
#     :param wrapper_function: calls this optional function on all values before added to the list
#     :type wrapper_function: ~types.FunctionType
#     :param unwrapper_function: calls this optional function on all values when retrieved from the
#      list
#     :type unwrapper_function: ~types.FunctionType
#     """
# 
#     def __init__(self, items=None, value_type=None, wrapper_function=None, unwrapper_function=None):
#         super(StrictList, self).__init__()
#         if isinstance(items, StrictList):
#             self.value_type = items.value_type
#             self.wrapper_function = items.wrapper_function
#             self.unwrapper_function = items.unwrapper_function
#         self.value_type = _convert_type(value_type)
#         self.wrapper_function = wrapper_function
#         self.unwrapper_function = unwrapper_function
#         if items:
#             for item in items:
#                 self.append(item)
# 
#     def _wrap(self, value):
#         if (self.value_type is not None) and (not isinstance(value, self.value_type)):
#             raise TypeError('value must be a "{}": {!r}'.format(type_name(self.value_type), value))
#         if self.wrapper_function is not None:
#             value = self.wrapper_function(value)
#         return value
# 
#     def _unwrap(self, value):
#         if self.unwrapper_function is not None:
#             value = self.unwrapper_function(value)
#         return value
# 
#     def __getitem__(self, index):
#         value = super(StrictList, self).__getitem__(index)
#         value = self._unwrap(value)
#         return value
# 
#     def __setitem__(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).__setitem__(index, value)
# 
#     def __iadd__(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).__iadd__(values)
# 
#     def append(self, value):
#         value = self._wrap(value)
#         return super(StrictList, self).append(value)
# 
#     def extend(self, values):
#         values = [self._wrap(v) for v in values]
#         return super(StrictList, self).extend(values)
# 
#     def insert(self, index, value):
#         value = self._wrap(value)
#         return super(StrictList, self).insert(index, value)


# Path: ronin/executors.py
from .utils.strings import stringify, join_later
from .utils.collections import StrictList
from io import StringIO

# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import unicode_literals


class Executor(object):
    """
    Base class for executors.
    
    :ivar command: command
    :vartype command: str or ~types.FunctionType
    :ivar command_types: command types supported (used by extensions)
    :vartype command_types: [:obj:`str`]
    :ivar output_extension: when calculating outputs, change extension to this
    :vartype output_extension: str or ~types.FunctionType
    :ivar output_prefix: when calculating outputs, prefix this to filename
    :vartype output_prefix: str or ~types.FunctionType
    :ivar hooks: called when generating the Ninja file
    :vartype hooks: [:obj:`~types.FunctionType`]
    """
    
    def __init__(self):
        self.command = None
        self.command_types = StrictList(value_type=str)
        self.output_extension = None
        self.output_prefix = None
        self.output_type = 'binary'

        self.hooks = StrictList(value_type='types.FunctionType')