EVOLUTION-MANAGER
Edit File: completionFinder.py
#!/usr/bin/env python # -*- coding: utf-8 -*- ############################################################################### # $Id$ # # Project: GDAL/OGR Utilities # Purpose: Bash completion script generation # Author: Guillaume Pasero <guillaume dot pasero at c dash s dot fr> # ############################################################################### # Copyright (c) 2016, Guillaume Pasero <guillaume dot pasero at c dash s dot fr> # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. ############################################################################### import sys, os import os.path as op from subprocess import call, Popen, PIPE, STDOUT def showHelp(): print "Usage : completionFinder.py output_script" def processLine(line): outList = [] lvl1 = line.split(' ') lvl2 = [] for item in lvl1: lvl2 += item.split('[') lvl3 = [] for item in lvl2: lvl3 += item.split(']') lvl4 = [] for item in lvl3: lvl4 += item.split('|') for item in lvl4: if len(item) >= 2: if item[0] == '-': key = item # Handle special cases -key={A/B/C} if (key.count("={") == 1 and key[-1] == '}'): pair = key.split("=") choices = ((pair[1])[1:-1]).split('/') for c in choices: outList.append(pair[0]+"="+c) else: outList.append(key) return outList def processTool(toolName): command = [toolName, "-"] process = Popen(command,stdout=PIPE,stderr=STDOUT) result = process.communicate()[0] lines = result.split('\n') index = 0 while index < len(lines): if (lines[index].find("Usage:") >= 0): break index += 1 options = [] while index < len(lines): cleanLine = lines[index].strip('\t\r ') if (len(cleanLine) == 0): break; options += processLine(cleanLine) index += 1 return options def parseGDALGeneralOptions(): command = ["gdalinfo", "--help-general"] process = Popen(command,stdout=PIPE,stderr=STDOUT) result = process.communicate()[0] lines = result.split('\n') index = 0 options = [] while index < len(lines): cleanLine = lines[index].strip('\t\r ') parts = cleanLine.split(':') if (parts[0].find('--') == 0): words = parts[0].split(' ') options.append(words[0]) index += 1 return options def parseOGRGeneralOptions(): command = ["ogr2ogr", "--help-general"] process = Popen(command,stdout=PIPE,stderr=STDOUT) result = process.communicate()[0] lines = result.split('\n') index = 0 options = [] while index < len(lines): cleanLine = lines[index].strip('\t\r ') parts = cleanLine.split(':') if (parts[0].find('--') == 0): words = parts[0].split(' ') options.append(words[0]) index += 1 return options # generate completion script section for : # - name : the given gdal/ogr tool # - optList : option list def getCompletionScript(name,optList): output = [] output.append("_"+name+"()\n") output.append("{\n") output.append(" local cur prev\n") output.append(" COMPREPLY=()\n") output.append(" _get_comp_words_by_ref cur prev\n") output.append(" case \"$cur\" in\n") output.append(" -*)\n") optLine = " key_list=\"" for item in optList: optLine += item + " " optLine += "\"\n" output.append(optLine) output.append(" COMPREPLY=( $( compgen -W '$key_list' -- $cur) )\n") output.append(" return 0\n") output.append(" ;;\n") output.append(" esac\n") # adapt format parsing command : GDAL type of OGR type isGdal = True if (name.find("ogr") == 0): isGdal = False # gdal type if isGdal: formatParsingCmd = "$tool --formats | tail -n +2 | cut -f 3 -d ' '" if ("-ot" in optList) or ("-of" in optList) or ("--format" in optList): output.append(" tool=${COMP_WORDS[0]}\n") output.append(" case \"$prev\" in\n") if "-ot" in optList: output.append(" -ot)\n") output.append(" key_list=\"Byte Int16 UInt16 UInt32 Int32 Float32 Float64 CInt16 CInt32 CFloat32 CFloat64\"\n") output.append(" COMPREPLY=( $( compgen -W '$key_list' -- $cur) )\n") output.append(" ;;\n") if ("-of" in optList) and isGdal: output.append(" -of)\n") output.append(" key_list=\"$( "+formatParsingCmd+")\"\n") output.append(" COMPREPLY=( $( compgen -W '$key_list' -- $cur) )\n") output.append(" ;;\n") if ("--format" in optList) and isGdal: output.append(" --format)\n") output.append(" key_list=\"$( "+formatParsingCmd+")\"\n") output.append(" COMPREPLY=( $( compgen -W '$key_list' -- $cur) )\n") output.append(" ;;\n") output.append(" esac\n") else: # ogr type formatParsingCmd = "$tool --formats | tail -n +2 | grep -o -E '\"[^\"]+\"' | sed 's/\ /__/'" if ("-f" in optList): # replace ogrtindex by ogr2ogr to check --formats output.append(" tool=${COMP_WORDS[0]/ogrtindex/ogr2ogr}\n") output.append(" case \"$prev\" in\n") if ("-f" in optList) and not isGdal: # completion is more tricky here because of spaces output.append(" -f)\n") output.append(" key_list=\"$( "+formatParsingCmd+")\"\n") output.append(" for iter in $key_list; do\n") output.append(" if [[ $iter =~ ^$cur ]]; then\n") output.append(" COMPREPLY+=( \"${iter//__/ }\" )\n") output.append(" fi\n") output.append(" done\n") output.append(" ;;\n") output.append(" esac\n") output.append(" return 0\n") output.append("}\n") output.append("complete -o default -F _"+name+" "+name+"\n") return output def main(argv): if len(argv) < 2 : showHelp() return 1 gdaltools = [ "gdal2tiles.py",\ "gdal2xyz.py",\ "gdaladdo",\ # "gdal_auth.py",\ "gdalbuildvrt",\ "gdal_calc.py",\ "gdalchksum.py",\ "gdalcompare.py",\ "gdal-config",\ "gdal_contour",\ "gdaldem",\ "gdal_edit.py",\ "gdalenhance",\ "gdal_fillnodata.py",\ "gdal_grid",\ "gdalident.py",\ "gdalimport.py",\ "gdalinfo",\ "gdallocationinfo",\ "gdalmanage",\ "gdal_merge.py",\ "gdalmove.py",\ "gdal_polygonize.py",\ "gdal_proximity.py",\ "gdal_rasterize",\ "gdal_retile.py",\ "gdalserver",\ "gdal_sieve.py",\ "gdalsrsinfo",\ "gdaltindex",\ "gdaltransform",\ "gdal_translate",\ "gdalwarp"] ogrtools = [ "ogr2ogr",\ "ogrinfo",\ "ogrlineref",\ "ogrtindex", "ogrmerge.py"] # parse general options generalOptions = parseGDALGeneralOptions() generalOGROptions = parseOGRGeneralOptions() outFile = argv[1] of = open(outFile,'w') of.write("# File auto-generated by completionFinder.py, do not modify manually\n") of.write(""" function_exists() { declare -f -F $1 > /dev/null return $? } # Checks that bash-completion is recent enough function_exists _get_comp_words_by_ref || return 0 """) for name in gdaltools: # verbose print print name optList = processTool(name) if "--help-general" in optList: for item in generalOptions: if not item in optList: optList.append(item) of.writelines(getCompletionScript(name,optList)) for name in ogrtools: # verbose print print name optList = processTool(name) if "--help-general" in optList: for item in generalOGROptions: if not item in optList: optList.append(item) of.writelines(getCompletionScript(name,optList)) of.close() return 0 if __name__ == "__main__": main(sys.argv)