diff --git a/3rdParty/LibIDN/SConscript b/3rdParty/LibIDN/SConscript index 90892b0..c99aff8 100644 --- a/3rdParty/LibIDN/SConscript +++ b/3rdParty/LibIDN/SConscript @@ -40,13 +40,13 @@ if env.get("LIBIDN_BUNDLED", False) : if conf.CheckFunc("stricmp") : myenv.Append(CPPDEFINES = [("strcasecmp", "stricmp")]) else : - print "Error: Cannot find strcasecmp() or stricmp()" + print("Error: Cannot find strcasecmp() or stricmp()") Exit(1) if not conf.CheckFunc('strncasecmp') : if conf.CheckFunc("strnicmp") : myenv.Append(CPPDEFINES = [("strncasecmp", "strnicmp")]) else : - print "Error: Cannot find strncasecmp() or strnicmp()" + print("Error: Cannot find strncasecmp() or strnicmp()") Exit(1) conf.Finish() diff --git a/BuildTools/CheckHeaders.py b/BuildTools/CheckHeaders.py index 79ff85c..752d257 100755 --- a/BuildTools/CheckHeaders.py +++ b/BuildTools/CheckHeaders.py @@ -36,7 +36,7 @@ for line in file.readlines() : continue for forbiddenInclude, ignores in FORBIDDEN_INCLUDES : if forbiddenInclude in line and len([x for x in ignores if x in filename]) == 0 : - print "Found " + forbiddenInclude + " include in " + filename + print("Found " + forbiddenInclude + " include in " + filename) foundBadHeaders = True sys.exit(foundBadHeaders) diff --git a/BuildTools/CheckTranslations.py b/BuildTools/CheckTranslations.py index 615f81f..0617fba 100755 --- a/BuildTools/CheckTranslations.py +++ b/BuildTools/CheckTranslations.py @@ -41,10 +41,10 @@ for filename in os.listdir("Swift/Translations") : translationText = getText(translation.childNodes) translationPlaceholders = set(re.findall("%\d+%?", translationText)) if translationPlaceholders != sourcePlaceholders : - print "[Error] " + filename + ": Placeholder mismatch in translation '" + sourceText + "'" + print("[Error] " + filename + ": Placeholder mismatch in translation '" + sourceText + "'") if not finished : - print "[Warning] " + filename + ": Unfinished" + print("[Warning] " + filename + ": Unfinished") if language not in desktop_generic_names and language != "en" : - print "[Warning] GenericName field missing in desktop entry for " + language + print("[Warning] GenericName field missing in desktop entry for " + language) if language not in desktop_comments and language != "en" : - print "[Warning] Comment field missing in desktop entry for " + language + print("[Warning] Comment field missing in desktop entry for " + language) diff --git a/BuildTools/Copyright/find-contribs.py b/BuildTools/Copyright/find-contribs.py index ac30afb..799ae7b 100755 --- a/BuildTools/Copyright/find-contribs.py +++ b/BuildTools/Copyright/find-contribs.py @@ -46,12 +46,12 @@ def print_log(full_log): full_swiften_log = subprocess.check_output(["git", "log", "--", "Swiften"]) -print "Contributors for Swiften/ subtree:\n" +print("Contributors for Swiften/ subtree:\n") print_log(full_swiften_log) full_all_log = subprocess.check_output(["git", "log"]) -print "\n\n\n\n" +print("\n\n\n\n") -print "Contributors for full tree:\n" +print("Contributors for full tree:\n") print_log(full_all_log) diff --git a/BuildTools/Copyrighter.py b/BuildTools/Copyrighter.py index a16050c..4c7bfeb 100755 --- a/BuildTools/Copyrighter.py +++ b/BuildTools/Copyrighter.py @@ -8,7 +8,7 @@ CONTRIBUTOR_LICENSE = "mit" LICENSE_DIR = "Documentation/Licenses" # The following regex parses license comment blocks and its part out of a complete source file. -reParseLicenseCommentBlocks = re.compile(ur'(\/\*\n\s\*\sCopyright \(c\) (?P\d\d\d\d)(-(?P\d\d\d\d))? (?P[^\n\.]*)\.?\n.\* (?P[^\n]*)\n \* (?P[^\n]+)\n *\*\/)') +reParseLicenseCommentBlocks = re.compile(r'(\/\*\n\s\*\sCopyright \(c\) (?P\d\d\d\d)(-(?P\d\d\d\d))? (?P[^\n\.]*)\.?\n.\* (?P[^\n]*)\n \* (?P[^\n]+)\n *\*\/)') class License : def __init__(self, name, file) : @@ -122,14 +122,14 @@ def check_copyright(filename, hints) : return True else : if hints : - print "Copyright block for " + copyrightSetting.author + " does not cover current year in: " + filename + print("Copyright block for " + copyrightSetting.author + " does not cover current year in: " + filename) return False if hints : - print "Missing copyright block for " + copyrightSetting.author + " in: " + filename + print("Missing copyright block for " + copyrightSetting.author + " in: " + filename) return False else : if hints : - print "No copyright found in: " + filename + print("No copyright found in: " + filename) return False def replace_data_in_file(filename, begin, end, replaceWith) : @@ -140,7 +140,7 @@ def replace_data_in_file(filename, begin, end, replaceWith) : def set_or_update_copyright(filename) : if check_copyright(filename, False) : - print "No update required for file: " + filename + print("No update required for file: " + filename) else : copyrightBlocks = parse_file_new(filename) username, email = get_userinfo() @@ -161,7 +161,7 @@ def set_or_update_copyright(filename) : replace_data_in_file(filename, lastBlock+1, lastBlock+1, "\n" + str(copyrightSetting)) def print_help() : - print """Usage: + print("""Usage: Copyrighter.py check-copyright $filename Cheks for the existence of a copyright comment block. @@ -172,7 +172,7 @@ def print_help() : A users license configuration can be set via the SWIFT_LICENSE_CONFIG environment variable in the format "$copyright holder|$license", e.g. "Jane Doe|mit". Possible values for $license are default, mit and gpl. - """ + """) if sys.argv[1] == "check-copyright" : file = sys.argv[2] @@ -183,6 +183,6 @@ elif sys.argv[1] == "set-copyright" : file = sys.argv[2] set_or_update_copyright(file) else : - print "Unknown command: " + sys.argv[1] + print("Unknown command: " + sys.argv[1]) print_help() sys.exit(-1) diff --git a/BuildTools/CrashReportAnalysis/WindowsMinidumpAnalyse.py b/BuildTools/CrashReportAnalysis/WindowsMinidumpAnalyse.py index dada920..92f9b28 100644 --- a/BuildTools/CrashReportAnalysis/WindowsMinidumpAnalyse.py +++ b/BuildTools/CrashReportAnalysis/WindowsMinidumpAnalyse.py @@ -19,11 +19,11 @@ import time swiftWindowBuildsPathPrefix = os.getenv("SWIFT_DIST") if swiftWindowBuildsPathPrefix == None : - print "Please set the SWIFT_DIST environment variable to a location containing msi and pdb.gz files." + print("Please set the SWIFT_DIST environment variable to a location containing msi and pdb.gz files.") sys.exit(1) if len(sys.argv) != 3: - print "Usage: python WindowsMinidumpAnalyse.py VERSION MINIDUMP_FILE" + print("Usage: python WindowsMinidumpAnalyse.py VERSION MINIDUMP_FILE") sys.exit(1) version = sys.argv[1] @@ -93,7 +93,7 @@ def printHumanReadableReport(): try: shutil.rmtree(working_folder) except: - print "" + print("") # clone local git repository into dedicated directory call(["git", "clone", ".", working_folder], shell=True) @@ -120,7 +120,7 @@ assert(len(commit) > 0) if not os.path.exists(symbol_cache_path): os.makedirs(symbol_cache_path) -#print "Checking out commit {0}.".format(commit) +#print("Checking out commit {0}.".format(commit)) call(["git", "-C", working_folder, "checkout", commit]) os.chdir(working_folder) diff --git a/BuildTools/DocBook/SCons/DocBook.py b/BuildTools/DocBook/SCons/DocBook.py index ffb0bfc..d7c95ba 100644 --- a/BuildTools/DocBook/SCons/DocBook.py +++ b/BuildTools/DocBook/SCons/DocBook.py @@ -5,6 +5,19 @@ import SCons.Util, SCons.Action import xml.dom.minidom, re, os.path, sys +def maybeBytesToString(s): + if isinstance(s, bytes): + return s.decode('utf-8') + return s + +def prepareForWrite(s): + try: + if isinstance(s, unicode): + return s.encode('utf-8') + except NameError: + pass + return s + def generate(env) : # Location of stylesheets and catalogs docbook_dir = "#/BuildTools/DocBook" @@ -32,15 +45,15 @@ def generate(env) : rewritePrefix="%(docbook_xsl_dir)s/" /> """ - docbook_xml_dir = source[0].get_contents() - docbook_xsl_dir = source[1].get_contents() + docbook_xml_dir = maybeBytesToString(source[0].get_contents()) + docbook_xsl_dir = maybeBytesToString(source[1].get_contents()) if env["PLATFORM"] == "win32" : docbook_xml_dir = docbook_xml_dir.replace("\\","/") docbook_xsl_dir = docbook_xsl_dir.replace("\\","/") file = open(target[0].abspath, "w") file.write(catalog % { - "docbook_xml_dir" : docbook_xml_dir, - "docbook_xsl_dir" : docbook_xsl_dir, + "docbook_xml_dir" : prepareForWrite(docbook_xml_dir), + "docbook_xsl_dir" : prepareForWrite(docbook_xsl_dir), }) file.close() diff --git a/BuildTools/DocBook/SCons/XSLT.py b/BuildTools/DocBook/SCons/XSLT.py index 38e36c5..6a40b62 100644 --- a/BuildTools/DocBook/SCons/XSLT.py +++ b/BuildTools/DocBook/SCons/XSLT.py @@ -8,7 +8,7 @@ import xml.dom.minidom, os, os.path def generate(env) : def generate_actions(source, target, env, for_signature) : if not env.has_key("XSLTSTYLESHEET") : - raise SCons.Errors.UserError, "The XSLTSTYLESHEET construction variable must be defined" + raise SCons.Errors.UserError("The XSLTSTYLESHEET construction variable must be defined") # Process the XML catalog files # FIXME: It's probably not clean to do an ENV assignment globally diff --git a/BuildTools/FixIncludes.py b/BuildTools/FixIncludes.py index 8984944..e532464 100755 --- a/BuildTools/FixIncludes.py +++ b/BuildTools/FixIncludes.py @@ -153,12 +153,12 @@ for line in content[headerStart:headerEnd]: headerGroups[headerType] = [line] if containsComplexPreprocessorDirectives: - print "Cannot format headers containing preprocessor #if, #pragma, #define or #undef statements!" + print("Cannot format headers containing preprocessor #if, #pragma, #define or #undef statements!") exit(1) if filename_base.endswith(".h"): if not HeaderType.PRAGMA_ONCE in headerGroups: - print "Missing #pragma once!" + print("Missing #pragma once!") exit(2) cleanHeaderFile(content, headerStart, headerEnd, headerGroups) elif filename_base.endswith(".cpp") or filename_base.endswith(".mm"): diff --git a/BuildTools/GetBuildVersion.py b/BuildTools/GetBuildVersion.py index 70fdc5c..be7cc03 100755 --- a/BuildTools/GetBuildVersion.py +++ b/BuildTools/GetBuildVersion.py @@ -16,6 +16,6 @@ if only_major : if version_match : print version_match.group(1) else : - print "0" + print("0") else : print Version.getBuildVersion(os.path.dirname(sys.argv[0]) + "/..", sys.argv[1]) diff --git a/BuildTools/Gource/GetGravatars.py b/BuildTools/Gource/GetGravatars.py index d1f40a4..17198aa 100755 --- a/BuildTools/Gource/GetGravatars.py +++ b/BuildTools/Gource/GetGravatars.py @@ -5,7 +5,7 @@ import subprocess, os, sys, hashlib, urllib GRAVATAR_URL = "http://www.gravatar.com/avatar/%(id)s?d=404" if len(sys.argv) != 2 : - print "Usage: " + sys.argv[0] + " " + print("Usage: " + sys.argv[0] + " ") sys.exit(-1) output_dir = sys.argv[1] @@ -18,32 +18,32 @@ for line in p.stdout.readlines() : authors[author_components[0]] = author_components[1] p.stdin.close() if p.wait() != 0 : - print "Error" + print("Error") sys.exit(-1) # Get & save the avatars if not os.path.isdir(output_dir) : os.makedirs(output_dir) for email, name in authors.items() : - print "Processing avatar for " + name + " <" + email + ">" + print("Processing avatar for " + name + " <" + email + ">") filename = os.path.join(output_dir, name + ".png") if os.path.isfile(filename) : - print "-> Already there. Skipping." + print("-> Already there. Skipping.") continue m = hashlib.md5() m.update(email) url = GRAVATAR_URL % {"id" : m.hexdigest()} - print "- Downloading " + url + print("- Downloading " + url) f = urllib.urlopen(url) input = None if f.getcode() == 200 : input = f.read() f.close() if input : - print "- Saving file " + filename + print("- Saving file " + filename) f = open(filename, "w") f.write(input) f.close() else : - print "- No Gravatar found" + print("- No Gravatar found") diff --git a/BuildTools/ProjectCopyrightSummary.py b/BuildTools/ProjectCopyrightSummary.py index 6e2d824..f6b18a0 100755 --- a/BuildTools/ProjectCopyrightSummary.py +++ b/BuildTools/ProjectCopyrightSummary.py @@ -17,7 +17,7 @@ def CopyrightNames(filename): names = [] with open(filename, 'r') as file: data = file.read() - p = re.compile(ur'\* Copyright.*\d\d\d\d (.*?)\.?$', re.MULTILINE) + p = re.compile(r'\* Copyright.*\d\d\d\d (.*?)\.?$', re.MULTILINE) names = re.findall(p, data) return names diff --git a/BuildTools/SCons/SConstruct b/BuildTools/SCons/SConstruct index 6d63d5b..e40bfb8 100644 --- a/BuildTools/SCons/SConstruct +++ b/BuildTools/SCons/SConstruct @@ -7,9 +7,9 @@ root = Dir("../..").abspath # Override SConscript to handle tests oldSConscript = SConscript -def SConscript(*arguments, **keywords) : - if not keywords.get("test_only", False) or env["TEST"] : - return apply(oldSConscript, arguments, keywords) +def SConscript(*args, **kwargs) : + if not kwargs.get("test_only", False) or env["TEST"] : + return oldSConscript(*args, **kwargs) env.SConscript = SConscript ################################################################################ @@ -142,11 +142,11 @@ conf = Configure(conf_env, custom_tests = { }) if not conf.CheckCXX() or not conf.CheckCC() : - print "Error: You need a working compiler" + print("Error: You need a working compiler") Exit(1) if not conf.CheckCpp11Support() : - print "Error: You need a compiler with support for the C++11 standard" + print("Error: You need a compiler with support for the C++11 standard") Exit(1) @@ -170,7 +170,7 @@ if (not zlib_okay) and conf.CheckLib("z") : if zlib_okay : env["ZLIB_FLAGS"] = zlib_flags elif not env.get("zlib_bundled_enable", True) : - print "Error: Zlib not found and zlib_bundled_enable is false" + print("Error: Zlib not found and zlib_bundled_enable is false") Exit(1) else : env["ZLIB_BUNDLED"] = True @@ -238,7 +238,7 @@ if not env.get("boost_force_bundled") and allLibsPresent : # FIXME: Remove this workaround when UUID is available in most distros env["BOOST_BUNDLED_UUID_ONLY"] = True elif not env.get("boost_bundled_enable", True) : - print "Error: Boost not found and boost_bundled_enable is false" + print("Error: Boost not found and boost_bundled_enable is false") Exit(1) else : env["BOOST_BUNDLED"] = True @@ -373,7 +373,7 @@ if env.get("try_expat", True) and not env.get("HAVE_LIBXML",0) : # Bundled expat bundledExpat = False if not env.get("HAVE_EXPAT", 0) and not env.get("HAVE_LIBXML", 0) : - print "Expat or LibXML not found. Using bundled Expat" + print("Expat or LibXML not found. Using bundled Expat") SConscript("#/3rdParty/Expat/SConscript") env["HAVE_EXPAT"] = 1 env["EXPAT_BUNDLED"] = True @@ -424,10 +424,10 @@ if not env.get("HAVE_ICU", False) and not env.get("HAVE_LIBIDN", False) : env["HAVE_LIBIDN"] = 1 env["LIBIDN_BUNDLED"] = 1 elif env.get("need_idn", True): - print "Error: ICU and LIBIDN not found, and libidn_bundled_enable is false" + print("Error: ICU and LIBIDN not found, and libidn_bundled_enable is false") Exit(1) else: - print "Proceeding without an IDN library because need_idn was false. This will break all internal binaries" + print("Proceeding without an IDN library because need_idn was false. This will break all internal binaries") # Unbound if env["unbound"] : @@ -514,7 +514,7 @@ if not env.get("lua_force_bundled", False) and conf.CheckLibWithHeader(env["lua_ if lua_version > 0 : env["LUA_FLAGS"]["LUA_VERSION"] = str(lua_version // 100) + "." + str(lua_version % 100) else : - print "Warning: Unable to determine Lua version. Not installing Lua libraries." + print("Warning: Unable to determine Lua version. Not installing Lua libraries.") env["LUA_FLAGS"].update(lua_flags) else : env["LUA_BUNDLED"] = 1 @@ -666,7 +666,7 @@ try : except SCons.Errors.StopError: env["HAVE_QT"] = False except Exception as e: - print "Info: %s" % str(e) + print("Info: %s" % str(e)) env["HAVE_QT"] = False ################################################################################ @@ -688,7 +688,7 @@ try: if not env.GetOption("clean") and env.get("install_git_hooks", True) : env.Install("#/.git/hooks", Glob("#/BuildTools/Git/Hooks/*")) except TypeError: - print "You seem to be using Swift in a Git submodule. Not installing hooks." + print("You seem to be using Swift in a Git submodule. Not installing hooks.") ################################################################################ @@ -752,7 +752,7 @@ modules.append("QA") env["PROJECTS"] = [m for m in modules if m not in ["Documentation", "QA", "SwifTools"] and not m.startswith("3rdParty")] for stage in ["flags", "build"] : env["SCONS_STAGE"] = stage - SConscript(dirs = map(lambda x : root + "/" + x, modules)) + SConscript(dirs = list(map(lambda x : root + "/" + x, modules))) # SLOCCount if ARGUMENTS.get("sloccount", False) : @@ -764,9 +764,9 @@ if ARGUMENTS.get("sloccount", False) : # Print summary ################################################################################ -print -print " Build Configuration" -print " -------------------" +print("") +print(" Build Configuration") +print(" -------------------") parsers = [] if env.get("HAVE_LIBXML", 0): @@ -775,14 +775,14 @@ if env.get("HAVE_EXPAT", 0): parsers.append("Expat") if env.get("EXPAT_BUNDLED", False) : parsers.append("(Bundled)") -print " Projects: " + ' '.join(env["PROJECTS"]) -print "" -print " XML Parsers: " + ' '.join(parsers) +print(" Projects: " + ' '.join(env["PROJECTS"])) +print("") +print(" XML Parsers: " + ' '.join(parsers)) -print " TLS Support: " + (env.get("HAVE_OPENSSL",0) and "OpenSSL" or env.get("HAVE_SECURETRANSPORT",0) and "Secure Transport" or env.get("HAVE_SCHANNEL", 0) and "Schannel" or "Disabled") -print " DNSSD Support: " + (env.get("HAVE_BONJOUR") and "Bonjour" or (env.get("HAVE_AVAHI") and "Avahi" or "Disabled")) -print +print(" TLS Support: " + (env.get("HAVE_OPENSSL",0) and "OpenSSL" or env.get("HAVE_SECURETRANSPORT",0) and "Secure Transport" or env.get("HAVE_SCHANNEL", 0) and "Schannel" or "Disabled")) +print(" DNSSD Support: " + (env.get("HAVE_BONJOUR") and "Bonjour" or (env.get("HAVE_AVAHI") and "Avahi" or "Disabled"))) +print("") if not GetOption("help") and not env.get("HAVE_OPENSSL", 0) and not env.get("HAVE_SCHANNEL", 0) and not env.get("HAVE_SECURETRANSPORT", 0): - print "Error: A working TLS backend is required. Please check the documentation for more information." + print("Error: A working TLS backend is required. Please check the documentation for more information.") Exit(1) diff --git a/BuildTools/SCons/Tools/AppBundle.py b/BuildTools/SCons/Tools/AppBundle.py index 337e83f..31cfef1 100644 --- a/BuildTools/SCons/Tools/AppBundle.py +++ b/BuildTools/SCons/Tools/AppBundle.py @@ -34,7 +34,7 @@ def generate(env) : """ for key, value in infoDict.items() : plist += "" + key + "\n" - plist += "" + value.encode("utf-8") + "\n" + plist += "" + value + "\n" if handlesXMPPURIs : plist += """CFBundleURLTypes @@ -50,7 +50,7 @@ def generate(env) : if sparklePublicDSAKey : plist += "SUPublicDSAKeyFile" - plist += "" + sparklePublicDSAKey.name.encode("utf-8") + "" + plist += "" + sparklePublicDSAKey.name + "" env.Install(resourcesDir, sparklePublicDSAKey) plist += """ diff --git a/BuildTools/SCons/Tools/InstallWithSymLinks.py b/BuildTools/SCons/Tools/InstallWithSymLinks.py index 23d12ed..4955192 100644 --- a/BuildTools/SCons/Tools/InstallWithSymLinks.py +++ b/BuildTools/SCons/Tools/InstallWithSymLinks.py @@ -74,21 +74,21 @@ def scons_copytree(src, dst, symlinks=False): else: shutil.copy2(srcname, dstname) # XXX What about devices, sockets etc.? - except (IOError, os.error), why: + except (IOError, os.error) as why: errors.append((srcname, dstname, str(why))) # catch the CopytreeError from the recursive copytree so that we can # continue with other files - except CopytreeError, err: + except CopytreeError as err: errors.extend(err.args[0]) try: shutil.copystat(src, dst) except WindowsError: # can't copy file access times on Windows pass - except OSError, why: + except OSError as why: errors.extend((src, dst, str(why))) if errors: - raise CopytreeError, errors + raise CopytreeError(errors) def symlinkBuilderImpl(target, source, env): diff --git a/BuildTools/SCons/Tools/WindowsBundle.py b/BuildTools/SCons/Tools/WindowsBundle.py index 20d41ff..2c8c3e7 100644 --- a/BuildTools/SCons/Tools/WindowsBundle.py +++ b/BuildTools/SCons/Tools/WindowsBundle.py @@ -33,9 +33,13 @@ def generate(env) : mappings = [] - p = re.compile(ur'"([^\"]*)" "([^\"]*)"') + regex = re.compile(r'"([^\"]*)" "([^\"]*)"') + + if SCons.Util.PY3: + matches = re.findall(regex, stdout.decode('utf8')) + else: + matches = re.findall(regex, stdout) - matches = re.findall(p, stdout) for match in matches: mappings.append(match) return mappings @@ -84,7 +88,7 @@ def generate(env) : assert(qtmappings) # handle core DLLs - qt_corelib_regex = re.compile(ur".*bin.*\\(.*)\.dll") + qt_corelib_regex = re.compile(r".*bin.*\\(.*)\.dll") for qtlib in qtlibs: if qtlib.startswith("Qt5"): @@ -98,7 +102,7 @@ def generate(env) : all_files += env.Install(bundle, src_path) # handle plugins - qt_plugin_regex = re.compile(ur".*plugins.*\\(.*)\\(.*)\.dll") + qt_plugin_regex = re.compile(r".*plugins.*\\(.*)\\(.*)\.dll") for (src_path, target_path) in qtmappings: if qt_plugin_regex.match(src_path): plugin_folder, filename = qt_plugin_regex.match(src_path).groups() diff --git a/BuildTools/SCons/Tools/qt4.py b/BuildTools/SCons/Tools/qt4.py index d5c14e2..c97e751 100644 --- a/BuildTools/SCons/Tools/qt4.py +++ b/BuildTools/SCons/Tools/qt4.py @@ -137,23 +137,23 @@ class _Automoc: out_sources = source[:] for obj in source: - if isinstance(obj,basestring): # big kludge! - print "scons: qt4: '%s' MAYBE USING AN OLD SCONS VERSION AND NOT CONVERTED TO 'File'. Discarded." % str(obj) + if isinstance(obj,str): # big kludge! + print("scons: qt4: '%s' MAYBE USING AN OLD SCONS VERSION AND NOT CONVERTED TO 'File'. Discarded." % str(obj)) continue if not obj.has_builder(): # binary obj file provided if debug: - print "scons: qt: '%s' seems to be a binary. Discarded." % str(obj) + print("scons: qt: '%s' seems to be a binary. Discarded." % str(obj)) continue cpp = obj.sources[0] if not splitext(str(cpp))[1] in cxx_suffixes: if debug: - print "scons: qt: '%s' is no cxx file. Discarded." % str(cpp) + print("scons: qt: '%s' is no cxx file. Discarded." % str(cpp) ) # c or fortran source continue #cpp_contents = comment.sub('', cpp.get_contents()) try: - cpp_contents = cpp.get_contents() + cpp_contents = str(cpp.get_contents()) except: continue # may be an still not generated source h=None for h_ext in header_extensions: @@ -163,12 +163,12 @@ class _Automoc: h = find_file(hname, (cpp.get_dir(),), env.File) if h: if debug: - print "scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp)) + print("scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp))) #h_contents = comment.sub('', h.get_contents()) - h_contents = h.get_contents() + h_contents = str(h.get_contents()) break if not h and debug: - print "scons: qt: no header for '%s'." % (str(cpp)) + print("scons: qt: no header for '%s'." % (str(cpp))) if h and q_object_search.search(h_contents): # h file with the Q_OBJECT macro found -> add moc_cpp moc_cpp = env.Moc4(h) @@ -176,14 +176,14 @@ class _Automoc: out_sources.append(moc_o) #moc_cpp.target_scanner = SCons.Defaults.CScan if debug: - print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp)) + print("scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp))) if cpp and q_object_search.search(cpp_contents): # cpp file with Q_OBJECT macro found -> add moc # (to be included in cpp) moc = env.Moc4(cpp) env.Ignore(moc, moc) if debug: - print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc)) + print("scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc))) #moc.source_scanner = SCons.Defaults.CScan # restore the original env attributes (FIXME) objBuilder.env = objBuilderEnv @@ -344,7 +344,7 @@ def generate(env): else: result.append(itemPath) return result - contents = node.get_contents() + contents = str(node.get_contents()) includes = [included[1] for included in qrcinclude_re.findall(contents)] qrcpath = os.path.dirname(node.path) dirs = [included for included in includes if os.path.isdir(os.path.join(qrcpath,included))] diff --git a/BuildTools/SCons/Tools/wix.py b/BuildTools/SCons/Tools/wix.py index 907b6d9..2d46188 100644 --- a/BuildTools/SCons/Tools/wix.py +++ b/BuildTools/SCons/Tools/wix.py @@ -15,7 +15,10 @@ def generate(env) : def WiX_IncludeScanner(source, env, path, arg): wixIncludeRegexp = re.compile(r'^\s*\<\?include (\S+.wxs)\s*\?\>\S*', re.M) - contents = source.get_contents() + if SCons.Util.PY3: + contents = source.get_contents().decode("utf8") + else: + contents = source.get_contents() includes = wixIncludeRegexp.findall(contents) return [ "" + include for include in includes ] diff --git a/BuildTools/SCons/Version.py b/BuildTools/SCons/Version.py index f215a5d..23cd850 100644 --- a/BuildTools/SCons/Version.py +++ b/BuildTools/SCons/Version.py @@ -1,26 +1,34 @@ +from __future__ import print_function import subprocess, os, datetime, re, os.path, sys, unittest -def getGitBuildVersion(root, project) : - tag = git("describe --tags --exact --match \"" + project + "-*\"", root) - if tag : - return tag.rstrip()[len(project)+1:] - tag = git("describe --tags --match \"" + project + "-*\"", root) - if tag : - m = re.match(project + "-(.*)-(.*)-(.*)", tag) - if m : - return m.group(1) + "-dev" + m.group(2) +def gitDescribeToVersion(tag, tagPrefix): + m = re.match(r'^' + tagPrefix + r'-(.+?)(?:-(.+?)-(.+?))?$', tag) + if not m: + return None + result = m.group(1) + if m.group(2): + result += "-dev" + m.group(2) + return result + +def getGitBuildVersion(root, tagPrefix) : + tag = git("describe --tags --match \"" + tagPrefix + "-*\"", root) + if tag: + return gitDescribeToVersion(tag, tagPrefix) return None -def git(cmd, root) : +def git(cmd, root): full_cmd = "git " + cmd + # Would've used with .. as p, but that's not supported by Python 2.7 p = subprocess.Popen(full_cmd, cwd=root, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=(os.name != "nt")) gitVersion = p.stdout.read() - # error = p.stderr.read() - # if error: - # print "Git error: " + error - p.stdin.close() - if p.wait() == 0 : - return gitVersion + try: + p.stdin.close() + p.stdout.close() + p.stderr.close() + except: + pass + if p.wait() == 0: + return bytes(gitVersion).decode('utf-8') return None def getBuildVersion(root, project) : @@ -95,7 +103,7 @@ def convertToWindowsVersion(version): return (major, minor, patch) # Test Windows version mapping scheme -class convertToWindowsVersionTest(unittest.TestCase): +class TestCases(unittest.TestCase): def testWindowsVersionsAreDescending(self): versionStringsWithOldVersions = [ ("5.0rc11", None), @@ -111,13 +119,13 @@ class convertToWindowsVersionTest(unittest.TestCase): ("4.0rc5", (4, 0, 50000)), ("4.0rc4", (4, 0, 40000)), ("4.0rc3", (4, 0, 30000)), + ('4.0rc2-dev39', (4, 0, 20039)), ('4.0rc2-dev34', (4, 0, 20034)), ('4.0rc2-dev33', (4, 0, 20033)), ('4.0rc2-dev31', (4, 0, 20031)), ('4.0rc2-dev30', (4, 0, 20030)), ('4.0rc2-dev29', (4, 0, 20029)), ('4.0rc2-dev27', (4, 0, 20027)), - ('4.0rc2-dev39', (4, 0, 20039)), ('4.0rc2', (4, 0, 20000)), ('4.0rc1', (4, 0, 10000)), ('4.0beta2-dev203', (4, 0, 2203)), @@ -163,7 +171,17 @@ class convertToWindowsVersionTest(unittest.TestCase): ('3.0alpha-dev524', (3, 0, 524)), ('3.0alpha-dev515', (3, 0, 515)), ] - windowsVersionMapping = list(map(lambda (x,y): (x, convertToWindowsVersion(x)), versionStringsWithOldVersions)) + prevParsed = None + prevOldVersion = None + for string, oldVersion in versionStringsWithOldVersions: + parsed = convertToWindowsVersion(string) + if prevOldVersion and oldVersion: + self.assertTrue(oldVersion <= prevOldVersion, "Old version %r must come before %r" % (oldVersion, prevOldVersion)) + if prevParsed: + self.assertTrue(parsed < prevParsed, "%s => %r must be smaller than %s => %r" % (string, parsed, prevString, prevParsed)) + prevString = string + prevParsed = parsed + prevOldVersion = oldVersion def testThatBetaIsHigherThanAlpha(self): self.assertTrue(convertToWindowsVersion("3.0beta0") > convertToWindowsVersion("3.0alpha0")) @@ -190,12 +208,24 @@ class convertToWindowsVersionTest(unittest.TestCase): self.assertTrue(convertToWindowsVersion("3.0") > convertToWindowsVersion("3.0rc1")) self.assertTrue(convertToWindowsVersion("3.0") > convertToWindowsVersion("3.0rc11")) + def testGitDescribeToVersion(self): + self.assertEqual("5.0alpha2-dev100", gitDescribeToVersion("swift-5.0alpha2-100-g33d5f6571", "swift")) + self.assertEqual("5.0alpha2", gitDescribeToVersion("swift-5.0alpha2", "swift")) + self.assertEqual("5.0-dev1", gitDescribeToVersion("swift-5.0-1-g012312312", "swift")) + self.assertIsNone(gitDescribeToVersion("swiften-5.0-1-g012312312", "swift")) + self.assertIsNone(gitDescribeToVersion("quickly-5.0-1-g012312312", "swift")) + self.assertIsNone(gitDescribeToVersion("swift-", "swift")) + self.assertIsNone(gitDescribeToVersion("swift", "swift")) + if __name__ == '__main__': if len(sys.argv) == 1: unittest.main() elif len(sys.argv) == 2: - print convertToWindowsVersion(sys.argv[1]) + if sys.argv[1] == "--git-build-version": + print(getGitBuildVersion(os.path.dirname(os.path.dirname(__file__)), "swift")) + else: + print(convertToWindowsVersion(sys.argv[1])) sys.exit(0) else: - print "Error: Simply run the script without arguments or pass a single argument." + print("Error: Simply run the script without arguments or pass a single argument.") sys.exit(-1) diff --git a/BuildTools/scons2ninja.py b/BuildTools/scons2ninja.py index 6c77c88..855a133 100755 --- a/BuildTools/scons2ninja.py +++ b/BuildTools/scons2ninja.py @@ -429,7 +429,7 @@ for line in f.stdout : previous_filename = filename if f.wait() != 0 : - print "Error calling '" + scons_generate_cmd + "'" + print("Error calling '" + scons_generate_cmd + "'") print f.stderr.read() exit(-1) diff --git a/Documentation/SwiftenDevelopersGuide/SConscript b/Documentation/SwiftenDevelopersGuide/SConscript index ac7c67a..95e5c87 100644 --- a/Documentation/SwiftenDevelopersGuide/SConscript +++ b/Documentation/SwiftenDevelopersGuide/SConscript @@ -9,36 +9,6 @@ env.Tool("DocBook", toolpath = ["#/BuildTools/DocBook/SCons"]) import sys, re, os.path def generateDocBookCode(env, target, source) : - # Strips empty lines from the beginning & end of a program - def stripEmptyLines(program) : - programLines = program.split('\n') - newProgramLines = [] - inProgram = False - for line in programLines : - if not re.match("^\s*$", line) or inProgram : - inProgram = True - newProgramLines.append(line) - return '\n'.join(newProgramLines).rstrip() - - def createCallouts(program, calloutPrefix) : - newProgramLines = [] - calloutLines = [] - nextID = 0 - for line in program.split("\n") : - # FIXME: Takes the largest match - m = re.match(".*\/* \(\*\) (.*) \*/.*", line) - if m : - cobID = "cob-" + calloutPrefix + "-" + str(nextID) - coID = "co-" + calloutPrefix + "-" + str(nextID) - nextID += 1 - line = re.sub("/\*.*\*/", "]]>%(text)s" % {"cobID": cobID, "coID": coID, "text": m.group(1)}) - newProgramLines.append(line) - callouts = "" - if len(calloutLines) > 0 : - callouts = "" + "\n".join(calloutLines) + "" - return ("\n".join(newProgramLines), callouts) - # Parse program filename = source[0].abspath filenameBase = os.path.basename(filename).replace(".cpp", "") @@ -71,10 +41,7 @@ def generateDocBookCode(env, target, source) : inputfile.close() for programName, program in programs.items() : - program = stripEmptyLines(program) - (program, callouts) = createCallouts(program, filenameBase + "-" + programName) - - document = "" + callouts + "" + document = "" # Generate code output = open(target[0].abspath, 'w') diff --git a/Slimber/SConscript b/Slimber/SConscript index a41fe0b..fa5aa53 100644 --- a/Slimber/SConscript +++ b/Slimber/SConscript @@ -11,10 +11,10 @@ elif env["PLATFORM"] != "darwin" : env["PROJECTS"].remove("Slimber") if not "Slimber" in env["PROJECTS"] and env["SCONS_STAGE"] == "flags" : - print "Bonjour missing. Not building Slimber." + print("Bonjour missing. Not building Slimber.") if not env.get("HAVE_QT", False) and "Slimber" in env["PROJECTS"] : - print "Qt missing. Not building Slimber." + print("Qt missing. Not building Slimber.") env["PROJECTS"].remove("Slimber") if "Slimber" in env["PROJECTS"] : diff --git a/Sluift/SConscript b/Sluift/SConscript index de9cab6..af54ece 100644 --- a/Sluift/SConscript +++ b/Sluift/SConscript @@ -3,7 +3,7 @@ import Version, os.path Import(["env"]) if env["SCONS_STAGE"] == "build" and not GetOption("help") and not env.get("HAVE_LUA", 0) : - print "Warning: Lua was not found. Sluift will not be built." + print("Warning: Lua was not found. Sluift will not be built.") if "Sluift" in env["PROJECTS"] : env["PROJECTS"].remove("Sluift") diff --git a/Swift/Packaging/SConscript b/Swift/Packaging/SConscript index 3aa791f..556c596 100644 --- a/Swift/Packaging/SConscript +++ b/Swift/Packaging/SConscript @@ -25,5 +25,5 @@ if env["SCONS_STAGE"] == "build" : target='$HELP2MAN_DEBIAN_DIR/swift-im.1', source='#/Swift/QtUI/swift-im', action = Action('$HELP2MAN --no-discard-stderr -m "Swift Manual" -S "Swift" -n "swift-im" -N $SOURCE > $TARGET', cmdstr = "$HELP2MANSTR")) else: - print "Enabled help2man but help2man is not in the PATH of the current environment." + print("Enabled help2man but help2man is not in the PATH of the current environment.") Exit(1) diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index 54f0450..9bd2dcf 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -1,5 +1,6 @@ import os, datetime, re, time import Version +import SCons.Util def generateQRCTheme(dir, prefix) : sourceDir = dir.abspath @@ -19,10 +20,10 @@ def generateQRCTheme(dir, prefix) : Import("env") -myenv = env.Clone() +myenv = env.Clone(tools = [ 'textfile' ]) # Disable warnings that affect Qt -myenv["CXXFLAGS"] = filter(lambda x : x != "-Wfloat-equal", myenv["CXXFLAGS"]) +myenv["CXXFLAGS"] = list(filter(lambda x : x != "-Wfloat-equal", myenv["CXXFLAGS"])) if "clang" in env["CC"] : myenv.Append(CXXFLAGS = ["-Wno-float-equal", "-Wno-shorten-64-to-32", "-Wno-missing-prototypes", "-Wno-unreachable-code", "-Wno-disabled-macro-expansion", "-Wno-unused-private-field", "-Wno-extra-semi", "-Wno-duplicate-enum", "-Wno-missing-variable-declarations", "-Wno-conversion", "-Wno-undefined-reinterpret-cast"]) @@ -351,7 +352,7 @@ myenv["TEXTFILESUFFIX"] = "" copying_files = [myenv.File("../../COPYING.gpl"), myenv.File("../../COPYING.thirdparty"), myenv.File("../../COPYING.dependencies")] if env["PLATFORM"] == "darwin" and env["HAVE_SPARKLE"] : copying_files.append(env["SPARKLE_COPYING"]) -myenv.MyTextfile(target = "COPYING", source = copying_files, LINESEPARATOR = "\n\n========\n\n\n") +myenv.Textfile(target = "COPYING", source = copying_files, LINESEPARATOR = "\n\n========\n\n\n") ################################################################################ # Translation @@ -463,9 +464,16 @@ if env["PLATFORM"] == "win32" : def convertToRTF(env, target, source) : infile = open(source[0].abspath, 'r') outfile = open(target[0].abspath, 'w') + if SCons.Util.PY3: + infile = open(source[0].abspath, 'r', encoding="utf8") + outfile = open(target[0].abspath, 'w', encoding="utf8") + else: + infile = open(source[0].abspath, 'r') + outfile = open(target[0].abspath, 'w') outfile.write('{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\fs16\\f0\\pard\n') for line in infile: - for char in line.decode("utf-8") : + line = line if SCons.Util.PY3 else line.decode("utf-8") + for char in line : if ord(char) > 127 : # FIXME: This is incorrect, because it only works for latin1. # The correct way is \u? , but this is more @@ -496,16 +504,16 @@ if env["PLATFORM"] == "win32" : def signToolAction(target = None, source = None, env = None): signresult = 0 for x in range (1, 4) : - print "Attemping to sign the packages [%s]" % x + print("Attemping to sign the packages [%s]" % x) signresult = env.Execute('signtool.exe sign /fd SHA256 /f "${SIGNTOOL_KEY_PFX}" /t "${SIGNTOOL_TIMESTAMP_URL}" /d "Swift Installer" ' + str(target[0])) if signresult != 1 : break #If all 3 attemps to sign the package failed, stop the build. if signresult == 1 : - print "Error: The build has failed to sign the installer package" + print("Error: The build has failed to sign the installer package") Exit(1) if signresult == 2 : - print "Signing was completed with warnings." + print("Signing was completed with warnings.") myenv.AddPostAction(lightTask, signToolAction) diff --git a/Swift/SConscript b/Swift/SConscript index b211435..30b09e0 100644 --- a/Swift/SConscript +++ b/Swift/SConscript @@ -7,17 +7,17 @@ SConscript("Controllers/SConscript") if env["SCONS_STAGE"] == "build" : if not GetOption("help") and not env.get("HAVE_QT", 0) : if "Swift" in env["PROJECTS"] : - print "Warning: Swift requires Qt. Not building the Swift Qt application." + print("Warning: Swift requires Qt. Not building the Swift Qt application.") env["PROJECTS"].remove("Swift") elif not GetOption("help") and env["target"] == "native" and "Swift" in env["PROJECTS"] : try : SConscript("QtUI/SConscript") except Exception as e: - print "Warning: %s" % str(e) + print("Warning: %s" % str(e)) env["PROJECTS"].remove("Swift") if "Swift" in env["PROJECTS"] and env["BOOST_1_64_DETECTED"] and not env.get("allow_boost_1_64") and not env.GetOption("clean") : #Version 1.64 has some issues with the serialization of boost::optional, see https://svn.boost.org/trac10/ticket/13050 - print "Boost 1.64 has been detected. It is not recommended to use this version due to a regression within the library. Swift has been removed from the current build. You can still use this version by setting allow_boost_1_64 to true, but recent chats and highlighting rules will reset." + print("Boost 1.64 has been detected. It is not recommended to use this version due to a regression within the library. Swift has been removed from the current build. You can still use this version by setting allow_boost_1_64 to true, but recent chats and highlighting rules will reset.") env["PROJECTS"].remove("Swift") if env["help2man"]: SConscript("Packaging/SConscript") \ No newline at end of file diff --git a/Swiften/SConscript b/Swiften/SConscript index f52637b..c2536f7 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -12,7 +12,7 @@ external_swiften_dep_modules = ["BOOST"] if env["SCONS_STAGE"] == "flags" : env["SWIFTEN_DLL"] = env["swiften_dll"] env["SWIFTEN_VERSION"] = Version.getBuildVersion(env.Dir("#").abspath, "swift") - version_match = re.match("(\d+)\.(\d+).*", env["SWIFTEN_VERSION"]) + version_match = re.match(r"(\d+)\.(\d+).*", env["SWIFTEN_VERSION"]) if version_match : env["SWIFTEN_VERSION_MAJOR"] = int(version_match.group(1)) env["SWIFTEN_VERSION_MINOR"] = int(version_match.group(2))