|
|
|
# This script generates the PyKDE configuration and generates the Makefiles.
|
|
|
|
#
|
|
|
|
# Copyright (c) 2004
|
|
|
|
# Riverbank Computing Limited <info@riverbankcomputing.co.uk>
|
|
|
|
# Jim Bublitz <jbublitz@nwinternet.com>
|
|
|
|
#
|
|
|
|
# This file is part of PyKDE.
|
|
|
|
#
|
|
|
|
# This copy of PyKDE is free software; you can redistribute it and/or modify it
|
|
|
|
# under the terms of the GNU General Public License as published by the Free
|
|
|
|
# Software Foundation; either version 2, or (at your option) any later
|
|
|
|
# version.
|
|
|
|
#
|
|
|
|
# PyKDE is supplied in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
|
|
# details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License along with
|
|
|
|
# PyKDE; see the file LICENSE. If not, write to the Free Software Foundation,
|
|
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import os
|
|
|
|
import string
|
|
|
|
import glob
|
|
|
|
import getopt
|
|
|
|
import shutil
|
|
|
|
import py_compile
|
|
|
|
|
|
|
|
try:
|
|
|
|
import sipconfig
|
|
|
|
except:
|
|
|
|
print ("Can't find sipconfig.py (expected in sys.path)")
|
|
|
|
print ("Have you built the correct version of sip?")
|
|
|
|
sys.exit (-1)
|
|
|
|
|
|
|
|
try:
|
|
|
|
import pyqtconfig
|
|
|
|
except:
|
|
|
|
sipconfig.error ("Can't find pyqtconfig.py in sys.path - exiting")
|
|
|
|
|
|
|
|
topsrcdir = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
has_objdir = topsrcdir != os.path.abspath(os.path.curdir)
|
|
|
|
if not has_objdir:
|
|
|
|
topsrcdir = None
|
|
|
|
|
|
|
|
def srcPath(filename):
|
|
|
|
if topsrcdir is not None:
|
|
|
|
return os.path.join(topsrcdir, filename)
|
|
|
|
return filename
|
|
|
|
|
|
|
|
topsrcdir = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
has_objdir = topsrcdir != os.path.abspath(os.path.curdir)
|
|
|
|
if not has_objdir:
|
|
|
|
topsrcdir = None
|
|
|
|
|
|
|
|
def srcPath(filename):
|
|
|
|
if topsrcdir is not None:
|
|
|
|
return os.path.join(topsrcdir, filename)
|
|
|
|
return filename
|
|
|
|
|
|
|
|
# Get the SIP configuration.
|
|
|
|
sipcfg = sipconfig.Configuration()
|
|
|
|
pyqtcfg = pyqtconfig.Configuration ()
|
|
|
|
|
|
|
|
# Initialise the globals.
|
|
|
|
pykde_version = 0x031006
|
|
|
|
pykde_version_str = "3.16.6"
|
|
|
|
kde_version = None
|
|
|
|
kde_version_str = None
|
|
|
|
kde_version_sfx = None
|
|
|
|
kde_version_extra = None
|
|
|
|
kde_max_version = 0x030503
|
|
|
|
|
|
|
|
sip_min_v4_version = 0x040900
|
|
|
|
qt_min_version = 0x030200
|
|
|
|
pyqt_min_version = 0x031000
|
|
|
|
|
|
|
|
kde_sip_flags = []
|
|
|
|
|
|
|
|
# Command line options.
|
|
|
|
opt_pykdemoddir = sipcfg.default_mod_dir
|
|
|
|
opt_pykdesipdir = sipcfg.default_sip_dir
|
|
|
|
opt_debug = 0
|
|
|
|
opt_concat = None
|
|
|
|
opt_split = 1
|
|
|
|
opt_releasegil = 0
|
|
|
|
opt_tracing = 0
|
|
|
|
opt_static = 0
|
|
|
|
opt_tdebasedir = None
|
|
|
|
opt_kdelibdir = None
|
|
|
|
opt_kdeincdir = None
|
|
|
|
opt_dep_warnings = 0
|
|
|
|
opt_libdir = "lib"
|
|
|
|
opt_dist_name = ""
|
|
|
|
|
|
|
|
pykde_modules = ["dcop", "tdecore", "tdefx", "tdeui", "kio", "kresources", "kabc", "kutils", "kfile", "kparts",\
|
|
|
|
"khtml", "kspell", "tdeprint", "kmdi"] #, "kspell2"]
|
|
|
|
|
|
|
|
pykde_imports = {
|
|
|
|
"dcop": ["qt"],
|
|
|
|
"tdecore": ["qt", "dcop"],
|
|
|
|
# "tdesu": ["qt", "dcop", "tdecore"],
|
|
|
|
"tdefx": ["qt", "dcop", "tdecore"],
|
|
|
|
"tdeui": ["qt", "qtxml", "dcop", "tdecore", "tdefx"],
|
|
|
|
"kio": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui"],
|
|
|
|
"kresources": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "kio"],
|
|
|
|
"kabc": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "kio", "kresources"],
|
|
|
|
"kutils": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "kio"],
|
|
|
|
"kfile": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "kio"],
|
|
|
|
"kparts": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "kio"],
|
|
|
|
"khtml": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "kutils", "kio", "kparts"],
|
|
|
|
"kspell": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "kio", "kfile"],
|
|
|
|
"tdeprint": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui"],
|
|
|
|
"kmdi": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui", "kio", "kparts"],
|
|
|
|
"kspell2": ["qt", "qtxml", "dcop", "tdecore", "tdefx", "tdeui"]
|
|
|
|
}
|
|
|
|
|
|
|
|
kde_includes = {
|
|
|
|
"dcop": None,
|
|
|
|
"tdecore": None,
|
|
|
|
# "tdesu": ["tdesu"],
|
|
|
|
"tdefx": None,
|
|
|
|
"tdeui": None,
|
|
|
|
"kio": ["kio"],
|
|
|
|
"kresources": ["kio", "../kio", "kresources"],
|
|
|
|
"kabc": ["kio", "../kio", "kresources", "kabc"],
|
|
|
|
"kfile": ["kio", "../kio"],
|
|
|
|
"kparts": ["kio", "../kio", "kparts"],
|
|
|
|
"khtml": ["kio", "../kio", "kparts", "dom"],
|
|
|
|
"kspell": ["kio"],
|
|
|
|
"tdeprint": ["tdeprint"],
|
|
|
|
"kmdi": ["kmdi", "kio", "../kio", "kparts"],
|
|
|
|
"kutils": ["kio", "../kio"] #,
|
|
|
|
# "kspell2": None
|
|
|
|
}
|
|
|
|
|
|
|
|
postProcess = {
|
|
|
|
"dcop": None,
|
|
|
|
"tdecore": [["-p ", "tdecore", "-o", "appQuit", "tdecore.py"],
|
|
|
|
#["-p ", "tdecore", "-o", "fixTQVariant", "tdecore.sbf"],
|
|
|
|
["-p ", "tdecore", "-o", "fixSignal", "tdecorepart0.*"]],
|
|
|
|
# "tdesu": None,
|
|
|
|
"tdefx": None,
|
|
|
|
"tdeui": None, #[["-p ", "tdeui", "-o", "shpix", "siptdeuiKSharedPixmap.cpp"]],
|
|
|
|
"kresources": None,
|
|
|
|
"kabc": None,
|
|
|
|
"kio": None,
|
|
|
|
"kfile": None,
|
|
|
|
"kparts": None,
|
|
|
|
"khtml": None,
|
|
|
|
"kspell": None,
|
|
|
|
"tdeprint": None,
|
|
|
|
"kmdi": None,
|
|
|
|
"kutils": None #,
|
|
|
|
# "kspell2": None
|
|
|
|
}
|
|
|
|
|
|
|
|
opt_startModName = ""
|
|
|
|
opt_startmod = 0
|
|
|
|
opt_endmod = len (pykde_modules)
|
|
|
|
|
|
|
|
def check_gcc ():
|
|
|
|
global opt_concat
|
|
|
|
|
|
|
|
os.system ("gcc -dumpversion > gccvers.txt")
|
|
|
|
m = open ('gccvers.txt', 'r')
|
|
|
|
vers = m.read ().strip ()
|
|
|
|
m.close ()
|
|
|
|
os.unlink ('gccvers.txt')
|
|
|
|
print "gcc version %s" % vers
|
|
|
|
|
|
|
|
if opt_concat == None:
|
|
|
|
if vers < "4.0.0" or vers >= "4.0.3":
|
|
|
|
opt_concat = 1
|
|
|
|
else:
|
|
|
|
opt_concat = 0
|
|
|
|
|
|
|
|
if opt_concat == 1:
|
|
|
|
print "concatenating files"
|
|
|
|
else:
|
|
|
|
print "no concatenation"
|
|
|
|
print
|
|
|
|
|
|
|
|
def init_and_check_sanity ():
|
|
|
|
""" Do some initialization and check various versions and
|
|
|
|
attributes of sip and PyTQt installations
|
|
|
|
"""
|
|
|
|
|
|
|
|
check_gcc ()
|
|
|
|
|
|
|
|
# Check SIP is new enough.
|
|
|
|
if sipcfg.sip_version_str[:8] != "snapshot":
|
|
|
|
minv = None
|
|
|
|
|
|
|
|
if sipcfg.sip_version < sip_min_v4_version:
|
|
|
|
minv = sip_min_v4_version
|
|
|
|
|
|
|
|
if minv:
|
|
|
|
sipcfg.error("This version of PyKDE retquires SIP v%s or later" % sipcfg.version_to_string(minv))
|
|
|
|
|
|
|
|
# Check SIP has TQt support enabled and check version
|
|
|
|
if pyqtcfg.qt_version == 0:
|
|
|
|
sipconfig.error("SIP has been built with TQt support disabled.")
|
|
|
|
if pyqtcfg.qt_version < qt_min_version:
|
|
|
|
sipconfig.error("SIP has been built with an unsupported TQt version (%s)"\
|
|
|
|
% sipcfg.version_to_string (sipcfg.qt_version))
|
|
|
|
|
|
|
|
# Check PyTQt built with libtqt-mt
|
|
|
|
if pyqtcfg.qt_threaded == 0:
|
|
|
|
sipconfig.error ("PyKDE retquires a threaded TQt version (libtqt-mt)")
|
|
|
|
|
|
|
|
# Check PyTQt version
|
|
|
|
if pyqtcfg.pyqt_version < pyqt_min_version:
|
|
|
|
sipcfg.error("This version of PyKDE retquires PyTQt v%s or later"\
|
|
|
|
% pyqtcfg.version_to_string(pyqtcfg.pyqt_version))
|
|
|
|
|
|
|
|
# find the libs, includes, and version info
|
|
|
|
check_kde_installation ()
|
|
|
|
|
|
|
|
def usage(rcode = 2):
|
|
|
|
"""Display a usage message and exit.
|
|
|
|
|
|
|
|
rcode is the return code passed back to the calling process.
|
|
|
|
"""
|
|
|
|
print "Usage:"
|
|
|
|
print " python configure.py [-h] [-c] [-d dir] [-g] [-j #] [-k] [-n dir] [-o dir] [-r] [-u] [-v dir] [-z file]"
|
|
|
|
print "where:"
|
|
|
|
print " -h displays this help message"
|
|
|
|
print " -c concatenates each module's C/C++ source files [default]"
|
|
|
|
print " -d dir where the PyKDE modules will be installed [default %s]" % opt_pykdemoddir
|
|
|
|
print " -g always release the GIL (SIP v3.x behaviour)"
|
|
|
|
print " -i no concatenation of each module's C/C++ source files"
|
|
|
|
print " -j # splits the concatenated C++ source files into # pieces [default 1]"
|
|
|
|
print " -k dir the KDE base directory"
|
|
|
|
print " -L dir the library directory name [default lib]"
|
|
|
|
print " -n dir the directory containing the KDE lib files"
|
|
|
|
print " -o dir the directory containing the KDE header files"
|
|
|
|
print " -r generates code with tracing enabled [default disabled]"
|
|
|
|
print " -u build with debugging symbols"
|
|
|
|
print " -v dir where the PyKDE .sip files will be installed [default %s]" % opt_pykdesipdir
|
|
|
|
print " -w turn on KDE deprecated object warnings when compiling [default off]"
|
|
|
|
print " -z file the name of a file containing command line flags"
|
|
|
|
|
|
|
|
sys.exit(rcode)
|
|
|
|
|
|
|
|
|
|
|
|
def inform_user(stage):
|
|
|
|
"""Tell the user the option values that are going to be used.
|
|
|
|
"""
|
|
|
|
if stage == 0:
|
|
|
|
print
|
|
|
|
print " PyKDE version %s" % pykde_version_str
|
|
|
|
print " -------"
|
|
|
|
print
|
|
|
|
sipconfig.inform ("Python include directory is %s" % sipcfg.py_inc_dir)
|
|
|
|
sipconfig.inform ("Python version is %s" % sipconfig.version_to_string (sipcfg.py_version))
|
|
|
|
print
|
|
|
|
sipconfig.inform ("sip version is %s (%s)" % (sipcfg.sip_version_str,
|
|
|
|
sipconfig.version_to_string (sipcfg.sip_version)))
|
|
|
|
print
|
|
|
|
sipconfig.inform ("TQt directory is %s" % pyqtcfg.qt_dir)
|
|
|
|
sipconfig.inform ("TQt version is %s" % sipconfig.version_to_string (pyqtcfg.qt_version))
|
|
|
|
print
|
|
|
|
sipconfig.inform ("PyTQt directory is %s" % pyqtcfg.pyqt_sip_dir)
|
|
|
|
sipconfig.inform ("PyTQt version is %s (%s)" % (pyqtcfg.pyqt_version_str,
|
|
|
|
sipconfig.version_to_string (pyqtcfg.pyqt_version)))
|
|
|
|
print
|
|
|
|
|
|
|
|
elif stage == 1:
|
|
|
|
sipconfig.inform ("KDE base directory is %s" % opt_tdebasedir)
|
|
|
|
sipconfig.inform ("KDE include directory is %s" % opt_kdeincdir)
|
|
|
|
sipconfig.inform ("KDE lib directory is %s" % opt_kdelibdir)
|
|
|
|
sipconfig.inform ("lib directory is %s" % opt_libdir)
|
|
|
|
|
|
|
|
elif stage == 2:
|
|
|
|
sipconfig.inform ("KDE version is %s (0x%x)" % (kde_version_str, kde_version))
|
|
|
|
print
|
|
|
|
|
|
|
|
sipconfig.inform("PyKDE modules will be installed in %s" % opt_pykdemoddir)
|
|
|
|
sipconfig.inform("PyKDE .sip files will be installed in %s" % opt_pykdesipdir)
|
|
|
|
print
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_config(module, template):
|
|
|
|
"""Create the PyKDE configuration module so that it can be imported by build
|
|
|
|
scripts.
|
|
|
|
|
|
|
|
module is the module file name.
|
|
|
|
template is the template file name.
|
|
|
|
"""
|
|
|
|
sipconfig.inform("Creating %s..." % module)
|
|
|
|
|
|
|
|
content = {
|
|
|
|
"pykde_version": pykde_version,
|
|
|
|
"pykde_version_str": pykde_version_str,
|
|
|
|
"kde_version": kde_version,
|
|
|
|
"kde_version_str": kde_version_str,
|
|
|
|
"kde_version_sfx": kde_version_sfx,
|
|
|
|
"kde_version_extra": kde_version_extra,
|
|
|
|
# "pykde_bin_dir": opt_pykdebindir,
|
|
|
|
"pykde_mod_dir": opt_pykdemoddir,
|
|
|
|
"pykde_sip_dir": opt_pykdesipdir,
|
|
|
|
"pykde_modules": pykde_modules,
|
|
|
|
"pykde_kde_sip_flags": kde_sip_flags,
|
|
|
|
"tdebasedir": opt_tdebasedir,
|
|
|
|
"kdelibdir": opt_kdelibdir,
|
|
|
|
"libdir": opt_libdir,
|
|
|
|
"kdeincdir": opt_kdeincdir,
|
|
|
|
"pykde_modules": pykde_modules,
|
|
|
|
"dist_name": opt_dist_name
|
|
|
|
}
|
|
|
|
|
|
|
|
sipconfig.create_config_module(module, template, content)
|
|
|
|
|
|
|
|
def getKDEVersion (versFile):
|
|
|
|
if not os.path.isfile (versFile):
|
|
|
|
return
|
|
|
|
|
|
|
|
major = None
|
|
|
|
minor = None
|
|
|
|
micro = None
|
|
|
|
|
|
|
|
global kde_version, kde_version_str, kde_version_sfx, kde_version_extra
|
|
|
|
|
|
|
|
f = open (versFile)
|
|
|
|
l = f.readline ()
|
|
|
|
ok = 0
|
|
|
|
|
|
|
|
while not ok and l:
|
|
|
|
wl = string.split(l)
|
|
|
|
if len(wl) == 3 and wl[0] == "#define":
|
|
|
|
if wl[1] == "TDE_VERSION_MAJOR":
|
|
|
|
major = string.strip (wl[2])
|
|
|
|
|
|
|
|
if wl[1] == "TDE_VERSION_MINOR":
|
|
|
|
minor = string.strip (wl[2])
|
|
|
|
|
|
|
|
if wl[1] == "TDE_VERSION_RELEASE":
|
|
|
|
micro = string.strip (wl[2])
|
|
|
|
|
|
|
|
if major and minor and micro:
|
|
|
|
ok = 1
|
|
|
|
|
|
|
|
l = f.readline()
|
|
|
|
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
if micro >= "90" and minor == "2":
|
|
|
|
micro = "0"
|
|
|
|
minor = "3"
|
|
|
|
|
|
|
|
kde_version = (int (major) << 16) + (int (minor) << 8) + int (micro)
|
|
|
|
|
|
|
|
if kde_version > kde_max_version:
|
|
|
|
print
|
|
|
|
sipconfig.inform ("*** True KDE version is %s -- building for KDE %s ***" % (hex (kde_version), hex (kde_max_version)))
|
|
|
|
print
|
|
|
|
kde_version = kde_max_version
|
|
|
|
major = hex ((kde_version & 0xff0000) >> 16) [ 2:]
|
|
|
|
minor = hex ((kde_version & 0x00ff00) >> 8) [ 2:]
|
|
|
|
micro = hex (kde_version & 0x0000ff) [ 2:]
|
|
|
|
|
|
|
|
if ok:
|
|
|
|
kde_version_str = string.join ([major, minor, micro], ".")
|
|
|
|
kde_version_sfx = string.join (["-kde", major, minor, micro, ".diff"], "")
|
|
|
|
kde_version_extra = string.join (["kde", major, minor, micro], "")
|
|
|
|
else:
|
|
|
|
sipconfig.error ("KDE version not found in %s" % versFile)
|
|
|
|
|
|
|
|
global postProcess
|
|
|
|
|
|
|
|
def search (target, searchPath):
|
|
|
|
if not searchPath:
|
|
|
|
return
|
|
|
|
|
|
|
|
path = None
|
|
|
|
for searchEntry in searchPath:
|
|
|
|
if os.path.isdir (searchEntry)\
|
|
|
|
and (not target or os.path.isfile (os.path.join (searchEntry, target))):
|
|
|
|
path = searchEntry
|
|
|
|
break
|
|
|
|
|
|
|
|
return path
|
|
|
|
|
|
|
|
def discoverKDE3 ():
|
|
|
|
global opt_kdeincdir, opt_tdebasedir, opt_kdelibdir, opt_libdir
|
|
|
|
|
|
|
|
if not opt_tdebasedir:
|
|
|
|
kdeSearchPaths = []
|
|
|
|
libSearchPaths = []
|
|
|
|
incSearchPaths = []
|
|
|
|
|
|
|
|
try:
|
|
|
|
kdeSearchPaths.append (os.environ ["KDEDIR"])
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
kdeSearchPaths.append (os.path.join ("/opt", "trinity"))
|
|
|
|
kdeSearchPaths.append ("/usr")
|
|
|
|
|
|
|
|
opt_tdebasedir = search (None, kdeSearchPaths)
|
|
|
|
|
|
|
|
if not opt_kdelibdir:
|
|
|
|
libSearchPaths = [os.path.join (opt_tdebasedir, "lib"), os.path.join (opt_tdebasedir, "lib64"), os.path.join (opt_tdebasedir, opt_libdir)]
|
|
|
|
# print opt_libdir
|
|
|
|
opt_kdelibdir = search ("libtdecore.so", libSearchPaths)
|
|
|
|
|
|
|
|
if not opt_kdeincdir:
|
|
|
|
incSearchPaths = [os.path.join (opt_tdebasedir, "include")]
|
|
|
|
incSearchPaths.append (os.path.join (opt_tdebasedir, "include", "kde")) # Red Hat
|
|
|
|
opt_kdeincdir = search ("kapplication.h", incSearchPaths)
|
|
|
|
|
|
|
|
def check_kde_installation():
|
|
|
|
"""Check the KDE installation and get the version number
|
|
|
|
|
|
|
|
"""
|
|
|
|
# Check the KDE header files have been installed.
|
|
|
|
|
|
|
|
discoverKDE3 ()
|
|
|
|
|
|
|
|
if not opt_tdebasedir:
|
|
|
|
sipconfig.error ("Couldn't locate KDE3 base directory")
|
|
|
|
|
|
|
|
if not opt_kdeincdir:
|
|
|
|
sipconfig.error ("Couldn't locate KDE3 include directory (%s is KDE base)" % opt_tdebasedir)
|
|
|
|
|
|
|
|
if not opt_kdelibdir:
|
|
|
|
sipconfig.error ("Couldn't locate KDE3 lib directory (%s is KDE base)" % opt_tdebasedir)
|
|
|
|
|
|
|
|
tdeversion_h = os.path.join(opt_kdeincdir, "tdeversion.h")
|
|
|
|
|
|
|
|
inform_user (1)
|
|
|
|
|
|
|
|
if not os.access(tdeversion_h, os.F_OK):
|
|
|
|
sipconfig.error("tdeversion.h could not be found in %s." % opt_kdeincdir)
|
|
|
|
|
|
|
|
# Get the KDE version number.
|
|
|
|
getKDEVersion(tdeversion_h)
|
|
|
|
|
|
|
|
inform_user (2)
|
|
|
|
|
|
|
|
def create_top_level (mname):
|
|
|
|
""" Create the top level sip file <mname>mod.sip from <mname>mod.sip-in
|
|
|
|
and add/delete any %Included sip files per the current KDE version
|
|
|
|
"""
|
|
|
|
diff = srcPath(os.path.join ("sip", mname, mname + kde_version_sfx))
|
|
|
|
plus = []
|
|
|
|
minus = []
|
|
|
|
if os.path.exists (diff):
|
|
|
|
d = open (diff)
|
|
|
|
line = d.readline()
|
|
|
|
while line:
|
|
|
|
if string.find (line, "+") == 0:
|
|
|
|
plus.append (line [2:])
|
|
|
|
elif string.find (line, "-") == 0:
|
|
|
|
minus.append (line [2:])
|
|
|
|
|
|
|
|
line = d.readline()
|
|
|
|
|
|
|
|
sipin = open (srcPath(os.path.join ("sip", mname, mname + "mod.sip.in")))
|
|
|
|
sipout = open (srcPath(os.path.join ("sip", mname, mname + "mod.sip")), "w")
|
|
|
|
|
|
|
|
line = sipin.readline()
|
|
|
|
while line:
|
|
|
|
if string.find (line, "%Include") == 0:
|
|
|
|
inclFound = 1
|
|
|
|
if minus and line in minus:
|
|
|
|
line = sipin.readline()
|
|
|
|
continue
|
|
|
|
sipout.write (line)
|
|
|
|
elif string.find (line, "@mark@") == 0:
|
|
|
|
for p in plus:
|
|
|
|
sipout.write (p)
|
|
|
|
elif mname == "kabc" and kde_version < 0x030200 and string.find (line, "kresourcesmod.sip") >= 0:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
sipout.write (line)
|
|
|
|
|
|
|
|
line = sipin.readline()
|
|
|
|
|
|
|
|
sipin.close ()
|
|
|
|
sipout.close ()
|
|
|
|
|
|
|
|
if mname == "khtml":
|
|
|
|
# PyKDE < 3.3.0 doesn't provide kutils (and khtml doesn't need it)
|
|
|
|
sippath = srcPath(os.path.join ("sip", mname))
|
|
|
|
if kde_version < 0x030300:
|
|
|
|
sipin = open (os.path.join (sippath, mname + "mod.sip"))
|
|
|
|
sipout = open (os.path.join (sippath, mname + "mod.sip.new"), "w")
|
|
|
|
for line in sipin:
|
|
|
|
if line.find ("kutilsmod.sip") > 0:
|
|
|
|
continue
|
|
|
|
sipout.write (line)
|
|
|
|
sipin.close ()
|
|
|
|
sipout.close ()
|
|
|
|
os.unlink (os.path.join (sippath, mname + "mod.sip"))
|
|
|
|
os.rename (os.path.join (sippath, mname + "mod.sip.new"), os.path.join (sippath, mname + "mod.sip"))
|
|
|
|
|
|
|
|
os.system ("cp %s %s" % (os.path.join (sippath, "khtml_part.sip.323"), os.path.join (sippath, "khtml_part.sip")))
|
|
|
|
|
|
|
|
else:
|
|
|
|
os.system ("cp %s %s" % (os.path.join (sippath, "khtml_part.sip.330"), os.path.join (sippath, "khtml_part.sip")))
|
|
|
|
|
|
|
|
|
|
|
|
def check_distribution ():
|
|
|
|
dist = glob.glob ("/etc/*-release")
|
|
|
|
|
|
|
|
kde_sip_flags.append ("-t")
|
|
|
|
kde_sip_flags.append ("ALL")
|
|
|
|
|
|
|
|
for file in dist:
|
|
|
|
if file.find ("andrake") > 0:
|
|
|
|
kde_sip_flags.remove ("ALL")
|
|
|
|
kde_sip_flags.append ("D_MANDRAKE")
|
|
|
|
|
|
|
|
def set_sip_flags():
|
|
|
|
"""Set the SIP platform, version and feature flags.
|
|
|
|
"""
|
|
|
|
global kde_sip_flags
|
|
|
|
|
|
|
|
check_distribution ()
|
|
|
|
|
|
|
|
kde_sip_flags.append (pyqtcfg.pyqt_qt_sip_flags)
|
|
|
|
|
|
|
|
kdetags = {
|
|
|
|
0x030001: "KDE_3_0_0",
|
|
|
|
0x030003: "KDE_3_0_1",
|
|
|
|
0x030100: "KDE_3_0_3",
|
|
|
|
0x030101: "KDE_3_1_0",
|
|
|
|
0x030102: "KDE_3_1_1",
|
|
|
|
0x030103: "KDE_3_1_2",
|
|
|
|
0x030104: "KDE_3_1_3",
|
|
|
|
0x030105: "KDE_3_1_4",
|
|
|
|
0x030200: "KDE_3_1_5",
|
|
|
|
0x030201: "KDE_3_2_0",
|
|
|
|
0x030202: "KDE_3_2_1",
|
|
|
|
0x030203: "KDE_3_2_2",
|
|
|
|
0x030300: "KDE_3_2_3",
|
|
|
|
0x030301: "KDE_3_3_0",
|
|
|
|
0x030302: "KDE_3_3_1",
|
|
|
|
0x030400: "KDE_3_3_2",
|
|
|
|
0x030401: "KDE_3_4_0",
|
|
|
|
0x030402: "KDE_3_4_1",
|
|
|
|
0x030403: "KDE_3_4_2",
|
|
|
|
0x030500: "KDE_3_4_3",
|
|
|
|
0x030501: "KDE_3_5_0",
|
|
|
|
0x030502: "KDE_3_5_1",
|
|
|
|
0x030503: "KDE_3_5_2",
|
|
|
|
0x040000: "KDE_3_5_3"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
kde_sip_flags.append("-t")
|
|
|
|
kde_sip_flags.append(sipconfig.version_to_sip_tag(kde_version, kdetags, "KDE"))
|
|
|
|
|
|
|
|
|
|
|
|
def generate_code(mname, imports=None, extra_cflags=None, extra_cxxflags=None, extra_define=None, extra_include_dir=None, extra_lflags=None, extra_lib_dir=None, extra_lib=None, opengl=0, sip_flags=None):
|
|
|
|
"""Generate the code for a module.
|
|
|
|
|
|
|
|
mname is the name of the module.
|
|
|
|
imports is the list of PyTQt/PyKDE modules that this one %Imports.
|
|
|
|
extra_cflags is a string containing additional C compiler flags.
|
|
|
|
extra_cxxflags is a string containing additional C++ compiler flags.
|
|
|
|
extra_define is a name to add to the list of preprocessor defines.
|
|
|
|
extra_include_dir is the name of a directory to add to the list of include
|
|
|
|
directories.
|
|
|
|
extra_lflags is a string containing additional linker flags.
|
|
|
|
extra_lib_dir is the name of a directory to add to the list of library
|
|
|
|
directories.
|
|
|
|
extra_lib is the name of an extra library to add to the list of libraries.
|
|
|
|
opengl is set if the module needs OpenGL support.
|
|
|
|
sip_flags is the list of sip flags to use instead of the defaults.
|
|
|
|
"""
|
|
|
|
sipconfig.inform("Generating the C++ source for the %s module..." % mname)
|
|
|
|
|
|
|
|
create_top_level (mname)
|
|
|
|
try:
|
|
|
|
#create_top_level (mname)
|
|
|
|
pass
|
|
|
|
except:
|
|
|
|
sipconfig.error ("Couldn't create top level sip file for %s" % mname)
|
|
|
|
|
|
|
|
try:
|
|
|
|
shutil.rmtree(mname)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
try:
|
|
|
|
os.mkdir(mname)
|
|
|
|
except:
|
|
|
|
sipconfig.error("Unable to create the %s directory." % mname)
|
|
|
|
|
|
|
|
# Build the SIP command line.
|
|
|
|
argv = [sipcfg.sip_bin]
|
|
|
|
argv.extend(kde_sip_flags)
|
|
|
|
|
|
|
|
if opt_concat:
|
|
|
|
argv.append("-j")
|
|
|
|
if mname == "tdeui" and opt_split == 1:
|
|
|
|
splits = 2
|
|
|
|
else:
|
|
|
|
splits = opt_split
|
|
|
|
argv.append(str(splits))
|
|
|
|
|
|
|
|
if opt_tracing:
|
|
|
|
argv.append("-r")
|
|
|
|
|
|
|
|
if opt_releasegil:
|
|
|
|
argv.append("-g")
|
|
|
|
|
|
|
|
argv.append("-c")
|
|
|
|
argv.append(mname)
|
|
|
|
|
|
|
|
buildfile = os.path.join(mname, mname + ".sbf")
|
|
|
|
argv.append("-b")
|
|
|
|
argv.append(buildfile)
|
|
|
|
|
|
|
|
argv.append("-I")
|
|
|
|
argv.append(srcPath("sip"))
|
|
|
|
|
|
|
|
pyqtInclPathSeen = 0
|
|
|
|
for mod in pykde_imports [mname]:
|
|
|
|
if string.find (mod, "q") == 0 and not pyqtInclPathSeen:
|
|
|
|
argv.append ("-I")
|
|
|
|
argv.append (pyqtcfg.pyqt_sip_dir)
|
|
|
|
pyqtInclPathSeen = 1
|
|
|
|
|
|
|
|
elif mod == "dcop" or string.find (mod, "k") == 0 or string.find (mod, "tde") == 0:
|
|
|
|
subdir = os.path.join(srcPath("sip"), mod)
|
|
|
|
argv.append("-I")
|
|
|
|
argv.append(subdir)
|
|
|
|
|
|
|
|
# SIP assumes POSIX style path separators.
|
|
|
|
argv.append(srcPath(string.join(["sip", mname, mname + "mod.sip"], "/")))
|
|
|
|
|
|
|
|
# print string.join (argv)
|
|
|
|
# finally, run SIP and generate the C++ code
|
|
|
|
os.system (string.join(argv))
|
|
|
|
|
|
|
|
# post process the C++ code for QT_NO_TRANSLATION
|
|
|
|
if os.system (string.join ([sys.executable, srcPath("postproc")] + ['-p', mname, "-o", "tr", "*.cpp"])) != 0:
|
|
|
|
sipconfig.error ("Post processing of C++ code failed %s (tr)" % mname)
|
|
|
|
|
|
|
|
# Check the result.
|
|
|
|
if not os.access(buildfile, os.F_OK):
|
|
|
|
sipconfig.error("Unable to create the C++ code.")
|
|
|
|
|
|
|
|
if mname == "tdecore" and not opt_concat:
|
|
|
|
postProcess ["tdecore"][-1][-1] = "tdecorecmodule.*"
|
|
|
|
|
|
|
|
# Compile the Python stub.
|
|
|
|
if sipcfg.sip_version < 0x040000:
|
|
|
|
sipconfig.inform("Compiling %s.py..." % mname)
|
|
|
|
py_compile.compile(os.path.join(mname, mname + ".py"), os.path.join(mname, mname + ".pyc"))
|
|
|
|
elif mname == "tdecore":
|
|
|
|
postProcess ["tdecore"][-1][-1] = "sip" + postProcess ["tdecore"][-1][-1]
|
|
|
|
|
|
|
|
# needs to be here (not earlier) to catch .py files if any
|
|
|
|
if postProcess [mname]:
|
|
|
|
for s in postProcess [mname]:
|
|
|
|
if os.system (string.join ([sys.executable, srcPath("postproc")] + s)) != 0:
|
|
|
|
sipconfig.error ("Post processing of C++ code failed %s (%s)" % (mname, s [3]))
|
|
|
|
|
|
|
|
# Generate the Makefile.
|
|
|
|
sipconfig.inform("Creating the Makefile for the %s module..." % mname)
|
|
|
|
|
|
|
|
installs = []
|
|
|
|
if mname == "dcop":
|
|
|
|
if has_objdir:
|
|
|
|
installs.append ([[srcPath("extensions/dcopext.py"), srcPath("extensions/dcopexport.py")], opt_pykdemoddir])
|
|
|
|
else:
|
|
|
|
installs.append ([["../extensions/dcopext.py", "../extensions/dcopexport.py"], opt_pykdemoddir])
|
|
|
|
|
|
|
|
|
|
|
|
if sipcfg.sip_version >= 0x040000:
|
|
|
|
warnings = 1
|
|
|
|
else:
|
|
|
|
warnings = 0
|
|
|
|
installs.append([[mname + ".py", mname + ".pyc"], opt_pykdemoddir])
|
|
|
|
|
|
|
|
sipfiles = []
|
|
|
|
|
|
|
|
# for s in glob.glob("sip/*.sip"):
|
|
|
|
# sipfiles.append(os.path.join("..", "sip", os.path.basename(s)))
|
|
|
|
for s in os.listdir (srcPath(os.path.join ("sip", mname))):
|
|
|
|
if s.endswith (".sip"):
|
|
|
|
if has_objdir:
|
|
|
|
sipfiles.append(srcPath(os.path.join("sip", mname, os.path.basename(s))))
|
|
|
|
else:
|
|
|
|
sipfiles.append(os.path.join("..", "sip", mname, os.path.basename(s)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
installs.append([sipfiles, os.path.join(opt_pykdesipdir, mname)])
|
|
|
|
|
|
|
|
makefile = sipconfig.SIPModuleMakefile(
|
|
|
|
configuration = pyqtcfg,
|
|
|
|
build_file = mname + ".sbf",
|
|
|
|
dir = mname,
|
|
|
|
install_dir = opt_pykdemoddir,
|
|
|
|
installs = installs,
|
|
|
|
qt = 1,
|
|
|
|
opengl = opengl,
|
|
|
|
warnings = warnings,
|
|
|
|
static = opt_static,
|
|
|
|
debug = opt_debug,
|
|
|
|
)
|
|
|
|
|
|
|
|
if extra_cflags:
|
|
|
|
makefile.extra_cflags.append(extra_cflags)
|
|
|
|
|
|
|
|
if extra_cxxflags:
|
|
|
|
makefile.extra_cxxflags.append(extra_cxxflags)
|
|
|
|
|
|
|
|
if opt_dep_warnings == 0:
|
|
|
|
makefile.extra_cflags.append ("-Wno-deprecated-declarations")
|
|
|
|
makefile.extra_cxxflags.append ("-Wno-deprecated-declarations")
|
|
|
|
|
|
|
|
if extra_define:
|
|
|
|
makefile.extra_defines.append(extra_define)
|
|
|
|
|
|
|
|
if has_objdir:
|
|
|
|
makefile.extra_include_dirs.append (srcPath(os.path.join("extra", kde_version_extra)))
|
|
|
|
else:
|
|
|
|
makefile.extra_include_dirs.append (os.path.join ("..", "extra", kde_version_extra))
|
|
|
|
|
|
|
|
makefile.extra_include_dirs.append (opt_kdeincdir)
|
|
|
|
if kde_includes [mname]:
|
|
|
|
for incdir in kde_includes [mname]:
|
|
|
|
if "/" not in incdir:
|
|
|
|
makefile.extra_include_dirs.append (os.path.join (opt_kdeincdir, incdir))
|
|
|
|
else:
|
|
|
|
makefile.extra_include_dirs.append (incdir)
|
|
|
|
|
|
|
|
if extra_include_dir:
|
|
|
|
makefile.extra_include_dirs.append(extra_include_dir)
|
|
|
|
|
|
|
|
makefile.extra_include_dirs.append ("/usr/include/tqt")
|
|
|
|
|
|
|
|
if extra_lflags:
|
|
|
|
makefile.extra_lflags.append(extra_lflags)
|
|
|
|
|
|
|
|
makefile.extra_lib_dirs.append (opt_kdelibdir)
|
|
|
|
if extra_lib_dir:
|
|
|
|
makefile.extra_lib_dirs.append(extra_lib_dir)
|
|
|
|
|
|
|
|
if extra_lib == "dcop":
|
|
|
|
extra_lib = "DCOP"
|
|
|
|
elif extra_lib == "kfile":
|
|
|
|
extra_lib = "kio"
|
|
|
|
|
|
|
|
makefile.extra_libs.append(extra_lib)
|
|
|
|
if extra_lib == "tdefx":
|
|
|
|
makefile.extra_libs.append ("tdecore")
|
|
|
|
if extra_lib == "kspell":
|
|
|
|
makefile.extra_libs.append ("tdeui")
|
|
|
|
if extra_lib == "kabc" and kde_version >= 0x030200:
|
|
|
|
makefile.extra_libs.append ("kabc_file")
|
|
|
|
if extra_lib == "kparts" and kde_version >= 0x030500:
|
|
|
|
makefile.extra_lib_dirs.append (os.path.join (opt_kdelibdir, "trinity"))
|
|
|
|
|
|
|
|
if extra_lib == "tdeprint":
|
|
|
|
makefile.extra_cflags.append ("-fno-rtti")
|
|
|
|
makefile.extra_cxxflags.append ("-fno-rtti")
|
|
|
|
|
|
|
|
if sipcfg.sip_version < 0x040000 and imports:
|
|
|
|
# Inter-module links.
|
|
|
|
for im in imports:
|
|
|
|
makefile.extra_lib_dirs.insert(0, os.path.join("..", im))
|
|
|
|
makefile.extra_libs.insert(0, makefile.module_as_lib(im))
|
|
|
|
|
|
|
|
makefile.generate()
|
|
|
|
print
|
|
|
|
|
|
|
|
|
|
|
|
def create_makefiles():
|
|
|
|
"""Create the additional Makefiles.
|
|
|
|
"""
|
|
|
|
subdirs = pykde_modules[:]
|
|
|
|
|
|
|
|
sipconfig.inform("Creating top level Makefile...")
|
|
|
|
|
|
|
|
sipconfig.ParentMakefile(
|
|
|
|
configuration = pyqtcfg,
|
|
|
|
subdirs = subdirs,
|
|
|
|
installs= [("pykdeconfig.py", opt_pykdemoddir), (srcPath("contrib/kdepyuic"), sipcfg.default_bin_dir)]
|
|
|
|
).generate()
|
|
|
|
|
|
|
|
|
|
|
|
def fileOpts (fn):
|
|
|
|
try:
|
|
|
|
optfile = open (fn, 'r')
|
|
|
|
except:
|
|
|
|
error ("Could not open option file %s" % (fn))
|
|
|
|
|
|
|
|
opts = []
|
|
|
|
|
|
|
|
for line in optfile.readlines ():
|
|
|
|
if (line [0] == '#') or (line == '\n'):
|
|
|
|
continue
|
|
|
|
elif line [0] == '-':
|
|
|
|
opts.append ((line [0:2], string.strip (line [2:])))
|
|
|
|
else:
|
|
|
|
opts.append (("-" + line [0:1], string.strip (line [1:])))
|
|
|
|
|
|
|
|
print 'Additional options: ',
|
|
|
|
for opt, arg in opts:
|
|
|
|
print "%s %s " %(opt, arg)
|
|
|
|
print
|
|
|
|
|
|
|
|
return opts
|
|
|
|
|
|
|
|
def main(argv):
|
|
|
|
"""Create the configuration module module.
|
|
|
|
|
|
|
|
argv is the list of command line arguments.
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
optlist, args = getopt.getopt(argv[1:], "hcd:gij:k:L:l:n:o:ruv:wz:")
|
|
|
|
except getopt.GetoptError:
|
|
|
|
usage()
|
|
|
|
|
|
|
|
global opt_pykdemoddir, opt_pykdesipdir
|
|
|
|
global opt_debug, opt_concat, opt_releasegil
|
|
|
|
global opt_split, opt_tracing, opt_startModName
|
|
|
|
global opt_startmod, opt_endmod
|
|
|
|
global opt_tdebasedir, opt_kdelibdir, opt_kdeincdir, opt_libdir
|
|
|
|
global pykde_modules, opt_dep_warnings, opt_dist_name
|
|
|
|
global pykde_imports, kde_includes
|
|
|
|
|
|
|
|
# Look for '-z' first and process that switch
|
|
|
|
# (command line switches override file switches)
|
|
|
|
for opt, arg in optlist:
|
|
|
|
if opt == "-z":
|
|
|
|
optlist = fileOpts (arg) + optlist
|
|
|
|
break
|
|
|
|
elif opt == "-h":
|
|
|
|
usage (0)
|
|
|
|
else:
|
|
|
|
if args: usage()
|
|
|
|
|
|
|
|
for opt, arg in optlist:
|
|
|
|
if opt == "-h":
|
|
|
|
usage(0)
|
|
|
|
|
|
|
|
# turns on concatentation (on by default, here for consistency)
|
|
|
|
elif opt == "-c":
|
|
|
|
opt_concat = 1
|
|
|
|
|
|
|
|
elif opt == "-d":
|
|
|
|
opt_pykdemoddir = arg
|
|
|
|
elif opt == "-g":
|
|
|
|
opt_releasegil = 1
|
|
|
|
|
|
|
|
# turns off concatenation (on by default)
|
|
|
|
elif opt == "-i":
|
|
|
|
opt_concat = 0
|
|
|
|
|
|
|
|
elif opt == "-j":
|
|
|
|
try:
|
|
|
|
opt_split = int(arg)
|
|
|
|
except:
|
|
|
|
usage()
|
|
|
|
|
|
|
|
elif opt == "-k":
|
|
|
|
opt_tdebasedir = arg
|
|
|
|
|
|
|
|
elif opt == "-L":
|
|
|
|
opt_libdir = arg
|
|
|
|
|
|
|
|
# allows build of single module (-lmodule) or all modules
|
|
|
|
# beginning at specified module (-lmodule:)
|
|
|
|
elif opt == "-l":
|
|
|
|
opt_startModName = arg
|
|
|
|
|
|
|
|
elif opt == "-n":
|
|
|
|
opt_kdelibdir = arg
|
|
|
|
elif opt == "-o":
|
|
|
|
opt_kdeincdir = arg
|
|
|
|
elif opt == "-r":
|
|
|
|
opt_tracing = 1
|
|
|
|
elif opt == "-u":
|
|
|
|
opt_debug = 1
|
|
|
|
elif opt == "-v":
|
|
|
|
opt_pykdesipdir = arg
|
|
|
|
elif opt == "-w":
|
|
|
|
opt_dep_warnings = 1
|
|
|
|
|
|
|
|
inform_user (0)
|
|
|
|
init_and_check_sanity ()
|
|
|
|
|
|
|
|
# Set the SIP platform, version and feature flags.
|
|
|
|
if kde_version < 0x030200:
|
|
|
|
pykde_modules.remove ("kmdi")
|
|
|
|
pykde_modules.remove ("kresources")
|
|
|
|
pykde_imports ["kabc"].remove ("kresources")
|
|
|
|
kde_includes ["kabc"].remove ("kresources")
|
|
|
|
|
|
|
|
if kde_version < 0x030300:
|
|
|
|
pykde_modules.remove ("kutils")
|
|
|
|
# pykde_modules.remove ("kspell2")
|
|
|
|
pykde_imports ["khtml"].remove ("kutils")
|
|
|
|
|
|
|
|
opt_endmod = len (pykde_modules)
|
|
|
|
if opt_startModName != "":
|
|
|
|
if opt_startModName in pykde_modules:
|
|
|
|
single = opt_startModName [-1] != ":"
|
|
|
|
if not single:
|
|
|
|
opt_startModName = opt_startModName [:-1]
|
|
|
|
|
|
|
|
try:
|
|
|
|
opt_startmod = pykde_modules.index (opt_startModName)
|
|
|
|
if single:
|
|
|
|
opt_endmod = opt_startmod + 1
|
|
|
|
except:
|
|
|
|
sipconfig.error ("%s is not a PyKDE module" % opt_startModName)
|
|
|
|
|
|
|
|
print "PyKDE modules to be built:\n %s\n" % string.join(pykde_modules [opt_startmod:opt_endmod])
|
|
|
|
|
|
|
|
set_sip_flags()
|
|
|
|
|
|
|
|
for module in pykde_modules [opt_startmod:opt_endmod]:
|
|
|
|
generate_code (module, pykde_imports [module], extra_lib = module)
|
|
|
|
|
|
|
|
# Create the additional Makefiles.
|
|
|
|
create_makefiles()
|
|
|
|
|
|
|
|
# Install the configuration module.
|
|
|
|
create_config("pykdeconfig.py", srcPath("pykdeconfig.py.in"))
|
|
|
|
|
|
|
|
|
|
|
|
def reporting_msg ():
|
|
|
|
print """
|
|
|
|
If reporting errors, paste all of the output above into your
|
|
|
|
message and post to the PyKDE mailing list at:
|
|
|
|
|
|
|
|
mailto: PyKDE@mats.imk.fraunhofer.de
|
|
|
|
subscribe: http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
|
|
|
|
|
|
|
|
You can redirect the output into a file (> output.txt) if needed
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
# The script starts here.
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
try:
|
|
|
|
main(sys.argv)
|
|
|
|
except SystemExit:
|
|
|
|
reporting_msg ()
|
|
|
|
raise
|
|
|
|
except:
|
|
|
|
reporting_msg ()
|
|
|
|
print \
|
|
|
|
"""
|
|
|
|
An internal error occured. Please report all output from the program,
|
|
|
|
including the following traceback, to the PyKDE mailing list
|
|
|
|
"""
|
|
|
|
raise
|