1#!/usr/bin/env python3
2#
3# Check for the first line in a file generated with gmmproc,
4# to see which gmmproc version was used, to see whether
5# to enable __declspec(dllexport to export symbols).  This
6# is *not* intended for source files that are not generated
7# with gmmproc.
8#
9# Author: Chun-wei Fan April 2, 2020
10
11import argparse
12import os
13import sys
14
15min_required_gmmproc_ver = '2.64.3'
16
17parser = argparse.ArgumentParser(description='Check gmmproc version used.')
18parser.add_argument('--file',
19                    dest='file',
20                    help='Generated .cc/.h file to check gmmproc version')
21parser.add_argument('--gmmprocdir',
22                    dest='gmmprocdir',
23                    help='Directory where gmmproc is located')
24args = parser.parse_args()
25
26if args.file is None and args.gmmprocdir is None:
27    raise ValueError('Either --file or --gmmprocdir must be specified')
28
29if args.gmmprocdir is not None:
30    # gmmprocdir is specified: Check version string in gmmproc
31    gmmproc_path = os.path.join(args.gmmprocdir, 'gmmproc')
32    if not os.path.exists(gmmproc_path):
33        raise ValueError('A valid directory to locate gmmproc must be ' \
34                         'specified with --gmmprocdir=<directory>')
35
36    gmmproc_ver_str = None
37    with open(gmmproc_path, 'r') as f:
38        for line in f:
39            if line.startswith('  $main::glibmm_version = '):
40                gmmproc_ver_str = line[line.find('\"') + 1:line.rfind('\"')]
41
42    if gmmproc_ver_str is None:
43        raise ValueError('The gmmproc at %s is invalid' % gmmproc_path)
44
45    gmmproc_ver = gmmproc_ver_str.split('.')
46else:
47    # A pre-generated file is specified via --file
48    if not os.path.exists(args.file):
49        raise FileNotFoundError('File specified with --file does not exist')
50
51    # We only allow .h/.cc files to run this check
52    if not args.file.endswith('.cc') and \
53       not args.file.endswith('.h'):
54        raise ValueError('Only .cc/.h files are accepted here')
55
56    # Now grab the first line of the file we are checking for
57    f = open(args.file)
58    firstline = f.readline()
59    f.close()
60
61    # Check for gmmproc signature...
62    if not firstline.startswith('// Generated by gmmproc '):
63       raise ValueError('Specified file is not generated by gmmproc')
64
65    tokens = firstline.split()
66    gmmproc_ver = tokens[tokens.index('gmmproc') + 1].split('.')
67
68# Now compare the gmmproc version against the one we want
69# (2.64.3 or later)
70gmmproc_major = int(gmmproc_ver[0])
71gmmproc_minor = int(gmmproc_ver[1])
72gmmproc_micro = int(gmmproc_ver[2])
73
74min_required_ver = min_required_gmmproc_ver.split('.')
75min_major_ver = int(min_required_ver[0])
76min_minor_ver = int(min_required_ver[1])
77min_micro_ver = int(min_required_ver[2])
78
79if gmmproc_major > min_major_ver or \
80   (gmmproc_major == min_major_ver and \
81    gmmproc_minor > min_minor_ver) or \
82   (gmmproc_major == min_major_ver and \
83    gmmproc_minor == min_minor_ver and \
84    gmmproc_micro >= min_micro_ver):
85    sys.exit(0)
86else:
87    sys.exit(1)
88