#!/usr/bin/env python3

# Copyright 2018 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT
"""
This tool uses the contents of the kazoo-generated syscalls/definitions.json
to update docs/syscalls/.

It is not run automatically as part of the build for now (to allow confirmation
of what it does). So it should be run manually after updating //zircon/vdso
and building zircon, followed by uploading the changes to docs/ as a CL. (It
will attempt to do a build if it appears that definitions.json is out-of-date
with respect to the syscall fidl.)

It updates the signature, synopsis, and rights annotations, and corrects some
formatting.
"""

import argparse
import json
import os
import re
import subprocess
import sys

SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))

STANDARD_COMMENT = '<!-- Updated by update-docs-from-fidl, do not edit. -->'
STANDARD_BLOCK_HEADER = ['', STANDARD_COMMENT, '']

REFERENCES_COMMENT = \
        '<!-- References updated by update-docs-from-fidl, do not edit. -->'

SYSCALLS_FIDL_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, os.pardir,
                                                  'vdso'))


def parse_args():
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument(
        '--builddir',
        default=os.path.join('out','default'),
        help='overrides default build directory if set')
    parser.add_argument('--json',
                        default=None,
                        help='path to kazoo .json output')
    parser.add_argument('--docroot',
                        default=os.path.normpath(
                            os.path.join(SCRIPT_DIR, os.pardir, os.pardir,
                                         'docs', 'reference', 'syscalls')),
                        help='root of syscalls/ to be updated')
    parser.add_argument(
        '--generate-missing',
        default=False,
        action="store_true",
        help='if set, generate stubs for any syscalls that are missing')
    parser.add_argument('name', nargs='*', help='only generate these syscalls')
    return parser.parse_args()


def break_into_sentences(stream):
    """Partition on '.' to break into chunks. '.' can't appear elsewhere
    in the input stream."""
    sentences = []
    cur = []
    for tok in stream:
        cur.append(tok)
        if tok == '.':
            sentences.append(cur)
            cur = []
    assert not cur, cur
    return sentences


