]> git.donarmstrong.com Git - lilypond.git/blob - python/lilylib.py
Run `make grand-replace'.
[lilypond.git] / python / lilylib.py
1 ###############################################################
2 # lilylib.py -- options and stuff
3
4 # source file of the GNU LilyPond music typesetter
5 #
6 # (c) 1998--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 #                 Jan Nieuwenhuizen <janneke@gnu.org>
8
9 import __main__
10 import glob
11 import os
12 import re
13 import shutil
14 import sys
15 import optparse
16
17 ################################################################
18 # Users of python modules should include this snippet
19 # and customize variables below.
20
21
22 # Python 2.5 only accepts strings with proper Python internal encoding
23 # (i.e. ASCII or Unicode) when writing to stdout/stderr, so we must
24 # use ugettext iso gettext, and encode the string when writing to
25 # stdout/stderr
26
27 localedir = '@localedir@'
28 try:
29     import gettext
30     t = gettext.translation ('lilypond', localedir)
31     _ = t.ugettext
32 except:
33     def _ (s):
34         return s
35 underscore = _
36
37 # Urg, Python 2.4 does not define stderr/stdout encoding
38 # Maybe guess encoding from LANG/LC_ALL/LC_CTYPE?
39
40 def encoded_write(f, s):
41     f.write (s.encode (f.encoding or 'utf_8'))
42
43 # ugh, Python 2.5 optparse requires Unicode strings in some argument
44 # functions, and refuse them in some other places
45 def display_encode (s):
46     return s.encode (sys.stderr.encoding or 'utf_8')
47
48 def stderr_write (s):
49     encoded_write (sys.stderr, s)
50
51 progress = stderr_write
52
53 def require_python_version ():
54     if sys.hexversion < 0x02040000:
55         stderr_write ("Python 2.4 or newer is required to run this program.\n\
56 Please upgrade Python from http://python.org/download/, and if you use MacOS X,\n\
57 please read 'Setup for MacOS X' in Application Usage.")
58         os.system ("open http://python.org/download/")
59         sys.exit (2)
60
61 # Modified version of the commands.mkarg(x), which always uses 
62 # double quotes (since Windows can't handle the single quotes:
63 def mkarg(x):
64     s = ' "'
65     for c in x:
66         if c in '\\$"`':
67             s = s + '\\'
68         s = s + c
69     s = s + '"'
70     return s
71
72 def command_name (cmd):
73     # Strip all stuf after command,
74     # deal with "((latex ) >& 1 ) .." too
75     cmd = re.match ('([\(\)]*)([^\\\ ]*)', cmd).group (2)
76     return os.path.basename (cmd)
77
78 def subprocess_system (cmd,
79                        ignore_error=False,
80                        progress_p=True,
81                        be_verbose=False,
82                        log_file=None):
83     import subprocess
84
85     show_progress= progress_p 
86     name = command_name (cmd)
87     error_log_file = ''
88
89     if be_verbose:
90         show_progress = 1
91         progress (_ ("Invoking `%s\'") % cmd)
92     else:
93         progress ( _("Running %s...") % name)
94
95
96     stdout_setting = None
97     if not show_progress:
98         stdout_setting = subprocess.PIPE
99
100     proc = subprocess.Popen (cmd,
101                              shell=True,
102                              universal_newlines=True,
103                              stdout=stdout_setting,
104                              stderr=stdout_setting)
105
106     log = ''
107
108     if show_progress:
109         retval = proc.wait()
110     else:
111         log = proc.communicate ()
112         retval = proc.returncode
113
114
115     if retval:
116         print >>sys.stderr, 'command failed:', cmd
117         if retval < 0:
118             print >>sys.stderr, "Child was terminated by signal", -retval
119         elif retval > 0:
120             print >>sys.stderr, "Child returned", retval
121
122         if ignore_error:
123             print >>sys.stderr, "Error ignored"
124         else:
125             if not show_progress:
126                 print log[0]
127                 print log[1]
128             sys.exit (1)
129
130     return abs (retval)
131
132 def ossystem_system (cmd,
133                      ignore_error=False,
134                      progress_p=True,
135                      be_verbose=False,
136                      log_file=None):
137
138
139     name = command_name (cmd)
140     if be_verbose:
141         show_progress = 1
142         progress (_ ("Invoking `%s\'") % cmd)
143     else:
144         progress ( _("Running %s...") % name)
145
146     retval = os.system (cmd)
147     if retval:
148         print >>sys.stderr, 'command failed:', cmd
149         if retval < 0:
150             print >>sys.stderr, "Child was terminated by signal", -retval
151         elif retval > 0:
152             print >>sys.stderr, "Child returned", retval
153
154         if ignore_error:
155             print >>sys.stderr, "Error ignored"
156         else:
157             sys.exit (1)
158
159     return abs (retval)
160
161
162 system = subprocess_system
163 if sys.platform == 'mingw32':
164     
165     ## subprocess x-compile doesn't work.
166     system = ossystem_system
167
168 def strip_extension (f, ext):
169     (p, e) = os.path.splitext (f)
170     if e == ext:
171         e = ''
172     return p + e
173
174
175 def search_exe_path (name):
176     p = os.environ['PATH']
177     exe_paths = p.split (':')
178     for e in exe_paths:
179         full = os.path.join (e, name)
180         if os.path.exists (full):
181             return full
182     return None
183
184
185 def print_environment ():
186     for (k,v) in os.environ.items ():
187         sys.stderr.write ("%s=\"%s\"\n" % (k, v)) 
188
189 class NonDentedHeadingFormatter (optparse.IndentedHelpFormatter):
190     def format_heading(self, heading):
191         if heading:
192             return heading[0].upper() + heading[1:] + ':\n'
193         return ''
194     def format_option_strings(self, option):
195         sep = ' '
196         if option._short_opts and option._long_opts:
197             sep = ','
198
199         metavar = ''
200         if option.takes_value():
201             metavar = '=%s' % option.metavar or option.dest.upper()
202
203         return "%3s%s %s%s" % (" ".join (option._short_opts),
204                                sep,
205                                " ".join (option._long_opts),
206                                metavar)
207
208     def format_usage(self, usage):
209         return _("Usage: %s") % usage + '\n'
210
211     def format_description(self, description):
212         return description
213
214 def get_option_parser (*args, **kwargs): 
215     p = optparse.OptionParser (*args, **kwargs)
216     p.formatter = NonDentedHeadingFormatter () 
217     return p