-################################################################
+###############################################################
# lilylib.py -- options and stuff
#
# source file of the GNU LilyPond music typesetter
#
-# (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+# (c) 1998--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
# Jan Nieuwenhuizen <janneke@gnu.org>
-### subst:\(^\|[^._a-z]\)\(abspath\|identify\|warranty\|progress\|warning\|error\|exit\|getopt_args\|option_help_str\|options_help_str\|help\|setup_temp\|read_pipe\|system\|cleanup_temp\|strip_extension\|cp_to_dir\|mkdir_p\|init\) *(
-### replace:\1ly.\2 (
-
-### subst: \(help_summary\|keep_temp_dir_p\|option_definitions\|original_dir\|program_name\|pseudo_filter_p\|temp_dir\|verbose_p\)
-
import __main__
import glob
import os
import re
import shutil
-import string
import sys
import optparse
-import tempfile
################################################################
# Users of python modules should include this snippet
# it as we do with teTeX on Red Hat Linux: set some environment var
# (PYTHONPATH) in profile)
-# If set, LILYPONDPREFIX must take prevalence
-# if datadir is not set, we're doing a build and LILYPONDPREFIX
+# If set, LILYPOND_DATADIR must take prevalence
+# if datadir is not set, we're doing a build and LILYPOND_DATADIR
datadir = '@local_lilypond_datadir@'
if not os.path.isdir (datadir):
- datadir = '@lilypond_datadir@'
-if os.environ.has_key ('LILYPONDPREFIX') :
- datadir = os.environ['LILYPONDPREFIX']
- while datadir[-1] == os.sep:
- datadir= datadir[:-1]
+ datadir = '@lilypond_datadir@'
+if os.environ.has_key ('LILYPOND_DATADIR') :
+ datadir = os.environ['LILYPOND_DATADIR']
+ while datadir[-1] == os.sep:
+ datadir= datadir[:-1]
sys.path.insert (0, os.path.join (datadir, 'python'))
-
+# Python 2.5 only accepts strings with proper Python internal encoding
+# (i.e. ASCII or Unicode) when writing to stdout/stderr, so we must
+# use ugettext iso gettext, and encode the string when writing to
+# stdout/stderr
localedir = '@localedir@'
try:
- import gettext
- gettext.bindtextdomain ('lilypond', localedir)
- gettext.textdomain ('lilypond')
- _ = gettext.gettext
+ import gettext
+ t = gettext.translation ('lilypond', localedir)
+ _ = t.ugettext
except:
- def _ (s):
- return s
+ def _ (s):
+ return s
underscore = _
-progress = sys.stderr.write
+# Urg, Python 2.4 does not define stderr/stdout encoding
+# Maybe guess encoding from LANG/LC_ALL/LC_CTYPE?
-def command_name (cmd):
- # Strip all stuf after command,
- # deal with "((latex ) >& 1 ) .." too
- cmd = re.match ('([\(\)]*)([^\\\ ]*)', cmd).group (2)
- return os.path.basename (cmd)
+def encoded_write(f, s):
+ f.write (s.encode (f.encoding or 'utf_8'))
-def error_log (name):
- name = re.sub('[^a-z]','x', name)
- return tempfile.mktemp ('%s.errorlog' % name)
+# ugh, Python 2.5 optparse requires Unicode strings in some argument
+# functions, and refuse them in some other places
+def display_encode (s):
+ return s.encode (sys.stderr.encoding or 'utf_8')
+def stderr_write (s):
+ encoded_write (sys.stderr, s)
-def system (cmd, ignore_error = 0, progress_p = 0, be_verbose=0):
-
- '''System CMD. If IGNORE_ERROR, do not complain when CMD
-returns non zero. If PROGRESS_P, always show progress.
+progress = stderr_write
-RETURN VALUE
+# Modified version of the commands.mkarg(x), which always uses
+# double quotes (since Windows can't handle the single quotes:
+def mkarg(x):
+ s = ' "'
+ for c in x:
+ if c in '\\$"`':
+ s = s + '\\'
+ s = s + c
+ s = s + '"'
+ return s
-Exit status of CMD '''
+def command_name (cmd):
+ # Strip all stuf after command,
+ # deal with "((latex ) >& 1 ) .." too
+ cmd = re.match ('([\(\)]*)([^\\\ ]*)', cmd).group (2)
+ return os.path.basename (cmd)
+
+def subprocess_system (cmd,
+ ignore_error=False,
+ progress_p=True,
+ be_verbose=False,
+ log_file=None):
+ import subprocess
+
+ show_progress= progress_p
+ name = command_name (cmd)
+ error_log_file = ''
+
+ if be_verbose:
+ show_progress = 1
+ progress (_ ("Invoking `%s\'") % cmd)
+ else:
+ progress ( _("Running %s...") % name)
+
+
+ stdout_setting = None
+ if not show_progress:
+ stdout_setting = subprocess.PIPE
+
+ proc = subprocess.Popen (cmd,
+ shell=True,
+ universal_newlines=True,
+ stdout=stdout_setting,
+ stderr=stdout_setting)
+
+ log = ''
+
+ if show_progress:
+ retval = proc.wait()
+ else:
+ log = proc.communicate ()
+ retval = proc.returncode
+
+
+ if retval:
+ print >>sys.stderr, 'command failed:', cmd
+ if retval < 0:
+ print >>sys.stderr, "Child was terminated by signal", -retval
+ elif retval > 0:
+ print >>sys.stderr, "Child returned", retval
+
+ if ignore_error:
+ print >>sys.stderr, "Error ignored"
+ else:
+ if not show_progress:
+ print log[0]
+ print log[1]
+ sys.exit (1)
+
+ return abs (retval)
+
+def ossystem_system (cmd,
+ ignore_error=False,
+ progress_p=True,
+ be_verbose=False,
+ log_file=None):
+
+
+ name = command_name (cmd)
+ if be_verbose:
+ show_progress = 1
+ progress (_ ("Invoking `%s\'") % cmd)
+ else:
+ progress ( _("Running %s...") % name)
+
+ retval = os.system (cmd)
+ if retval:
+ print >>sys.stderr, 'command failed:', cmd
+ if retval < 0:
+ print >>sys.stderr, "Child was terminated by signal", -retval
+ elif retval > 0:
+ print >>sys.stderr, "Child returned", retval
+
+ if ignore_error:
+ print >>sys.stderr, "Error ignored"
+ else:
+ sys.exit (1)
- name = command_name (cmd)
- error_log_file = ''
+ return abs (retval)
- if be_verbose:
- progress_p = 1
- progress (_ ("Invoking `%s\'") % cmd)
- else:
- progress ( _("Running %s...") % name)
-
- redirect = ''
- if not progress_p:
- error_log_file = error_log (name)
- redirect = ' 1>/dev/null 2>' + error_log_file
-
- status = os.system (cmd + redirect)
- signal = 0x0f & status
- exit_status = status >> 8
-
- if status:
-
- exit_type = 'status %d' % exit_status
- if signal:
- exit_type = 'signal %d' % signal
-
- msg = _ ("`%s\' failed (%s)") % (name, exit_type)
- if ignore_error:
- if be_verbose:
- warning (msg + ' ' + _ ("(ignored)"))
- else:
- error (msg)
- if not progress_p and error_log_file:
- error (_ ("The error log is as follows:"))
- sys.stderr.write (open (error_log_file).read ())
- if error_log_file:
- os.unlink (error_log_file)
- exit (1)
-
- if error_log_file:
- os.unlink (error_log_file)
- progress ('\n')
- return status
+
+system = subprocess_system
+if sys.platform == 'mingw32':
+
+ ## subprocess x-compile doesn't work.
+ system = ossystem_system
def strip_extension (f, ext):
- (p, e) = os.path.splitext (f)
- if e == ext:
- e = ''
- return p + e
+ (p, e) = os.path.splitext (f)
+ if e == ext:
+ e = ''
+ return p + e
def search_exe_path (name):
- p = os.environ['PATH']
- exe_paths = string.split (p, ':')
- for e in exe_paths:
- full = os.path.join (e, name)
- if os.path.exists (full):
- return full
- return None
+ p = os.environ['PATH']
+ exe_paths = p.split (':')
+ for e in exe_paths:
+ full = os.path.join (e, name)
+ if os.path.exists (full):
+ return full
+ return None
def print_environment ():
- for (k,v) in os.environ.items ():
- sys.stderr.write ("%s=\"%s\"\n" % (k, v))
-
-
-def ps_page_count (ps_name):
- header = open (ps_name).read (1024)
- m = re.search ('\n%%Pages: ([0-9]+)', header)
- if m:
- return string.atoi (m.group (1))
- return 0
+ for (k,v) in os.environ.items ():
+ sys.stderr.write ("%s=\"%s\"\n" % (k, v))
class NonDentedHeadingFormatter (optparse.IndentedHelpFormatter):
def format_heading(self, heading):
- if heading:
- return heading[0].upper() + heading[1:] + ':\n'
- return ''
+ if heading:
+ return heading[0].upper() + heading[1:] + ':\n'
+ return ''
def format_option_strings(self, option):
- sep = ' '
- if option._short_opts and option._long_opts:
- sep = ','
+ sep = ' '
+ if option._short_opts and option._long_opts:
+ sep = ','
- metavar = ''
- if option.takes_value():
- metavar = '=%s' % option.metavar or option.dest.upper()
+ metavar = ''
+ if option.takes_value():
+ metavar = '=%s' % option.metavar or option.dest.upper()
- return "%3s%s %s%s" % (" ".join (option._short_opts),
- sep,
- " ".join (option._long_opts),
- metavar)
+ return "%3s%s %s%s" % (" ".join (option._short_opts),
+ sep,
+ " ".join (option._long_opts),
+ metavar)
def format_usage(self, usage):
- return _("Usage: %s\n") % usage
-
+ return _("Usage: %s") % usage + '\n'
+
def format_description(self, description):
- return description
+ return description
def get_option_parser (*args, **kwargs):
- p = optparse.OptionParser (*args, **kwargs)
- p.formatter = NonDentedHeadingFormatter ()
- return p
+ p = optparse.OptionParser (*args, **kwargs)
+ p.formatter = NonDentedHeadingFormatter ()
+ return p