def match_sentence_form(sentence, arg_names):
    """Matches a known sentence form, returning a format string and a dict for
    substitution. The values in dict are converted to markdown format.

    Certain TERMINALS are special:
    - ARG must appear in arg_names
    - RIGHT must be a valid ZX_RIGHT_
    - TYPE must be a valid ZX_OBJ_TYPE_
    - RSRC must be a valid ZX_RSRC_KIND_

    VALUE is a generic unchecked value type, used for masks, options, etc.
    """
    sentence_forms = [
        ['None', '.'],
        ['ARG', 'must', 'have', 'RIGHT', '.'],
        ['ARG', 'must', 'have', 'RIGHT1', 'and', 'have', 'RIGHT2', '.'],
        [
            'ARG', 'must', 'have', 'RIGHT1', 'and', 'have', 'RIGHT2', 'and',
            'have', 'RIGHT3', '.'
        ],
        [
            'ARG', 'must', 'have', 'RIGHT1', 'and', 'have', 'RIGHT2', 'and',
            'have', 'RIGHT3', 'and', 'have', 'RIGHT4', '.'
        ],
        ['ARG', 'must', 'have', 'resource', 'kind', 'RSRC', '.'],
        ['ARG', 'must', 'be', 'of', 'type', 'TYPE', '.'],
        [
            'ARG', 'must', 'be', 'of', 'type', 'TYPE', 'and', 'have', 'RIGHT1',
            'and', 'have', 'RIGHT2', '.'
        ],
        [
            'ARG', 'must', 'be', 'of', 'type', 'TYPE', 'and', 'have', 'RIGHT',
            '.'
        ],
        [
            'ARG', 'must', 'be', 'of', 'type', 'TYPE', 'and', 'have', 'RIGHT',
            'or', 'have', 'RIGHT', '.'
        ],
        [
            'ARG', 'must', 'be', 'of', 'type', 'TYPE1', 'or', 'TYPE2', 'and',
            'have', 'RIGHT', '.'
        ],
        [
            'If', 'ARG', 'is', 'of', 'type', 'TYPE1', 'or', 'TYPE2', ',', 'it',
            'must', 'have', 'RIGHT', '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'have', 'RIGHT',
            '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'have',
            'resource', 'kind', 'RSRC', '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'be', 'of',
            'type', 'TYPE', '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'be', 'of',
            'type', 'TYPE', 'and', 'have', 'RIGHT', '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'be', 'of',
            'type', 'TYPE1', ',', 'TYPE2', ',', 'or', 'TYPE3', ',', 'and', 'have', 'RIGHT', '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'be', 'of',
            'type', 'TYPE', 'and', 'have', 'RIGHT1', 'and', 'RIGHT2', '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'be', 'of',
            'type', 'TYPE', 'and', 'have', 'RIGHT1', 'and', 'RIGHT2', 'and',
            'RIGHT3', '.'
        ],
        [
            'If', 'ARG1', '&', 'VALUE', ',', 'ARG2', 'must', 'be', 'of', 'type',
            'TYPE', 'and', 'have', 'RIGHT', '.'
        ],
        ['Every', 'entry', 'of', 'ARG', 'must', 'have', 'RIGHT', '.'],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'affected', 'mappings', 'must',
            'be', 'writable', '.'
        ],
        [
            'Every', 'entry', 'of', 'ARG', 'must', 'have', 'a',
            'WAITITEMMEMBER', 'field', 'with', 'RIGHT', '.'
        ],

        # TODO(fxbug.dev/32253) TODO(scottmg): This is a hack specifically for
        # zx_channel_call_args_t. Trying to make a pseudo-generic case (that
        # handles the length from wr_num_handles, etc.) for this doesn't seem
        # worth the trouble at the moment, since it's only checking that the
        # handles have TRANSFER anyway. Revisit if/when there's more instances
        # like this.
        ['All', 'wr_handles', 'of', 'ARG', 'must', 'have', 'RIGHT', '.'],
    ]

    all_rights = set([
        'ZX_RIGHT_NONE',
        'ZX_RIGHT_DUPLICATE',
        'ZX_RIGHT_TRANSFER',
        'ZX_RIGHT_READ',
        'ZX_RIGHT_WRITE',
        'ZX_RIGHT_EXECUTE',
        'ZX_RIGHT_MAP',
        'ZX_RIGHT_GET_PROPERTY',
        'ZX_RIGHT_SET_PROPERTY',
        'ZX_RIGHT_ENUMERATE',
        'ZX_RIGHT_DESTROY',
        'ZX_RIGHT_SET_POLICY',
        'ZX_RIGHT_GET_POLICY',
        'ZX_RIGHT_SIGNAL',
        'ZX_RIGHT_SIGNAL_PEER',
        'ZX_RIGHT_WAIT',
        'ZX_RIGHT_INSPECT',
        'ZX_RIGHT_MANAGE_JOB',
        'ZX_RIGHT_MANAGE_PROCESS',
        'ZX_RIGHT_MANAGE_THREAD',
        'ZX_RIGHT_APPLY_PROFILE',
    ])

    all_types = set([
        'ZX_OBJ_TYPE_BTI',
        'ZX_OBJ_TYPE_CHANNEL',
        'ZX_OBJ_TYPE_CLOCK',
        'ZX_OBJ_TYPE_EVENT',
        'ZX_OBJ_TYPE_EVENTPAIR',
        'ZX_OBJ_TYPE_EXCEPTION',
        'ZX_OBJ_TYPE_FIFO',
        'ZX_OBJ_TYPE_GUEST',
        'ZX_OBJ_TYPE_INTERRUPT',
        'ZX_OBJ_TYPE_IOMMU',
        'ZX_OBJ_TYPE_JOB',
        'ZX_OBJ_TYPE_LOG',
        'ZX_OBJ_TYPE_MSI',
        'ZX_OBJ_TYPE_PAGER',
        'ZX_OBJ_TYPE_PCI_DEVICE',
        'ZX_OBJ_TYPE_PMT',
        'ZX_OBJ_TYPE_PORT',
        'ZX_OBJ_TYPE_PROCESS',
        'ZX_OBJ_TYPE_PROFILE',
        'ZX_OBJ_TYPE_RESOURCE',
        'ZX_OBJ_TYPE_SOCKET',
        'ZX_OBJ_TYPE_STREAM',
        'ZX_OBJ_TYPE_SUSPEND_TOKEN',
        'ZX_OBJ_TYPE_THREAD',
        'ZX_OBJ_TYPE_TIMER',
        'ZX_OBJ_TYPE_VCPU',
        'ZX_OBJ_TYPE_VMAR',
        'ZX_OBJ_TYPE_VMO',
    ])

    all_rsrcs = set([
        'ZX_RSRC_KIND_MMIO',
        'ZX_RSRC_KIND_IRQ',
        'ZX_RSRC_KIND_IOPORT',
        'ZX_RSRC_KIND_HYPERVISOR',
        'ZX_RSRC_KIND_ROOT',
        'ZX_RSRC_KIND_VMEX',
        'ZX_RSRC_KIND_SMC',
    ])

    # There's only two structs in zircon/types.h, so hardcoding this here is
    # a bit stinky, but probably OK.
    members_of_zx_wait_item_t = set([
        'handle',
        'waitfor',
        'pending',
    ])

    for form in sentence_forms:
        result_fmt = ''
        result_values = {}
        for f, s in zip(form, sentence):
            # Literal match.
            if s == f:
                if f == '.' or f == ',' or f == '->':
                    result_fmt += f
                elif f == '[':
                    result_fmt += '\['
                else:
                    result_fmt += ' ' + f
            elif f.startswith('ARG'):
                if s not in arg_names:
                    break
                else:
                    result_values[f] = '*' + s + '*'
                    result_fmt += ' %(' + f + ')s'
            elif f.startswith('VALUE'):
                # TODO(scottmg): Worth checking these in some way?
                result_fmt += ' %(' + f + ')s'
                result_values[f] = '**' + s + '**'
            elif f.startswith('RIGHT'):
                if s not in all_rights:
                    break
                result_fmt += ' %(' + f + ')s'
                result_values[f] = '**' + s + '**'
            elif f.startswith('RSRC'):
                if s not in all_rsrcs:
                    break
                result_fmt += ' %(' + f + ')s'
                result_values[f] = '**' + s + '**'
            elif f.startswith('TYPE'):
                if s not in all_types:
                    break
                result_fmt += ' %(' + f + ')s'
                result_values[f] = '**' + s + '**'
            elif f.startswith('WAITITEMMEMBER'):
                if s not in members_of_zx_wait_item_t:
                    break
                result_fmt += ' %(' + f + ')s'
                result_values[f] = '*' + s + '*'
            else:
                break
        else:
            if result_fmt[0] == ' ':
                result_fmt = result_fmt[1:]
            return result_fmt, result_values
    else:
        return None, None


