#!/usr/bin/env python3 # # Copyright © 2022 Collabora Inc. # # SPDX-License-Identifier: LGPL-2.1-or-later # # Original author: Xavier Claessens import argparse import textwrap from pathlib import Path def gen_versions_macros(args, current_minor_version): with args.out_path.open('w', encoding='utf-8') as ofile, \ args.in_path.open('r', encoding='utf-8') as ifile: for line in ifile.readlines(): if '@GLIB_VERSIONS@' in line: for minor in range(2, current_minor_version + 2, 2): ofile.write(textwrap.dedent(f'''\ /** * GLIB_VERSION_2_{minor}: * * A macro that evaluates to the 2.{minor} version of GLib, in a format * that can be used by the C pre-processor. * * Since: 2.{max(minor, 32)} */ #define GLIB_VERSION_2_{minor} (G_ENCODE_VERSION (2, {minor})) ''')) else: ofile.write(line) def gen_doc_sections(args, current_minor_version): with args.out_path.open('w', encoding='utf-8') as ofile, \ args.in_path.open('r', encoding='utf-8') as ifile: for line in ifile.readlines(): if '@GLIB_VERSIONS@' in line: for minor in range(2, current_minor_version + 2, 2): ofile.write(textwrap.dedent(f'''\ GLIB_VERSION_2_{minor} ''')) else: ofile.write(line) def gen_visibility_macros(args, current_minor_version): ''' Generates a set of macros for each minor stable version of GLib - GLIB_VAR - GLIB_DEPRECATED - GLIB_DEPRECATED_IN_… - GLIB_DEPRECATED_MACRO_IN_… - GLIB_DEPRECATED_ENUMERATOR_IN_… - GLIB_DEPRECATED_TYPE_IN_… - GLIB_AVAILABLE_IN_ALL - GLIB_AVAILABLE_IN_… - GLIB_AVAILABLE_STATIC_INLINE_IN_… - GLIB_AVAILABLE_MACRO_IN_… - GLIB_AVAILABLE_ENUMERATOR_IN_… - GLIB_AVAILABLE_TYPE_IN_… - GLIB_UNAVAILABLE(maj,min) - GLIB_UNAVAILABLE_STATIC_INLINE(maj,min) The GLIB namespace can be replaced with one of GOBJECT, GIO, GMODULE. ''' ns = args.namespace with args.out_path.open('w', encoding='utf-8') as f: f.write(textwrap.dedent(f'''\ #pragma once #if (defined(_WIN32) || defined(__CYGWIN__)) && !defined({ns}_STATIC_COMPILATION) # define _{ns}_EXPORT __declspec(dllexport) # define _{ns}_IMPORT __declspec(dllimport) #elif __GNUC__ >= 4 # define _{ns}_EXPORT __attribute__((visibility("default"))) # define _{ns}_IMPORT #else # define _{ns}_EXPORT # define _{ns}_IMPORT #endif #ifdef {ns}_COMPILATION # define _{ns}_API _{ns}_EXPORT #else # define _{ns}_API _{ns}_IMPORT #endif #define _{ns}_EXTERN _{ns}_API extern #define {ns}_VAR _{ns}_EXTERN #define {ns}_AVAILABLE_IN_ALL _{ns}_EXTERN #ifdef GLIB_DISABLE_DEPRECATION_WARNINGS #define {ns}_DEPRECATED _{ns}_EXTERN #define {ns}_DEPRECATED_FOR(f) _{ns}_EXTERN #define {ns}_UNAVAILABLE(maj,min) _{ns}_EXTERN #define {ns}_UNAVAILABLE_STATIC_INLINE(maj,min) #else #define {ns}_DEPRECATED G_DEPRECATED _{ns}_EXTERN #define {ns}_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) _{ns}_EXTERN #define {ns}_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min) _{ns}_EXTERN #define {ns}_UNAVAILABLE_STATIC_INLINE(maj,min) G_UNAVAILABLE(maj,min) #endif ''')) for minor in range(26, current_minor_version + 2, 2): f.write(textwrap.dedent(f''' #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_{minor} #define {ns}_DEPRECATED_IN_2_{minor} {ns}_DEPRECATED #define {ns}_DEPRECATED_IN_2_{minor}_FOR(f) {ns}_DEPRECATED_FOR (f) #define {ns}_DEPRECATED_MACRO_IN_2_{minor} GLIB_DEPRECATED_MACRO #define {ns}_DEPRECATED_MACRO_IN_2_{minor}_FOR(f) GLIB_DEPRECATED_MACRO_FOR (f) #define {ns}_DEPRECATED_ENUMERATOR_IN_2_{minor} GLIB_DEPRECATED_ENUMERATOR #define {ns}_DEPRECATED_ENUMERATOR_IN_2_{minor}_FOR(f) GLIB_DEPRECATED_ENUMERATOR_FOR (f) #define {ns}_DEPRECATED_TYPE_IN_2_{minor} GLIB_DEPRECATED_TYPE #define {ns}_DEPRECATED_TYPE_IN_2_{minor}_FOR(f) GLIB_DEPRECATED_TYPE_FOR (f) #else #define {ns}_DEPRECATED_IN_2_{minor} _{ns}_EXTERN #define {ns}_DEPRECATED_IN_2_{minor}_FOR(f) _{ns}_EXTERN #define {ns}_DEPRECATED_MACRO_IN_2_{minor} #define {ns}_DEPRECATED_MACRO_IN_2_{minor}_FOR(f) #define {ns}_DEPRECATED_ENUMERATOR_IN_2_{minor} #define {ns}_DEPRECATED_ENUMERATOR_IN_2_{minor}_FOR(f) #define {ns}_DEPRECATED_TYPE_IN_2_{minor} #define {ns}_DEPRECATED_TYPE_IN_2_{minor}_FOR(f) #endif #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_{minor} #define {ns}_AVAILABLE_IN_2_{minor} {ns}_UNAVAILABLE (2, {minor}) #define {ns}_AVAILABLE_STATIC_INLINE_IN_2_{minor} GLIB_UNAVAILABLE_STATIC_INLINE (2, {minor}) #define {ns}_AVAILABLE_MACRO_IN_2_{minor} GLIB_UNAVAILABLE_MACRO (2, {minor}) #define {ns}_AVAILABLE_ENUMERATOR_IN_2_{minor} GLIB_UNAVAILABLE_ENUMERATOR (2, {minor}) #define {ns}_AVAILABLE_TYPE_IN_2_{minor} GLIB_UNAVAILABLE_TYPE (2, {minor}) #else #define {ns}_AVAILABLE_IN_2_{minor} _{ns}_EXTERN #define {ns}_AVAILABLE_STATIC_INLINE_IN_2_{minor} #define {ns}_AVAILABLE_MACRO_IN_2_{minor} #define {ns}_AVAILABLE_ENUMERATOR_IN_2_{minor} #define {ns}_AVAILABLE_TYPE_IN_2_{minor} #endif ''')) def main(): parser = argparse.ArgumentParser() parser.add_argument('glib_version', help='Current GLib version') subparsers = parser.add_subparsers() versions_parser = subparsers.add_parser('versions-macros', help='Generate versions macros') versions_parser.add_argument('in_path', help='input file', type=Path) versions_parser.add_argument('out_path', help='output file', type=Path) versions_parser.set_defaults(func=gen_versions_macros) doc_parser = subparsers.add_parser('doc-sections', help='Generate glib-sections.txt') doc_parser.add_argument('in_path', help='input file', type=Path) doc_parser.add_argument('out_path', help='output file', type=Path) doc_parser.set_defaults(func=gen_doc_sections) visibility_parser = subparsers.add_parser('visibility-macros', help='Generate visibility macros') visibility_parser.add_argument('namespace', help='Macro namespace') visibility_parser.add_argument('out_path', help='output file', type=Path) visibility_parser.set_defaults(func=gen_visibility_macros) args = parser.parse_args() version = [int(i) for i in args.glib_version.split('.')] assert version[0] == 2 args.func(args, version[1]) if __name__ == '__main__': main()