Unicode aware version of curses's built-in addnstr method.

        Safely draws a line of text on the window starting at position
        (row, col). Checks the boundaries of the window and cuts off the text
        if it exceeds the length of the window.

def add_line(self, window, text, row=None, col=None, attr=None):
        """
        Unicode aware version of curses's built-in addnstr method.

        Safely draws a line of text on the window starting at position
        (row, col). Checks the boundaries of the window and cuts off the text
        if it exceeds the length of the window.
        """

        # The following arg combos must be supported to conform with addnstr
        # (window, text)
        # (window, text, attr)
        # (window, text, row, col)
        # (window, text, row, col, attr)
        cursor_row, cursor_col = window.getyx()
        row = row if row is not None else cursor_row
        col = col if col is not None else cursor_col

        max_rows, max_cols = window.getmaxyx()
        n_cols = max_cols - col - 1
        if n_cols <= 0:
            # Trying to draw outside of the screen bounds
            return

        try:
            text = self.clean(text, n_cols)
            params = [] if attr is None else [attr]
            window.addstr(row, col, text, *params)
        except (curses.error, ValueError, TypeError) as e:
            # Curses handling of strings with invalid null bytes (b'\00')
            #   python 2: TypeError: "int,int,str"
            #   python 3: ValueError: "embedded null byte"
            _logger.warning('add_line raised an exception')
            _logger.exception(str(e))