def to_markdown(req, arguments, warn):
    """Parses a few known forms of rules (see match_sentence_forms).

    Converts |req| to formatted markdown.
    """
    sentences = break_into_sentences(req)

    if not sentences:
        rights = ['TODO(fxbug.dev/32253)', '']
    else:
        rights = []
    for sentence in sentences:
        match_fmt, match_values = match_sentence_form(
            sentence, [x['name'] for x in arguments])
        if not match_fmt:
            warn('failed to parse: ' + repr(sentence))
            raise SystemExit(1)
        else:
            rights.append(match_fmt % match_values)
            rights.append('')

    return STANDARD_BLOCK_HEADER + rights


def find_block(lines, name):
    """Finds a .md block with the given name, and returns (start, end) line
    indices.
    """
    start_index = -1
    end_index = -1
    for i, line in enumerate(lines):
        if line == '## ' + name:
            start_index = i + 1
        elif ((start_index >= 0 and line.startswith('## ')) or
              line == REFERENCES_COMMENT):
            end_index = i
            break
    return start_index, end_index


def update_rights(lines, syscall_data, warn):
    """Updates the RIGHTS block of the .md file in lines.
    """
    rights_start_index, rights_end_index = find_block(lines, 'RIGHTS')
    if rights_start_index == -1 or rights_end_index == -1:
        warn('did not find RIGHTS section, skipping update')
        return

    lines[rights_start_index:rights_end_index] = to_markdown(
        syscall_data['requirements'], syscall_data['arguments'], warn)


