mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-14 14:03:58 +00:00
Work on improving the output of the manpage completion script
This commit is contained in:
parent
37defa739b
commit
7394374a15
1 changed files with 509 additions and 452 deletions
|
@ -14,9 +14,9 @@ Redistributions in binary form must reproduce the above copyright notice, this l
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
""" Run me like this: ./create_manpage_completions.py /usr/share/man/man1/* > test2.out """
|
""" Run me like this: ./create_manpage_completions.py /usr/share/man/man1/* > man_completions.fish """
|
||||||
|
|
||||||
import sys, re, os.path, gzip, traceback
|
import string, sys, re, os.path, gzip, traceback
|
||||||
|
|
||||||
# This gets set to the name of the command that we are currently executing
|
# This gets set to the name of the command that we are currently executing
|
||||||
CMDNAME = ""
|
CMDNAME = ""
|
||||||
|
@ -24,6 +24,24 @@ CMDNAME = ""
|
||||||
# builtcommand writes into this global variable, yuck
|
# builtcommand writes into this global variable, yuck
|
||||||
built_command_output = []
|
built_command_output = []
|
||||||
|
|
||||||
|
# Diagnostic output
|
||||||
|
diagnostic_output = []
|
||||||
|
diagnostic_indent = 0
|
||||||
|
|
||||||
|
def add_diagnostic(dgn):
|
||||||
|
diagnostic_output.append(' '*diagnostic_indent + dgn)
|
||||||
|
|
||||||
|
def flush_diagnostics(where):
|
||||||
|
if diagnostic_output:
|
||||||
|
output_str = '\n'.join(diagnostic_output) + '\n'
|
||||||
|
where.write(output_str)
|
||||||
|
diagnostic_output[:] = []
|
||||||
|
|
||||||
|
# Make sure we don't output the same completion multiple times, which can happen
|
||||||
|
# For example, xsubpp.1.gz and xsubpp5.10.1.gz
|
||||||
|
# This maps commands to lists of completions
|
||||||
|
already_output_completions = {}
|
||||||
|
|
||||||
def compileAndSearch(regex, input):
|
def compileAndSearch(regex, input):
|
||||||
options_section_regex = re.compile(regex , re.DOTALL)
|
options_section_regex = re.compile(regex , re.DOTALL)
|
||||||
options_section_matched = re.search( options_section_regex, input)
|
options_section_matched = re.search( options_section_regex, input)
|
||||||
|
@ -43,34 +61,64 @@ def unquoteSingleQuotes(data):
|
||||||
data = data[1:len(data)-1]
|
data = data[1:len(data)-1]
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
# Make a string of characters that are deemed safe in fish without needing to be escaped
|
||||||
|
# Note that space is not included
|
||||||
|
g_fish_safe_chars = frozenset(string.ascii_letters + string.digits + '_+-|/:=<>@~')
|
||||||
|
|
||||||
|
def fish_escape_single_quote(str):
|
||||||
|
# Escape a string if necessary so that it can be put in single quotes
|
||||||
|
# If it has no non-safe chars, there's nothing to do
|
||||||
|
if g_fish_safe_chars.issuperset(str):
|
||||||
|
return str
|
||||||
|
|
||||||
|
str = str.replace('\\', '\\\\') # Replace one backslash with two
|
||||||
|
str = str.replace("'", "\\'") # Replace one single quote with a backslash-single-quote
|
||||||
|
return "'" + str + "'"
|
||||||
|
|
||||||
def output_complete_command(cmdname, args, description, output_list):
|
def output_complete_command(cmdname, args, description, output_list):
|
||||||
comps = ['complete -c', cmdname]
|
comps = ['complete -c', cmdname]
|
||||||
comps.extend(args)
|
comps.extend(args)
|
||||||
|
if description:
|
||||||
comps.append('--description')
|
comps.append('--description')
|
||||||
comps.append("'" + description + "'")
|
comps.append(description)
|
||||||
output_list.append(' '.join(comps))
|
output_list.append(' '.join(comps))
|
||||||
|
|
||||||
|
|
||||||
def builtcommand(options, description):
|
def builtcommand(options, description):
|
||||||
# print "Options are: ", options
|
# print "Options are: ", options
|
||||||
optionlist = re.split(" |,|\"|=|[|]", options)
|
man_optionlist = re.split(" |,|\"|=|[|]", options)
|
||||||
optionlist = [x for x in optionlist if x.startswith('-')]
|
fish_options = []
|
||||||
if len(optionlist) == 0:
|
for option in man_optionlist:
|
||||||
return
|
if option.startswith('--'):
|
||||||
for i in range(0, len(optionlist)):
|
# New style long option (--recursive)
|
||||||
if optionlist[i][0:2] == "--":
|
fish_options.append('-l ' + fish_escape_single_quote(option[2:]))
|
||||||
optionlist[i] = "-l " + optionlist[i][2:]
|
elif option.startswith('-') and len(option) == 2:
|
||||||
else:
|
# New style short option (-r)
|
||||||
optionlist[i] = "-s " + optionlist[i][1:]
|
fish_options.append('-s ' + fish_escape_single_quote(option[1:]))
|
||||||
description = description.replace('"','\\"')
|
elif option.startswith('-') and len(option) > 2:
|
||||||
|
# Old style long option (-recursive)
|
||||||
|
fish_options.append('-o ' + fish_escape_single_quote(option[1:]))
|
||||||
|
|
||||||
|
# Determine which options are new (not already in existing_options)
|
||||||
|
# Then add those to the existing options
|
||||||
|
existing_options = already_output_completions.setdefault(CMDNAME, set())
|
||||||
|
fish_options = [opt for opt in fish_options if opt not in existing_options]
|
||||||
|
existing_options.update(fish_options)
|
||||||
|
|
||||||
|
# Maybe it's all for naught
|
||||||
|
if not fish_options: return
|
||||||
|
|
||||||
first_period = description.find(".")
|
first_period = description.find(".")
|
||||||
# print "First period at: ", first_period
|
if first_period >= 45 or (first_period == -1 and len(description) > 45):
|
||||||
if first_period >= 45 or first_period == -1 and len(description) > 45:
|
description = description[:45] + '... [See Man Page]'
|
||||||
description = description[:45] + "... [See Man Page]"
|
|
||||||
elif first_period >= 0:
|
elif first_period >= 0:
|
||||||
description = description[:first_period]
|
description = description[:first_period]
|
||||||
|
|
||||||
output_complete_command(CMDNAME, optionlist, description, built_command_output)
|
# Escape some more things
|
||||||
|
description = fish_escape_single_quote(description)
|
||||||
|
escaped_cmd = fish_escape_single_quote(CMDNAME)
|
||||||
|
|
||||||
|
output_complete_command(escaped_cmd, fish_options, description, built_command_output)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,10 +177,10 @@ class Type1ManParser(ManParser):
|
||||||
options_parts_regex = re.compile("\.PP(.*?)\.RE", re.DOTALL)
|
options_parts_regex = re.compile("\.PP(.*?)\.RE", re.DOTALL)
|
||||||
options_matched = re.search(options_parts_regex, options_section)
|
options_matched = re.search(options_parts_regex, options_section)
|
||||||
# print options_matched
|
# print options_matched
|
||||||
print >> sys.stderr, "Command is ", CMDNAME
|
add_diagnostic('Command is ' + CMDNAME)
|
||||||
|
|
||||||
if options_matched == None:
|
if options_matched == None:
|
||||||
print >> sys.stderr, "Unable to find options"
|
add_diagnostic('Unable to find options')
|
||||||
if( self.fallback(options_section) ):
|
if( self.fallback(options_section) ):
|
||||||
return True
|
return True
|
||||||
elif (self.fallback2(options_section) ):
|
elif (self.fallback2(options_section) ):
|
||||||
|
@ -154,7 +202,7 @@ class Type1ManParser(ManParser):
|
||||||
optionName = data[0].strip()
|
optionName = data[0].strip()
|
||||||
|
|
||||||
if ( optionName.find("-") == -1):
|
if ( optionName.find("-") == -1):
|
||||||
print >> sys.stderr, optionName, " doesn't contain - "
|
add_diagnostic(optionName + " doesn't contain - ")
|
||||||
# return False
|
# return False
|
||||||
else:
|
else:
|
||||||
optionName = unquoteDoubleQuotes(optionName)
|
optionName = unquoteDoubleQuotes(optionName)
|
||||||
|
@ -164,18 +212,18 @@ class Type1ManParser(ManParser):
|
||||||
builtcommand(optionName, optionDescription)
|
builtcommand(optionName, optionDescription)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print >> sys.stderr, "Unable to split option from description"
|
add_diagnostic('Unable to split option from description')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
options_section = options_section[options_matched.end()-3:]
|
options_section = options_section[options_matched.end()-3:]
|
||||||
options_matched = re.search(options_parts_regex, options_section)
|
options_matched = re.search(options_parts_regex, options_section)
|
||||||
|
|
||||||
def fallback(self, options_section):
|
def fallback(self, options_section):
|
||||||
print >> sys.stderr, "Falling Back"
|
add_diagnostic('Falling Back')
|
||||||
options_parts_regex = re.compile("\.TP( \d+)?(.*?)\.TP", re.DOTALL)
|
options_parts_regex = re.compile("\.TP( \d+)?(.*?)\.TP", re.DOTALL)
|
||||||
options_matched = re.search(options_parts_regex, options_section)
|
options_matched = re.search(options_parts_regex, options_section)
|
||||||
if options_matched == None:
|
if options_matched == None:
|
||||||
print >> sys.stderr, "Still not found"
|
add_diagnostic('Still not found')
|
||||||
return False
|
return False
|
||||||
while options_matched != None:
|
while options_matched != None:
|
||||||
data = options_matched.group(2)
|
data = options_matched.group(2)
|
||||||
|
@ -185,7 +233,7 @@ class Type1ManParser(ManParser):
|
||||||
if (len(data)>1 and len(data[1].strip())>0): # and len(data[1])<400):
|
if (len(data)>1 and len(data[1].strip())>0): # and len(data[1])<400):
|
||||||
optionName = data[0].strip()
|
optionName = data[0].strip()
|
||||||
if ( optionName.find("-") == -1):
|
if ( optionName.find("-") == -1):
|
||||||
print >> sys.stderr, optionName, "doesn't contains -"
|
add_diagnostic(optionName + "doesn't contains -")
|
||||||
else:
|
else:
|
||||||
optionName = unquoteDoubleQuotes(optionName)
|
optionName = unquoteDoubleQuotes(optionName)
|
||||||
optionName = unquoteSingleQuotes(optionName)
|
optionName = unquoteSingleQuotes(optionName)
|
||||||
|
@ -193,8 +241,7 @@ class Type1ManParser(ManParser):
|
||||||
# print "Option: ", optionName," Description: ", optionDescription , '\n'
|
# print "Option: ", optionName," Description: ", optionDescription , '\n'
|
||||||
builtcommand(optionName, optionDescription)
|
builtcommand(optionName, optionDescription)
|
||||||
else:
|
else:
|
||||||
print >> sys.stderr, data
|
add_diagnostic('Unable to split option from description')
|
||||||
print >> sys.stderr, "Unable to split option from description"
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
options_section = options_section[options_matched.end()-3:]
|
options_section = options_section[options_matched.end()-3:]
|
||||||
|
@ -202,7 +249,7 @@ class Type1ManParser(ManParser):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def fallback2(self, options_section):
|
def fallback2(self, options_section):
|
||||||
print >> sys.stderr, "Falling Back2"
|
add_diagnostic('Falling Back2')
|
||||||
ix_remover_regex = re.compile("\.IX.*")
|
ix_remover_regex = re.compile("\.IX.*")
|
||||||
trailing_num_regex = re.compile('\\d+$')
|
trailing_num_regex = re.compile('\\d+$')
|
||||||
options_parts_regex = re.compile("\.IP (.*?)\.IP", re.DOTALL)
|
options_parts_regex = re.compile("\.IP (.*?)\.IP", re.DOTALL)
|
||||||
|
@ -210,7 +257,7 @@ class Type1ManParser(ManParser):
|
||||||
options_section = re.sub(ix_remover_regex, "", options_section)
|
options_section = re.sub(ix_remover_regex, "", options_section)
|
||||||
options_matched = re.search(options_parts_regex, options_section)
|
options_matched = re.search(options_parts_regex, options_section)
|
||||||
if options_matched == None:
|
if options_matched == None:
|
||||||
print >> sys.stderr, "Still not found2"
|
add_diagnostic('Still not found2')
|
||||||
return False
|
return False
|
||||||
while options_matched != None:
|
while options_matched != None:
|
||||||
data = options_matched.group(1)
|
data = options_matched.group(1)
|
||||||
|
@ -225,8 +272,8 @@ class Type1ManParser(ManParser):
|
||||||
# data = re.sub(trailing_num_regex, "", data)
|
# data = re.sub(trailing_num_regex, "", data)
|
||||||
optionName = re.sub(trailing_num_regex, "", data[0].strip())
|
optionName = re.sub(trailing_num_regex, "", data[0].strip())
|
||||||
|
|
||||||
if ( optionName.find("-") == -1):
|
if ('-' not in optionName):
|
||||||
print >> sys.stderr, optionName, "doesn't contains -"
|
add_diagnostic(optionName + " doesn't contain -")
|
||||||
else:
|
else:
|
||||||
optionName = optionName.strip()
|
optionName = optionName.strip()
|
||||||
optionName = unquoteDoubleQuotes(optionName)
|
optionName = unquoteDoubleQuotes(optionName)
|
||||||
|
@ -236,7 +283,7 @@ class Type1ManParser(ManParser):
|
||||||
builtcommand(optionName, optionDescription)
|
builtcommand(optionName, optionDescription)
|
||||||
else:
|
else:
|
||||||
# print data
|
# print data
|
||||||
print >> sys.stderr, "Unable to split option from description"
|
add_diagnostic('Unable to split option from description')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
options_section = options_section[options_matched.end()-3:]
|
options_section = options_section[options_matched.end()-3:]
|
||||||
|
@ -274,10 +321,10 @@ class Type2ManParser(ManParser):
|
||||||
options_parts_regex = re.compile("\.[I|T]P( \d+(\.\d)?i?)?(.*?)\.[I|T]P", re.DOTALL)
|
options_parts_regex = re.compile("\.[I|T]P( \d+(\.\d)?i?)?(.*?)\.[I|T]P", re.DOTALL)
|
||||||
# options_parts_regex = re.compile("\.TP(.*?)[(\.TP)|(\.SH)]", re.DOTALL)
|
# options_parts_regex = re.compile("\.TP(.*?)[(\.TP)|(\.SH)]", re.DOTALL)
|
||||||
options_matched = re.search(options_parts_regex, options_section)
|
options_matched = re.search(options_parts_regex, options_section)
|
||||||
print >> sys.stderr, "Command is ", CMDNAME
|
add_diagnostic('Command is ' + CMDNAME)
|
||||||
|
|
||||||
if options_matched == None:
|
if options_matched == None:
|
||||||
print >> sys.stderr, self.name() + ": Unable to find options"
|
add_diagnostic(self.name() + ': Unable to find options')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
while (options_matched != None):
|
while (options_matched != None):
|
||||||
|
@ -292,8 +339,8 @@ class Type2ManParser(ManParser):
|
||||||
# print >> sys.stderr, data
|
# print >> sys.stderr, data
|
||||||
if (len(data)>1 and len(data[1].strip())>0): # and len(data[1])<400):
|
if (len(data)>1 and len(data[1].strip())>0): # and len(data[1])<400):
|
||||||
optionName = data[0].strip()
|
optionName = data[0].strip()
|
||||||
if ( optionName.find("-") == -1):
|
if '-' not in optionName:
|
||||||
print >> sys.stderr, optionName, "doesn't contains -"
|
add_diagnostic(optionName + " doesn't contain -")
|
||||||
else:
|
else:
|
||||||
optionName = unquoteDoubleQuotes(optionName)
|
optionName = unquoteDoubleQuotes(optionName)
|
||||||
optionName = unquoteSingleQuotes(optionName)
|
optionName = unquoteSingleQuotes(optionName)
|
||||||
|
@ -301,8 +348,8 @@ class Type2ManParser(ManParser):
|
||||||
# print "Option: ", optionName," Description: ", optionDescription , '\n'
|
# print "Option: ", optionName," Description: ", optionDescription , '\n'
|
||||||
builtcommand(optionName, optionDescription)
|
builtcommand(optionName, optionDescription)
|
||||||
else:
|
else:
|
||||||
print >> sys.stderr, data
|
# print >> sys.stderr, data
|
||||||
print >> sys.stderr, "Unable to split option from description"
|
add_diagnostic('Unable to split option from description')
|
||||||
|
|
||||||
# return False
|
# return False
|
||||||
|
|
||||||
|
@ -333,10 +380,10 @@ class Type3ManParser(ManParser):
|
||||||
# sys.exit(1)
|
# sys.exit(1)
|
||||||
options_parts_regex = re.compile("\.TP(.*?)\.TP", re.DOTALL)
|
options_parts_regex = re.compile("\.TP(.*?)\.TP", re.DOTALL)
|
||||||
options_matched = re.search(options_parts_regex, options_section)
|
options_matched = re.search(options_parts_regex, options_section)
|
||||||
print >> sys.stderr, "Command is ", CMDNAME
|
add_diagnostic('Command is ' + CMDNAME)
|
||||||
|
|
||||||
if options_matched == None:
|
if options_matched == None:
|
||||||
print >> sys.stderr, "Unable to find options section"
|
add_diagnostic('Unable to find options section')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
while (options_matched != None):
|
while (options_matched != None):
|
||||||
|
@ -350,7 +397,7 @@ class Type3ManParser(ManParser):
|
||||||
if (len(data)>1): # and len(data[1])<400):
|
if (len(data)>1): # and len(data[1])<400):
|
||||||
optionName = data[0].strip()
|
optionName = data[0].strip()
|
||||||
if ( optionName.find("-") == -1):
|
if ( optionName.find("-") == -1):
|
||||||
print >> sys.stderr, optionName, "doesn't contains -"
|
add_diagnostic(optionName + "doesn't contain -")
|
||||||
else:
|
else:
|
||||||
optionName = unquoteDoubleQuotes(optionName)
|
optionName = unquoteDoubleQuotes(optionName)
|
||||||
optionName = unquoteSingleQuotes(optionName)
|
optionName = unquoteSingleQuotes(optionName)
|
||||||
|
@ -359,7 +406,7 @@ class Type3ManParser(ManParser):
|
||||||
builtcommand(optionName, optionDescription)
|
builtcommand(optionName, optionDescription)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print >> sys.stderr, "Unable to split option from description"
|
add_diagnostic('Unable to split option from description')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
options_section = options_section[options_matched.end()-3:]
|
options_section = options_section[options_matched.end()-3:]
|
||||||
|
@ -415,7 +462,7 @@ class Type4ManParser(ManParser):
|
||||||
builtcommand(optionName, optionDescription)
|
builtcommand(optionName, optionDescription)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print >> sys.stderr, "Unable to split option from description"
|
add_diagnostic('Unable to split option from description')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
options_section = options_section[options_matched.end()-3:]
|
options_section = options_section[options_matched.end()-3:]
|
||||||
|
@ -485,11 +532,19 @@ class TypeMacManParser(ManParser):
|
||||||
def parse_manpage_at_path(manpage_path):
|
def parse_manpage_at_path(manpage_path):
|
||||||
filename = os.path.basename(manpage_path)
|
filename = os.path.basename(manpage_path)
|
||||||
|
|
||||||
|
# Clear diagnostics
|
||||||
|
global diagnostic_indent
|
||||||
|
diagnostic_output[:] = []
|
||||||
|
diagnostic_indent = 0
|
||||||
|
|
||||||
# Get the "base" command, e.g. gcc.1.gz -> gcc
|
# Get the "base" command, e.g. gcc.1.gz -> gcc
|
||||||
global CMDNAME
|
global CMDNAME
|
||||||
CMDNAME = filename.split('.', 1)[0]
|
CMDNAME = filename.split('.', 1)[0]
|
||||||
|
|
||||||
print >> sys.stderr, "Considering " + manpage_path
|
# Set up some diagnostics
|
||||||
|
add_diagnostic('Considering ' + manpage_path)
|
||||||
|
diagnostic_indent += 1
|
||||||
|
|
||||||
if manpage_path.endswith('.gz'):
|
if manpage_path.endswith('.gz'):
|
||||||
fd = gzip.open(manpage_path, 'r')
|
fd = gzip.open(manpage_path, 'r')
|
||||||
else:
|
else:
|
||||||
|
@ -497,55 +552,57 @@ def parse_manpage_at_path(manpage_path):
|
||||||
manpage = fd.read()
|
manpage = fd.read()
|
||||||
fd.close()
|
fd.close()
|
||||||
|
|
||||||
parsers = [Type1ManParser(), Type2ManParser(), Type4ManParser(), Type3ManParser(), TypeMacManParser()]
|
|
||||||
parserToUse = None
|
|
||||||
|
|
||||||
# Get the "base" command, e.g. gcc.1.gz -> gcc
|
# Get the "base" command, e.g. gcc.1.gz -> gcc
|
||||||
cmd_base = CMDNAME.split('.', 1)[0]
|
cmd_base = CMDNAME.split('.', 1)[0]
|
||||||
ignoredcommands = ["cc", "g++", "gcc", "c++", "cpp", "emacs", "gprof", "wget", "ld", "awk"]
|
ignoredcommands = ["cc", "g++", "gcc", "c++", "cpp", "emacs", "gprof", "wget", "ld", "awk"]
|
||||||
if cmd_base in ignoredcommands:
|
if cmd_base in ignoredcommands:
|
||||||
return
|
return
|
||||||
|
|
||||||
idx = 0
|
|
||||||
for parser in parsers:
|
|
||||||
if parser.isMyType(manpage):
|
|
||||||
parserToUse = parser
|
|
||||||
# print "Type is: ", parser.name()
|
|
||||||
break
|
|
||||||
idx += 1
|
|
||||||
|
|
||||||
# Clear the output list
|
# Clear the output list
|
||||||
built_command_output[:] = []
|
built_command_output[:] = []
|
||||||
|
|
||||||
if parserToUse == None:
|
parsers = [Type1ManParser(), Type2ManParser(), Type4ManParser(), Type3ManParser(), TypeMacManParser()]
|
||||||
print >> sys.stderr, manpage_path, " : Not supported"
|
parsersToTry = [p for p in parsers if p.isMyType(manpage)]
|
||||||
|
|
||||||
|
if not parsersToTry:
|
||||||
|
add_diagnostic(manpage_path + ": Not supported")
|
||||||
else:
|
else:
|
||||||
if parserToUse.parseManPage(manpage) == False:
|
success = False
|
||||||
print >> sys.stderr, "Type%d : %s is unparsable" % (idx, manpage_path)
|
for parser in parsersToTry:
|
||||||
elif built_command_output:
|
add_diagnostic('Trying parser ' + parser.name())
|
||||||
|
diagnostic_indent += 1
|
||||||
|
success = parser.parseManPage(manpage)
|
||||||
|
diagnostic_indent -= 1
|
||||||
|
if success: break
|
||||||
|
|
||||||
|
if success:
|
||||||
built_command_output.insert(0, "# %s: %s" % (CMDNAME, parser.name()))
|
built_command_output.insert(0, "# %s: %s" % (CMDNAME, parser.name()))
|
||||||
for line in built_command_output:
|
for line in built_command_output:
|
||||||
pass
|
print line
|
||||||
#print line
|
print ''
|
||||||
#print ''
|
add_diagnostic(manpage_path + ' parsed successfully')
|
||||||
print >> sys.stderr, manpage_path, " parsed successfully"
|
else:
|
||||||
|
parser_names = ', '.join(p.name() for p in parsersToTry)
|
||||||
|
add_diagnostic('%s is unparsable (tried parser %s)' % (manpage_path, parser_names))
|
||||||
|
|
||||||
def compare_paths(a, b):
|
def compare_paths(a, b):
|
||||||
""" Compare two paths by their base name, case insensitive """
|
""" Compare two paths by their base name, case insensitive """
|
||||||
return cmp(os.path.basename(a).lower(), os.path.basename(b).lower())
|
return cmp(os.path.basename(a).lower(), os.path.basename(b).lower())
|
||||||
|
|
||||||
def parse_and_output_man_pages(paths):
|
def parse_and_output_man_pages(paths):
|
||||||
|
global diagnostic_indent
|
||||||
paths.sort(compare_paths)
|
paths.sort(compare_paths)
|
||||||
for manpage_path in paths:
|
for manpage_path in paths:
|
||||||
try:
|
try:
|
||||||
parse_manpage_at_path(manpage_path)
|
parse_manpage_at_path(manpage_path)
|
||||||
except IOError:
|
except IOError:
|
||||||
print >> sys.stderr, 'Cannot open ', manpage_path
|
diagnostic_indent = 0
|
||||||
|
add_diagnostic('Cannot open ' + manpage_path)
|
||||||
except:
|
except:
|
||||||
print >> sys.stderr, "Error parsing %s: %s" % (manpage_path, sys.exc_info()[0])
|
add_diagnostic('Error parsing %s: %s' % (manpage_path, sys.exc_info()[0]))
|
||||||
traceback.print_exc(file=sys.stdout)
|
flush_diagnostics(sys.stderr)
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
flush_diagnostics(sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue