# Fill out block comments to the full line length (currently 100).
#
# We're defining a "block comment" to be a multiline comment where each line
# begins with an alphabetic character.
#
# We also have some special logic to handle function description comments even
# though those don't conform to our definition of a "block comment".
import re, sys

# List of words in the current block comment.
words = []

# Whether we're inside a potential block comment.
multiline = False

# The maximum allowed line length.
line_length = 100

# How far to indent the current block comment.
indentation = 0

# Whether we're inside a function description comment. This is not a block
# comment by our definition but we want to fill these too.
function_desc = False

# Whether we've seen a line in the multiline comment to indicate that it is NOT
# a block comment. In that case don't use the refilling logic and just print the
# contents verbatim.
block = False

# The literal contents of the current block comment. If we realise halfway
# through the comment that it's not a block comment then we'll just print this
# out and pretend none of this ever happened.
comment = str()

for line in sys.stdin:
    sline = line.strip()
    # Beginning of a block comment.
    if sline == '/*':
        comment = line
        assert not multiline
        multiline = True
        block = True
        # Figure out how far we need to indent.
        indentation = 0
        for c in line:
            if c == ' ':
                indentation += 1
            elif c == '\t':
                indentation += 8
            else:
                break
    # End of a block comment.
    elif sline.endswith('*/'):
        comment += line
        # Don't mess with generated comments.
        # Scripts in dist rely on them to figure out where to generate code.
        if 'DO NOT EDIT' in comment:
            block = False
        if multiline and not block:
            sys.stdout.write(comment)
        elif multiline:
            indent_ws = ' ' * indentation
            sys.stdout.write('{}/*\n'.format(indent_ws))
            current_line = indent_ws + ' *'
            for i in range(len(words)):
                word = words[i]
                if word == '--' and function_desc:
                    sys.stdout.write(current_line + ' ' + word + '\n')
                    current_line = indent_ws + ' *' + ' ' * 4
                    continue
                if word == '\n':
                    # If we already have partially built a line, write it out.
                    if current_line != indent_ws + ' *':
                        sys.stdout.write(current_line + '\n')
                    # If there are more words in this comment after this
                    # newline, add another line break.
                    if i < (len(words) - 1):
                        sys.stdout.write(indent_ws + ' *' + '\n')
                    current_line = indent_ws + ' *'
                    continue
                if len(current_line) + len(word) >= line_length:
                    sys.stdout.write(current_line + '\n')
                    current_line = indent_ws + ' *'
                    if function_desc:
                        current_line += ' ' * 4
                current_line += ' ' + word
            sys.stdout.write(current_line + '\n')
            sys.stdout.write('{} */\n'.format(indent_ws))
        else:
            sys.stdout.write(line)
        block = False
        words = []
        multiline = False
        function_desc = False
    elif multiline:
        comment += line
        # We want to preserve newlines for block comments that have multiple paragraphs.
        if sline == '*':
            words.append('\n')
            continue
        # Function names begin with either a lowercase char or an underscore.
        if (len(sline) >= 3 and sline.startswith('*') and sline[1] == ' ' and
            (sline[2].islower() or sline[2] == '_') and sline.endswith('--')):
            function_desc = True
        # We're only reformatting block comments where each line begins with a space and an
        # alphabetic character after the asterisk, or a parenthetical. The only exceptions
        # are function descriptions.
        block = block and \
            len(sline) >= 3 and sline.startswith('*') and sline[1] == ' ' and \
            (sline[2].isalpha() or (len(sline) >= 5 and \
            (sline[2] == '(' and sline[3].isalpha() and sline[4] != ')'))) or function_desc
        # Trim asterisks at the beginning of each line in a multiline comment.
        if sline.startswith('*'):
            sline = sline[1:]
        # Might be trailing whitespace after the asterisk. Leading strip again.
        sline = sline.lstrip()
        words.extend(sline.split())
    else:
        sys.stdout.write(line)
