1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#!/usr/bin/python3
##
## license:BSD-3-Clause
## copyright-holders:Vas Crabb
import argparse
import io
import re
import string
import sys
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('--target', '-t', metavar='<target>', default='mame', help='target name')
parser.add_argument('--subtarget', '-s', metavar='<subtarget>', default='mame', help='subtarget name')
parser.add_argument('--executable', '-e', metavar='<executable>', default='mame', help='base executable name')
parser.add_argument('--format', '-f', choices=('rc', 'plist'), metavar='<format>', default='rc', help='output format')
parser.add_argument('--resources', '-r', metavar='<resfile>', help='resource file to include')
parser.add_argument('-o', metavar='<outfile>', help='output file name')
parser.add_argument('input', metavar='<srcfile>', help='version info source file')
return parser.parse_args()
def extract_version(verinfo):
pattern = re.compile(r'\s+BARE_BUILD_VERSION\s+"(([^."]+)\.([^."]+))"')
for line in verinfo:
match = pattern.search(line)
if match:
return match.group(1), match.group(2), match.group(3)
return None, None, None
if __name__ == '__main__':
options = parse_args()
try:
with io.open(options.input, 'r') as verinfo:
verfull, vermajor, verminor = extract_version(verinfo)
verbuild = '0'
except IOError as e:
sys.stderr.write("Error reading source file '%s': %s\n" % (options.input, e))
sys.exit(1)
if verfull is None:
sys.stderr.write("Unable to extract version from source file '%s'\n" % (options.input, ))
sys.exit(1)
if options.format == 'plist':
template = string.Template(
'<?xml version="1.0" encoding="UTF-8"?>\n' \
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n' \
'<plist version="1.0">\n' \
'<dict>\n' \
'\t<key>CFBundleDisplayName</key>\n' \
'\t<string>${product}</string>\n' \
'\t<key>CFBundleIdentifier</key>\n' \
'\t<string>${rdns}</string>\n' \
'\t<key>CFBundleInfoDictionaryVersion</key>\n' \
'\t<string>6.0</string>\n' \
'\t<key>CFBundleName</key>\n' \
'\t<string>${product}</string>\n' \
'\t<key>CFBundleShortVersionString</key>\n' \
'\t<string>${major}.${minor}.${build}</string>\n' \
'\t<key>NSPrincipalClass</key>\n' \
'\t<string>NSApplication</string>\n' \
'</dict>\n' \
'</plist>\n')
else:
template = string.Template(
'#include <windows.h>\n' \
'#pragma code_page(65001)\n' \
'VS_VERSION_INFO VERSIONINFO\n' \
'\tFILEVERSION ${major},${minor},${build},${subbuild}\n' \
'\tPRODUCTVERSION ${major},${minor},${build},${subbuild}\n' \
'\tFILEFLAGSMASK 0x3fL\n' \
'\tFILEFLAGS ${winfileflags}\n' \
'\tFILEOS VOS_NT_WINDOWS32\n' \
'\tFILETYPE VFT_APP\n' \
'\tFILESUBTYPE VFT2_UNKNOWN\n' \
'BEGIN\n' \
'\tBLOCK "StringFileInfo"\n' \
'\tBEGIN\n' \
'#ifdef UNICODE\n' \
'\t\tBLOCK "040904b0"\n' \
'#else\n' \
'\t\tBLOCK "040904E4"\n' \
'#endif\n' \
'\t\tBEGIN\n' \
'\t\t\tVALUE "Author", "${author}\\0"\n' \
'\t\t\tVALUE "Comments", "${comments}\\0"\n' \
'\t\t\tVALUE "CompanyName", "${company}\\0"\n' \
'\t\t\tVALUE "FileDescription", "${filedesc}\\0"\n' \
'\t\t\tVALUE "FileVersion", "${major}, ${minor}, ${build}, ${subbuild}\\0"\n' \
'\t\t\tVALUE "InternalName", "${internal}\\0"\n' \
'\t\t\tVALUE "LegalCopyright", "${copyright}\\0"\n' \
'\t\t\tVALUE "OriginalFilename", "${original}\\0"\n' \
'\t\t\tVALUE "ProductName", "${product}\\0"\n' \
'\t\t\tVALUE "ProductVersion", "${version}\\0"\n' \
'\t\tEND\n' \
'\tEND\n' \
'\tBLOCK "VarFileInfo"\n' \
'\tBEGIN\n' \
'#ifdef UNICODE\n' \
'\t\tVALUE "Translation", 0x409, 1200\n' \
'#else\n' \
'\t\tVALUE "Translation", 0x409, 1252\n' \
'#endif\n' \
'\tEND\n' \
'END\n' \
'#include "${resources}"\n')
internal = options.target + '_' + options.subtarget if options.target != options.subtarget else options.target
text = template.substitute(
version=verfull,
major=vermajor, minor=verminor, build='0', subbuild='0',
author='MAMEdev and contributors',
comments='Multi-purpose emulation framework',
company='MAMEdev',
filedesc='MAME',
internal=internal,
original=options.executable,
product=('MAME' if options.target == 'mame' else options.target),
rdns=('org.mamedev.' + internal),
copyright='\u00a9 1997-2025 MAMEdev and contributors',
winfileflags=('0x0L' if verbuild == '0' else 'VS_FF_PRERELEASE'),
resources=(options.resources or 'mame.rc'))
if options.o is not None:
try:
with io.open(options.o, 'w', encoding='utf-8') as out:
out.write(text)
except IOError as e:
sys.stderr.write("Error writing output file '%s': %s\n" % (options.o, e))
sys.exit(1)
else:
sys.stdout.write(text)
|