1# This file is part of LilyPond, the GNU music typesetter. 2# 3# Copyright (C) 1998--2021 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 19import __main__ 20import codecs 21import gettext 22import optparse 23import os 24import sys 25 26sys.stdin = codecs.getreader('utf8')(sys.stdin.detach()) 27sys.stdout = codecs.getwriter('utf8')(sys.stdout.detach()) 28sys.stderr = codecs.getwriter('utf8')(sys.stderr.detach()) 29 30# Lilylib globals. 31program_name = os.path.basename(sys.argv[0]) 32 33# Logging framework: We have the following output functions: 34# error 35# warning 36# progress 37# debug 38 39# TODO: use the standard logging module 40_loglevels = {"NONE": 0, "ERROR": 1, "WARN": 2, 41 "BASIC": 3, "PROGRESS": 4, "INFO": 5, "DEBUG": 6} 42 43_loglevel = _loglevels["PROGRESS"] 44 45 46def set_loglevel(l): 47 global _loglevel 48 newlevel = _loglevels.get(l, -1) 49 if newlevel > 0: 50 debug_output(_("Setting loglevel to %s") % l) 51 _loglevel = newlevel 52 else: 53 error(_("Unknown or invalid loglevel '%s'") % l) 54 55 56def handle_loglevel_option(option, opt_str, value, parser, *args): 57 if value: 58 set_loglevel(value) 59 elif args: 60 set_loglevel(args[0]) 61 62 63def _is_loglevel(l): 64 global _loglevel 65 return _loglevel >= _loglevels[l] 66 67 68def is_verbose(): 69 return _is_loglevel("DEBUG") 70 71 72def _print_logmessage(level, s, fullmessage=True, newline=True): 73 if _is_loglevel(level): 74 if fullmessage: 75 s = program_name + ": " + s + "\n" 76 elif newline: 77 s += '\n' 78 sys.stderr.write(s) 79 sys.stderr.flush() 80 81 82def error(s): 83 _print_logmessage("ERROR", _("error: %s") % s) 84 85 86def warning(s): 87 _print_logmessage("WARN", _("warning: %s") % s) 88 89 90def progress(s, fullmessage=False, newline=True): 91 _print_logmessage("PROGRESS", s, fullmessage, newline) 92 93 94def debug_output(s, fullmessage=False, newline=True): 95 _print_logmessage("DEBUG", s, fullmessage, newline) 96 97 98class _NonDentedHeadingFormatter (optparse.IndentedHelpFormatter): 99 def format_heading(self, heading): 100 if heading: 101 return heading[0].upper() + heading[1:] + ':\n' 102 return '' 103 104 def format_option_strings(self, option): 105 sep = ' ' 106 if option._short_opts and option._long_opts: 107 sep = ',' 108 109 metavar = '' 110 if option.takes_value(): 111 metavar = '=%s' % option.metavar or option.dest.upper() 112 113 return "%3s%s %s%s" % (" ".join(option._short_opts), 114 sep, 115 " ".join(option._long_opts), 116 metavar) 117 118 # Only use one level of indentation (even for groups and nested groups), 119 # since we don't indent the headings, either 120 def indent(self): 121 self.current_indent = self.indent_increment 122 self.level += 1 123 124 def dedent(self): 125 self.level -= 1 126 if self.level <= 0: 127 self.current_indent = '' 128 self.level = 0 129 130 def format_usage(self, usage): 131 return _("Usage: %s") % usage + '\n' 132 133 def format_description(self, description): 134 return description 135 136 137class _NonEmptyOptionParser (optparse.OptionParser): 138 "A subclass of OptionParser that gobbles empty string arguments." 139 140 def parse_args(self, args=None, values=None): 141 options, args = optparse.OptionParser.parse_args(self, args, values) 142 return options, [_f for _f in args if _f] 143 144 145def get_option_parser(*args, **kwargs): 146 p = _NonEmptyOptionParser(*args, **kwargs) 147 p.formatter = _NonDentedHeadingFormatter() 148 p.formatter.set_parser(p) 149 return p 150