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