def make_name_block(syscall_data, warn):
    desc = ''
    for x in syscall_data['top_description']:
        # TODO(scottmg): This is gross, we should change the output to give us a
        # string instead of tokens.
        if x in (',', '.', '-', '/', '\'', ')'):
            desc += x
        else:
            if desc and desc[-1] not in ('-', '/', '\'', '('):
                desc += ' '
            desc += x
    if not desc:
        desc = 'TODO(fxbug.dev/32938)'
    else:
        if desc[0].upper() != desc[0]:
            warn('short description (#^) should start with a capital')
        if desc[-1] != '.':
            warn('short description (#^) should end with a period')
    return STANDARD_BLOCK_HEADER + [desc, '']


def update_name(lines, syscall_data, warn):
    """Updates the NAME block of the .md file in lines.
    """
    name_start_index, name_end_index = find_block(lines, 'NAME')
    if name_start_index == -1 or name_end_index == -1:
        warn('did not find NAME section, skipping update')
        return

    lines[name_start_index:name_end_index] = make_name_block(syscall_data, warn)


def make_synopsis_block(syscall_data, warn):
    # Construct a synopsis block of the form:
    #
    #   ```c
    #   #include <zircon/syscalls.h>
    #
    #   zx_status_t zx_syscall_xxx(int32_t p1, int32_t p2);
    #   ```
    headers = set([
        '#include <zircon/syscalls.h>',
    ])
    extra_headers = {}
    for arg in syscall_data['arguments']:
        if arg['type'] == 'zx_port_packet_t':
            headers.add('#include <zircon/syscalls/port.h>')
        elif (arg['type'] == 'zx_smc_parameters_t' or
              arg['type'] == 'zx_smc_result_t'):
            headers.add('#include <zircon/syscalls/smc.h>')
    header = ['```c'] + sorted(list(headers)) + ['']

    def format_arg(x):
        ret = ''
        if 'IN' in x['attributes']:
            ret += 'const '
        if x['type'] == 'any':
            ret += 'void '
        else:
            ret += x['type'] + ' '
        if x['is_array']:
            ret += ' * '
        ret += ' ' + x['name']
        return ret

    no_return = ''
    if 'noreturn' in syscall_data['attributes']: no_return = '[[noreturn]]'

    to_format = (no_return + syscall_data['return_type'] + ' zx_' +
                 syscall_data['name'] + '(')
    args = ','.join(format_arg(x) for x in syscall_data['arguments'])
    if not args:
        args = 'void'
    to_format += args + ');'

    CLANG_FORMAT_PATH = os.path.join(SCRIPT_DIR, os.pardir, os.pardir,
                                     'prebuilt', 'third_party', 'clang',
                                     'linux-x64', 'bin', 'clang-format')
    clang_format = subprocess.Popen([
        CLANG_FORMAT_PATH,
        '-style={BasedOnStyle: Google, BinPackParameters: false}'
    ],
                                    stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE)
    formatted, _ = clang_format.communicate(to_format.encode('utf-8'))
    if clang_format.returncode != 0:
        warn('formatting synopsis failed, skipping update')
        return None

    footer = [
        '```',
        '',
    ]
    return STANDARD_BLOCK_HEADER + header + [formatted.decode('utf-8')] + footer


def update_synopsis(lines, syscall_data, warn):
    """Updates the SYNOPSIS block of the .md file in lines.
    """
    start_index, end_index = find_block(lines, 'SYNOPSIS')
    if start_index == -1 or end_index == -1:
        warn('did not find SYNOPSIS section, skipping update')
        return

    syn = make_synopsis_block(syscall_data, warn)
    if not syn:
        return
    lines[start_index:end_index] = syn


def update_title(lines, syscall_data, _):
    """Updates the main title of the .md file given by |filename|.
    """
    correct_title = '# zx_' + syscall_data['name']
    if lines[0] != correct_title:
        lines[0] = correct_title


def generate_stub(md):
    """Makes a mostly-empty file that can then be filled out by later update
    functions."""

    stub = '''\
# zx_xyz

## NAME

## SYNOPSIS

## DESCRIPTION

TODO(fxbug.dev/32938)

## RIGHTS

## RETURN VALUE

TODO(fxbug.dev/32938)

## ERRORS

TODO(fxbug.dev/32938)

## SEE ALSO

TODO(fxbug.dev/32938)
'''
    with open(md, 'wb') as f:
        f.write(stub)


