X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=python%2Flilylib.py;h=a911cac23f0a2f8bdc77503a0e0c886becc7fa6f;hb=75fd76ce3b99883d86547ed7b6441a99d7be56dd;hp=dac53c16cf4dd5d83c2111e4ba49e28701f410b0;hpb=d70b0b408466d4b6992878b2bf11e8b222961472;p=lilypond.git diff --git a/python/lilylib.py b/python/lilylib.py index dac53c16cf..a911cac23f 100644 --- a/python/lilylib.py +++ b/python/lilylib.py @@ -1,6 +1,6 @@ # This file is part of LilyPond, the GNU music typesetter. # -# Copyright (C) 1998--2011 Han-Wen Nienhuys +# Copyright (C) 1998--2015 Han-Wen Nienhuys # Jan Nieuwenhuizen # # LilyPond is free software: you can redistribute it and/or modify @@ -23,6 +23,7 @@ import re import shutil import sys import optparse +import time ################################################################ # Users of python modules should include this snippet @@ -39,9 +40,14 @@ try: import gettext t = gettext.translation ('lilypond', localedir) _ = t.ugettext + ungettext = t.ungettext except: def _ (s): return s + def ungettext (s, p, n): + if n == 1: + return s + return p underscore = _ # Urg, Python 2.4 does not define stderr/stdout encoding @@ -77,29 +83,83 @@ if at_re.match (program_version): else: program_version = "unknown" + +# Logging framework: We have the following output functions: +# error +# warning +# progress +# debug + +loglevels = {"NONE":0, "ERROR":1, "WARN":2, "BASIC":3, "PROGRESS":4, "INFO":5, "DEBUG":6} + +loglevel = loglevels["PROGRESS"] + +def set_loglevel (l): + global loglevel + newlevel = loglevels.get (l, -1) + if newlevel > 0: + debug_output (_ ("Setting loglevel to %s") % l) + loglevel = newlevel + else: + error (_ ("Unknown or invalid loglevel '%s'") % l) + + +def handle_loglevel_option (option, opt_str, value, parser, *args): + if value: + set_loglevel (value); + elif args: + set_loglevel (args[0]); + +def is_loglevel (l): + global loglevel + return loglevel >= loglevels[l]; + +def is_verbose (): + return is_loglevel ("DEBUG") + def stderr_write (s): encoded_write (sys.stderr, s) -def warning (s): - stderr_write (program_name + ": " + _ ("warning: %s") % s + '\n') +def print_logmessage (level, s, fullmessage = True, newline = True): + if (is_loglevel (level)): + if fullmessage: + stderr_write (program_name + ": " + s + '\n') + elif newline: + stderr_write (s + '\n') + else: + stderr_write (s) def error (s): - stderr_write (program_name + ": " + _ ("error: %s") % s + '\n') + print_logmessage ("ERROR", _ ("error: %s") % s); + +def warning (s): + print_logmessage ("WARN", _ ("warning: %s") % s); + +def basic_progress (s): + print_logmessage ("BASIC", s); + +def progress (s, fullmessage = False, newline = True): + print_logmessage ("PROGRESS", s, fullmessage, newline); + +def debug_output (s, fullmessage = False, newline = True): + print_logmessage ("DEBUG", s, fullmessage, newline); -progress = stderr_write def require_python_version (): if sys.hexversion < 0x02040000: - stderr_write ("Python 2.4 or newer is required to run this program.\n\ + error ("Python 2.4 or newer is required to run this program.\n\ Please upgrade Python from http://python.org/download/, and if you use MacOS X,\n\ please read 'Setup for MacOS X' in Application Usage.") os.system ("open http://python.org/download/") sys.exit (2) -# Modified version of the commands.mkarg(x), which always uses -# double quotes (since Windows can't handle the single quotes: +# A modified version of the commands.mkarg(x) that always uses +# double quotes (since Windows can't handle the single quotes) +# and escapes the characters \, $, ", and ` for unix shells. def mkarg(x): + if os.name == 'nt': + return ' "%s"' % x s = ' "' for c in x: if c in '\\$"`': @@ -118,6 +178,7 @@ def subprocess_system (cmd, ignore_error=False, progress_p=True, be_verbose=False, + redirect_output=False, log_file=None): import subprocess @@ -125,31 +186,43 @@ def subprocess_system (cmd, name = command_name (cmd) error_log_file = '' - if be_verbose: - show_progress = 1 - progress (_ ("Invoking `%s\'") % cmd) + if redirect_output: + progress (_ ("Processing %s.ly") % log_file) else: - progress ( _("Running %s...") % name) - + if be_verbose: + show_progress = 1 + progress (_ ("Invoking `%s\'") % cmd) + else: + progress ( _("Running %s...") % name) stdout_setting = None + stderr_setting = None if not show_progress: - stdout_setting = subprocess.PIPE + stdout_setting = subprocess.PIPE + + if redirect_output: + stderr_filename = log_file + '.log' + stderr_setting = open(stderr_filename, 'w') proc = subprocess.Popen (cmd, shell=True, universal_newlines=True, stdout=stdout_setting, - stderr=stdout_setting) + stderr=stderr_setting) log = '' - if show_progress: - retval = proc.wait() + if redirect_output: + while proc.poll()==None: + time.sleep(0.01) + retval = proc.returncode + stderr_setting.close() else: - log = proc.communicate () - retval = proc.returncode - + if show_progress: + retval = proc.wait() + else: + log = proc.communicate () + retval = proc.returncode if retval: print >>sys.stderr, 'command failed:', cmd @@ -159,7 +232,7 @@ def subprocess_system (cmd, print >>sys.stderr, "Child returned", retval if ignore_error: - print >>sys.stderr, "Error ignored" + print >>sys.stderr, "Error ignored by lilylib" else: if not show_progress: print log[0] @@ -172,6 +245,7 @@ def ossystem_system (cmd, ignore_error=False, progress_p=True, be_verbose=False, + redirect_output=False, log_file=None): @@ -261,8 +335,15 @@ class NonDentedHeadingFormatter (optparse.IndentedHelpFormatter): def format_description(self, description): return description +class NonEmptyOptionParser (optparse.OptionParser): + "A subclass of OptionParser that gobbles empty string arguments." + + def parse_args (self, args=None, values=None): + options, args = optparse.OptionParser.parse_args (self, args, values) + return options, filter (None, args) + def get_option_parser (*args, **kwargs): - p = optparse.OptionParser (*args, **kwargs) + p = NonEmptyOptionParser (*args, **kwargs) p.formatter = NonDentedHeadingFormatter () p.formatter.set_parser (p) return p