Blame telepathy-account-widgets/tools/make-version-script.py

Packit Service c6b9b0
#!/usr/bin/python
Packit Service c6b9b0
Packit Service c6b9b0
"""Construct a GNU ld or Debian dpkg version-script from a set of
Packit Service c6b9b0
RFC822-style symbol lists.
Packit Service c6b9b0
Packit Service c6b9b0
Usage:
Packit Service c6b9b0
    make-version-script.py [--symbols SYMBOLS] [--unreleased-version VER]
Packit Service c6b9b0
        [--dpkg "LIBRARY.so.0 LIBRARY0 #MINVER#"]
Packit Service c6b9b0
        [--dpkg-build-depends-package LIBRARY-dev]
Packit Service c6b9b0
        [FILES...]
Packit Service c6b9b0
Packit Service c6b9b0
Each FILE starts with RFC822-style headers "Version:" (the name of the
Packit Service c6b9b0
symbol version, e.g. FOO_1.2.3) and "Extends:" (either the previous
Packit Service c6b9b0
version, or "-" if this is the first version). Next there is a blank
Packit Service c6b9b0
line, then a list of C symbols one per line.
Packit Service c6b9b0
Packit Service c6b9b0
Comments (lines starting with whitespace + "#") are allowed and ignored.
Packit Service c6b9b0
Packit Service c6b9b0
If --symbols is given, SYMBOLS lists the symbols actually exported by
Packit Service c6b9b0
the library (one per line). If --unreleased-version is given, any symbols
Packit Service c6b9b0
in SYMBOLS but not in FILES are assigned to that version; otherwise, any
Packit Service c6b9b0
such symbols cause an error.
Packit Service c6b9b0
Packit Service c6b9b0
If --dpkg is given, produce a Debian dpkg-gensymbols file instead of a
Packit Service c6b9b0
GNU ld version-script. The argument to --dpkg is the first line of the
Packit Service c6b9b0
resulting symbols file, and --dpkg-build-depends-package can optionally
Packit Service c6b9b0
be used to set the Build-Depends-Package field.
Packit Service c6b9b0
Packit Service c6b9b0
This script originates in telepathy-glib <http://telepathy.freedesktop.org/> -
Packit Service c6b9b0
please send us any changes that are needed.
Packit Service c6b9b0
"""
Packit Service c6b9b0
Packit Service c6b9b0
# Copyright (C) 2008-2010 Collabora Ltd. <http://www.collabora.co.uk/>
Packit Service c6b9b0
# Copyright (C) 2008 Nokia Corporation
Packit Service c6b9b0
#
Packit Service c6b9b0
# Copying and distribution of this file, with or without modification,
Packit Service c6b9b0
# are permitted in any medium without royalty provided the copyright
Packit Service c6b9b0
# notice and this notice are preserved.
Packit Service c6b9b0
Packit Service c6b9b0
import sys
Packit Service c6b9b0
from getopt import gnu_getopt
Packit Service c6b9b0
Packit Service c6b9b0
Packit Service c6b9b0
def e(format, *args):
Packit Service c6b9b0
    sys.stderr.write((format + '\n') % args)
Packit Service c6b9b0
Packit Service c6b9b0
Packit Service c6b9b0
def main(abifiles, symbols=None, unreleased_version=None,
Packit Service c6b9b0
         dpkg=False, dpkg_first_line=None, dpkg_build_depends_package=None):
Packit Service c6b9b0
Packit Service c6b9b0
    gnuld = not dpkg
Packit Service c6b9b0
    symbol_set = None
Packit Service c6b9b0
Packit Service c6b9b0
    if symbols is not None:
Packit Service c6b9b0
        symbol_set = open(symbols, 'r').readlines()
Packit Service c6b9b0
        symbol_set = map(str.strip, symbol_set)
Packit Service c6b9b0
        symbol_set = set(symbol_set)
Packit Service c6b9b0
Packit Service c6b9b0
    versioned_symbols = set()