def check_for_orphans(syscalls, root):
    """Checks for any .md files that have been orphaned (no longer have an
    associated syscalls file entry.)
    """
    orphan_count = 0
    names = set([x['name'] for x in syscalls])
    for md in os.listdir(root):
        if md == '_toc.yaml':
            continue
        if md == 'README.md':
            continue
        if not md.endswith('.md'):
            print('warning: non .md file %s' % md, file=sys.stderr)
        name = md[:-3]
        if name not in names:
            orphan_count += 1
            print('warning: %s has no entry in syscalls' % md, file=sys.stderr)
    return orphan_count


# A few concept docs that are linked in SEE ALSO sections.
SEE_ALSO_CONCEPTS = {
    'clock transformations': '/docs/concepts/kernel/clock_transformations.md',
    'clocks': '/docs/reference/kernel_objects/clock.md',
    'exceptions': '/docs/concepts/kernel/exceptions.md',
    'futex objects': '/docs/reference/kernel_objects/futex.md',
    'kernel command line': '/docs/reference/kernel/kernel_cmdline.md',
    'rights': '/docs/concepts/kernel/rights.md',
    'signals': '/docs/concepts/kernel/signals.md',
    'timer slack': '/docs/concepts/kernel/timer_slack.md',
}


def make_see_also_block(referenced_syscalls, concepts, extra):
    """Makes a formatted SEE ALSO block given a list of syscall names.
    """
    result = []

    for concept in sorted(concepts):
        result.append(' - [' + concept + ']')

    for sc in sorted(referenced_syscalls):
        # References to these will be done later by update_syscall_references().
        result.append(' - [`zx_' + sc + '()`]')

    if extra:
        extra += ['']

    # No comment header here, because people are still editing this by hand,
    # we're only canonicalizing it.
    return [''] + extra + result + ['']


def update_seealso(lines, syscall, all_syscall_names, warn):
    """Rewrites 'SEE ALSO' block to canonical format.
    """
    concepts = set()

    start_index, end_index = find_block(lines, 'SEE ALSO')
    if start_index == -1:
        return concepts

    referenced = set()
    extra = []
    for line in lines[start_index:end_index]:
        if not line or line == STANDARD_COMMENT:
            continue

        handled = False
        for concept in SEE_ALSO_CONCEPTS:
            if '[' + concept + ']' in line:
                concepts.add(concept)
                handled = True
        if handled:
            continue

        for sc in all_syscall_names:
            old = '[' + sc + ']'
            new = '[`zx_' + sc + '()`]'
            if old in line or new in line:
                referenced.add(sc)
                break
        else:
            warn('unrecognized "see also", keeping before syscalls: ' + line)
            extra.append(line)

    lines[start_index:end_index] = make_see_also_block(referenced, concepts,
                                                       extra)
    return concepts


SYSCALL_RE = {}


def update_syscall_references(lines, syscall, all_syscall_names, concepts, warn):
    """Attempts to update all syscall references to a canonical format, and
    linkifies them to their corresponding syscall.

    TODO(fxbug.dev/32938): It'd be nice to do the references from outside of
    docs/syscalls/ into syscalls too, in a similar style.
    """

    text = '\n'.join(lines)

    # Precompile these regexes as it takes measurable time.
    if not SYSCALL_RE:
        for sc in all_syscall_names:
            # Look for **zx_stuff()** and [`zx_stuff()`], with both "zx_" and
            # the () being optional.
            SYSCALL_RE[sc] = re.compile(r'\*{2}(?:zx_)?' + sc +
                                        r'(?:\(\))?\*{2}(?:\(\))?'
                                        r'|'
                                        r'(?:\[)`(?:zx_)?' + sc +
                                        r'(?:\(\))?`(?:\])?(\(\))?')

    referred_to = set()
    for sc in all_syscall_names:
        scre = SYSCALL_RE[sc]
        self = sc == syscall['name']
        repl = '`zx_' + sc + '()`'
        # Don't link to ourselves.
        if not self:
            repl = '[' + repl + ']'
        text, count = scre.subn(repl, text)
        if count and not self:
            referred_to.add(sc)

    lines[:] = text.splitlines()

    if REFERENCES_COMMENT not in lines:
        lines.extend(['', REFERENCES_COMMENT])
    start_index = lines.index(REFERENCES_COMMENT)

    references = []
    for concept in sorted(concepts):
        references.append('[' + concept + ']: ' + SEE_ALSO_CONCEPTS[concept])
    for ref in sorted(referred_to):
        references.append('[`zx_' + ref + '()`]: ' + ref + '.md')
    lines[start_index:] = [REFERENCES_COMMENT, ''] + references

    # Drop references section if it's empty to not be noisy.
    if lines[-3:] == ['', REFERENCES_COMMENT, '']:
        lines[:] = lines[:-3]


