summaryrefslogtreecommitdiff
path: root/clang/tools/scan-view/startfile.py
diff options
context:
space:
mode:
authorCarlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au>2012-10-15 17:10:06 +1100
committerCarlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au>2012-10-15 17:10:06 +1100
commitbe1de4be954c80875ad4108e0a33e8e131b2f2c0 (patch)
tree1fbbecf276bf7c7bdcbb4dd446099d6d90eaa516 /clang/tools/scan-view/startfile.py
parentc4626a62754862d20b41e8a46a3574264ea80e6d (diff)
parentf1bd2e48c5324d3f7cda4090c87f8a5b6f463ce2 (diff)
Merge branch 'master' of ssh://bitbucket.org/czan/honours
Diffstat (limited to 'clang/tools/scan-view/startfile.py')
-rw-r--r--clang/tools/scan-view/startfile.py203
1 files changed, 203 insertions, 0 deletions
diff --git a/clang/tools/scan-view/startfile.py b/clang/tools/scan-view/startfile.py
new file mode 100644
index 0000000..e8fbe2d
--- /dev/null
+++ b/clang/tools/scan-view/startfile.py
@@ -0,0 +1,203 @@
+"""Utility for opening a file using the default application in a cross-platform
+manner. Modified from http://code.activestate.com/recipes/511443/.
+"""
+
+__version__ = '1.1x'
+__all__ = ['open']
+
+import os
+import sys
+import webbrowser
+import subprocess
+
+_controllers = {}
+_open = None
+
+
+class BaseController(object):
+ '''Base class for open program controllers.'''
+
+ def __init__(self, name):
+ self.name = name
+
+ def open(self, filename):
+ raise NotImplementedError
+
+
+class Controller(BaseController):
+ '''Controller for a generic open program.'''
+
+ def __init__(self, *args):
+ super(Controller, self).__init__(os.path.basename(args[0]))
+ self.args = list(args)
+
+ def _invoke(self, cmdline):
+ if sys.platform[:3] == 'win':
+ closefds = False
+ startupinfo = subprocess.STARTUPINFO()
+ startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
+ else:
+ closefds = True
+ startupinfo = None
+
+ if (os.environ.get('DISPLAY') or sys.platform[:3] == 'win' or
+ sys.platform == 'darwin'):
+ inout = file(os.devnull, 'r+')
+ else:
+ # for TTY programs, we need stdin/out
+ inout = None
+
+ # if possible, put the child precess in separate process group,
+ # so keyboard interrupts don't affect child precess as well as
+ # Python
+ setsid = getattr(os, 'setsid', None)
+ if not setsid:
+ setsid = getattr(os, 'setpgrp', None)
+
+ pipe = subprocess.Popen(cmdline, stdin=inout, stdout=inout,
+ stderr=inout, close_fds=closefds,
+ preexec_fn=setsid, startupinfo=startupinfo)
+
+ # It is assumed that this kind of tools (gnome-open, kfmclient,
+ # exo-open, xdg-open and open for OSX) immediately exit after lauching
+ # the specific application
+ returncode = pipe.wait()
+ if hasattr(self, 'fixreturncode'):
+ returncode = self.fixreturncode(returncode)
+ return not returncode
+
+ def open(self, filename):
+ if isinstance(filename, basestring):
+ cmdline = self.args + [filename]
+ else:
+ # assume it is a sequence
+ cmdline = self.args + filename
+ try:
+ return self._invoke(cmdline)
+ except OSError:
+ return False
+
+
+# Platform support for Windows
+if sys.platform[:3] == 'win':
+
+ class Start(BaseController):
+ '''Controller for the win32 start progam through os.startfile.'''
+
+ def open(self, filename):
+ try:
+ os.startfile(filename)
+ except WindowsError:
+ # [Error 22] No application is associated with the specified
+ # file for this operation: '<URL>'
+ return False
+ else:
+ return True
+
+ _controllers['windows-default'] = Start('start')
+ _open = _controllers['windows-default'].open
+
+
+# Platform support for MacOS
+elif sys.platform == 'darwin':
+ _controllers['open']= Controller('open')
+ _open = _controllers['open'].open
+
+
+# Platform support for Unix
+else:
+
+ import commands
+
+ # @WARNING: use the private API of the webbrowser module
+ from webbrowser import _iscommand
+
+ class KfmClient(Controller):
+ '''Controller for the KDE kfmclient program.'''
+
+ def __init__(self, kfmclient='kfmclient'):
+ super(KfmClient, self).__init__(kfmclient, 'exec')
+ self.kde_version = self.detect_kde_version()
+
+ def detect_kde_version(self):
+ kde_version = None
+ try:
+ info = commands.getoutput('kde-config --version')
+
+ for line in info.splitlines():
+ if line.startswith('KDE'):
+ kde_version = line.split(':')[-1].strip()
+ break
+ except (OSError, RuntimeError):
+ pass
+
+ return kde_version
+
+ def fixreturncode(self, returncode):
+ if returncode is not None and self.kde_version > '3.5.4':
+ return returncode
+ else:
+ return os.EX_OK
+
+ def detect_desktop_environment():
+ '''Checks for known desktop environments
+
+ Return the desktop environments name, lowercase (kde, gnome, xfce)
+ or "generic"
+
+ '''
+
+ desktop_environment = 'generic'
+
+ if os.environ.get('KDE_FULL_SESSION') == 'true':
+ desktop_environment = 'kde'
+ elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):
+ desktop_environment = 'gnome'
+ else:
+ try:
+ info = commands.getoutput('xprop -root _DT_SAVE_MODE')
+ if ' = "xfce4"' in info:
+ desktop_environment = 'xfce'
+ except (OSError, RuntimeError):
+ pass
+
+ return desktop_environment
+
+
+ def register_X_controllers():
+ if _iscommand('kfmclient'):
+ _controllers['kde-open'] = KfmClient()
+
+ for command in ('gnome-open', 'exo-open', 'xdg-open'):
+ if _iscommand(command):
+ _controllers[command] = Controller(command)
+
+ def get():
+ controllers_map = {
+ 'gnome': 'gnome-open',
+ 'kde': 'kde-open',
+ 'xfce': 'exo-open',
+ }
+
+ desktop_environment = detect_desktop_environment()
+
+ try:
+ controller_name = controllers_map[desktop_environment]
+ return _controllers[controller_name].open
+
+ except KeyError:
+ if _controllers.has_key('xdg-open'):
+ return _controllers['xdg-open'].open
+ else:
+ return webbrowser.open
+
+
+ if os.environ.get("DISPLAY"):
+ register_X_controllers()
+ _open = get()
+
+
+def open(filename):
+ '''Open a file or an URL in the registered default application.'''
+
+ return _open(filename)