Packit Service c6b9b0
Packit Service c6b9b0
    dpkg_symbols = []
Packit Service c6b9b0
    dpkg_versions = []
Packit Service c6b9b0
Packit Service c6b9b0
    if dpkg:
Packit Service c6b9b0
        assert dpkg_first_line is not None
Packit Service c6b9b0
        print(dpkg_first_line)
Packit Service c6b9b0
        if dpkg_build_depends_package is not None:
Packit Service c6b9b0
            print("* Build-Depends-Package: %s" % dpkg_build_depends_package)
Packit Service c6b9b0
Packit Service c6b9b0
    for filename in abifiles:
Packit Service c6b9b0
        lines = open(filename, 'r').readlines()
Packit Service c6b9b0
Packit Service c6b9b0
        version = None
Packit Service c6b9b0
        extends = None
Packit Service c6b9b0
        release = None
Packit Service c6b9b0
Packit Service c6b9b0
        for i, line in enumerate(lines):
Packit Service c6b9b0
            line = line.strip()
Packit Service c6b9b0
Packit Service c6b9b0
            if line.startswith('#'):
Packit Service c6b9b0
                continue
Packit Service c6b9b0
            elif not line:
Packit Service c6b9b0
                # the transition betwen headers and symbols
Packit Service c6b9b0
                cut = i + 1
Packit Service c6b9b0
                break
Packit Service c6b9b0
            elif line.lower().startswith('version:'):
Packit Service c6b9b0
                line = line[8:].strip()
Packit Service c6b9b0
                version = line
Packit Service c6b9b0
                continue
Packit Service c6b9b0
            elif line.lower().startswith('extends:'):
Packit Service c6b9b0
                line = line[8:].strip()
Packit Service c6b9b0
                extends = line
Packit Service c6b9b0
                continue
Packit Service c6b9b0
            elif line.lower().startswith('release:'):
Packit Service c6b9b0
                release = line[8:].strip()
Packit Service c6b9b0
                continue
Packit Service c6b9b0
            else:
Packit Service c6b9b0
                e('Could not understand line in %s header: %s', filename, line)
Packit Service c6b9b0
                raise SystemExit(1)
Packit Service c6b9b0
Packit Service c6b9b0
        else:
Packit Service c6b9b0
            e('No symbols in %s', filename)
Packit Service c6b9b0
            raise SystemExit(1)
Packit Service c6b9b0
Packit Service c6b9b0
        if version is None:
Packit Service c6b9b0
            e('No Versions: header in %s', filename)
Packit Service c6b9b0
            raise SystemExit(1)
Packit Service c6b9b0
Packit Service c6b9b0
        if extends is None:
Packit Service c6b9b0
            e('No Extends: header in %s', filename)
Packit Service c6b9b0
            raise SystemExit(1)
Packit Service c6b9b0
Packit Service c6b9b0
        if release is None and dpkg:
Packit Service c6b9b0
            e('No Release: header in %s', filename)
Packit Service c6b9b0
            raise SystemExit(1)
Packit Service c6b9b0
Packit Service c6b9b0
        if dpkg:
Packit Service c6b9b0
            dpkg_versions.append('%s@%s %s' % (version, version, release))
Packit Service c6b9b0
Packit Service c6b9b0
        lines = lines[cut:]
Packit Service c6b9b0
Packit Service c6b9b0
        if gnuld:
Packit Service c6b9b0
            print("%s {" % version)
Packit Service c6b9b0
            print("    global:")
Packit Service c6b9b0
Packit Service c6b9b0
        for symbol in lines:
Packit Service c6b9b0
            symbol = symbol.strip()
Packit Service c6b9b0
Packit Service c6b9b0
            if symbol.startswith('#'):
Packit Service c6b9b0
                continue
Packit Service c6b9b0
Packit Service c6b9b0
            if gnuld:
Packit Service c6b9b0
                print("        %s;" % symbol)
Packit Service c6b9b0
            elif dpkg:
Packit Service c6b9b0
                dpkg_symbols.append('%s@%s %s' % (symbol, version, release))
Packit Service c6b9b0
Packit Service c6b9b0
            if symbol in versioned_symbols:
Packit Service c6b9b0
                raise AssertionError('Symbol %s is in version %s and an '
Packit Service c6b9b0
                                     'earlier version' % (symbol, version))
Packit Service c6b9b0
Packit Service c6b9b0
            versioned_symbols.add(symbol)
Packit Service c6b9b0
Packit Service c6b9b0
        if gnuld:
Packit Service c6b9b0
            if extends == '-':
Packit Service c6b9b0
                print("    local:")
Packit Service c6b9b0
                print("        *;")
Packit Service c6b9b0
                print("};")
Packit Service c6b9b0
            else:
Packit Service c6b9b0
                print("} %s;" % extends)
Packit Service c6b9b0
                print("")
Packit Service c6b9b0
Packit Service c6b9b0
    if dpkg:
Packit Service c6b9b0
        dpkg_symbols.sort()
Packit Service c6b9b0
        dpkg_versions.sort()
Packit Service c6b9b0
Packit Service c6b9b0
        for x in dpkg_versions:
Packit Service c6b9b0
            print(" %s" % x)
Packit Service c6b9b0
Packit Service c6b9b0
        for x in dpkg_symbols:
Packit Service c6b9b0
            print(" %s" % x)
Packit Service c6b9b0
Packit Service c6b9b0
    if symbol_set is not None:
Packit Service c6b9b0
        missing = versioned_symbols - symbol_set
Packit Service c6b9b0
Packit Service c6b9b0
        if missing:
Packit Service c6b9b0
            e('These symbols have disappeared:')
Packit Service c6b9b0
Packit Service c6b9b0
            for symbol in missing:
Packit Service c6b9b0
                e('    %s', symbol)
Packit Service c6b9b0
Packit Service c6b9b0
            raise SystemExit(1)
Packit Service c6b9b0
Packit Service c6b9b0
        unreleased = symbol_set - versioned_symbols
Packit Service c6b9b0
Packit Service c6b9b0
        if unreleased:
Packit Service c6b9b0
            if unreleased_version is None:
Packit Service c6b9b0
                e('Unversioned symbols are not allowed in releases:')
Packit Service c6b9b0
Packit Service c6b9b0
                for symbol in unreleased:
Packit Service c6b9b0
                    e('    %s', symbol)
Packit Service c6b9b0
Packit Service c6b9b0
                raise SystemExit(1)
Packit Service c6b9b0
Packit Service c6b9b0
            if gnuld:
Packit Service c6b9b0
                print("%s {" % unreleased_version)
Packit Service c6b9b0
                print("    global:")
Packit Service c6b9b0
Packit Service c6b9b0
                for symbol in unreleased:
Packit Service c6b9b0
                    print("        %s;" % symbol)
Packit Service c6b9b0
Packit Service c6b9b0
                print("} %s;" % version)
Packit Service c6b9b0
Packit Service c6b9b0
Packit Service c6b9b0
if __name__ == '__main__':
Packit Service c6b9b0
    options, argv = gnu_getopt (sys.argv[1:], '',
Packit Service c6b9b0
                                ['symbols=', 'unreleased-version=',
Packit Service c6b9b0
                                 'dpkg=', 'dpkg-build-depends-package='])
Packit Service c6b9b0
Packit Service c6b9b0
    opts = {'dpkg': False}
Packit Service c6b9b0
Packit Service c6b9b0
    for option, value in options:
Packit Service c6b9b0
        if option == '--dpkg':
Packit Service c6b9b0
            opts['dpkg'] = True
Packit Service c6b9b0
            opts['dpkg_first_line'] = value
Packit Service c6b9b0
        else:
Packit Service c6b9b0
            opts[option.lstrip('-').replace('-', '_')] = value
Packit Service c6b9b0
Packit Service c6b9b0
    main(argv, **opts)