def build_if_out_of_date(syscalls_dir, build_dir, json):
    """If the json file appears out-of-date relative to any files in the
    syscalls dir, then run a zircon build to get the definitions updated.
    """

    def is_up_to_date(input, output):
        """Checks if output exists and is newer-or-equal in mtime to input."""
        if not os.path.isfile(output):
            return False
        input_time = os.path.getmtime(input)
        output_time = os.path.getmtime(output)
        return output_time >= input_time

    for f in os.listdir(syscalls_dir):
        if not f.endswith('.fidl'):
            continue
        syscall = os.path.join(syscalls_dir, f)
        if not os.path.isfile(syscall):
            continue
        if not is_up_to_date(syscall, json):
            print(
                '%s out of date vs %s, running `fx build`\n'
                'This will only work if using out/default (or --builddir is set) '
                'and configured for x64.' % (json, syscall))
            subprocess.check_call(
                [
                    'fx',
                    '--dir=%s' % (build_dir), 'build', '-C',
                    build_dir,
                    os.path.relpath(json, build_dir),
                ])
            if not is_up_to_date(syscall, json):
                print('%s still out of date relative to %s!' % (json, syscall))
                raise SystemExit()
            break


def main():
    args = parse_args()
    # Need to construct the default json path here so that we can use any
    # configured build directory.
    if args.json:
        json_path = args.json
    else:
        json_path = os.path.normpath(
            os.path.join(
                SCRIPT_DIR, os.pardir, os.pardir, args.builddir, 'gen',
                'include', 'zircon', 'syscalls', 'definitions.json'))
    inf = os.path.relpath(json_path)
    outf = os.path.relpath(args.docroot)
    build_if_out_of_date(
        os.path.relpath(SYSCALLS_FIDL_DIR), args.builddir, json_path)
    print('using %s as input and updating %s...' % (inf, outf))
    data = json.load(open(inf, 'rb'))
    missing_count = 0
    all_syscall_names = set(x['name'] for x in data['syscalls'])
    for syscall in data['syscalls']:
        if 'internal' in syscall['attributes']:
            # Don't generate documentation for syscalls tagged as internal.
            continue
        name = syscall['name']
        if args.name and name not in args.name:
            continue
        md = os.path.join(outf, name + '.md')

        if not os.path.exists(md) and args.generate_missing:
            generate_stub(md)

        if not os.path.exists(md):
            print('warning: %s not found for updating, skipping update' % md, file=sys.stderr)
            missing_count += 1
        else:
            with open(md, 'r') as f:
              lines = f.read().splitlines()

            assert (lines)

            def warn(msg):
                print('warning: %s: %s' % (md, msg), file=sys.stderr)

            update_title(lines, syscall, warn)
            update_name(lines, syscall, warn)
            update_synopsis(lines, syscall, warn)
            update_rights(lines, syscall, warn)
            concepts = update_seealso(lines, syscall, all_syscall_names, warn)
            update_syscall_references(lines, syscall, all_syscall_names, concepts, warn)

            with open(md, 'w') as f:
                f.write('\n'.join(lines) + '\n')

    if missing_count > 0:
        print('warning: %d missing .md files' % missing_count, file=sys.stderr)
    missing_count += check_for_orphans(data['syscalls'], outf)
    return missing_count


if __name__ == '__main__':
    sys.exit(main())
