/usr/share/monkeystudio/apis/Tools/tags2api.py is in monkeystudio-common 1.9.0.1-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #! /usr/bin/env python
# Produces a .api file for SciTE's identifier completion and calltip features.
# invoke as
# python tags2api.py tags >x.api
# before running this program, create a tags file with
# ctags --excmd=number --c-types=pcdgstu <header files>
import fileinput
import string
import time
# Definitions that start with _ are often used for infrastructure
# like include guards and can be removed with
removePrivate=1
# The Windows headers include both ANSI and UniCode versions
# of many functions with macros that default to one or the other.
# When winMode is on, these 4 lines are replaced with either the
# ANSI or UniCode prototype.
winMode = 1
include="A" # Set to "W" if you want the UniCode prototypes.
class FileCache:
'''Caches the contents of a set of files.
Avoids reading files repeatedly from disk by holding onto the
contents of each file as a list of strings.
'''
def __init__(self):
self.filecache = {}
def grabFile(self, filename):
'''Return the contents of a file as a list of strings.
New line characters are removed.
'''
if not self.filecache.has_key(filename):
contents=[]
f = open(filename)
for line in f.readlines():
if line[-1:] == '\n': line = line[:-1]
contents.append(line)
f.close()
self.filecache[filename] = contents
return self.filecache[filename]
def bracesDiff(s):
''' Counts the number of '(' and ')' in a string and returns the difference between the two.
Used to work out when a function prototype is complete.
'''
diff = 0
mode=0 # 0 <=> default, 1 <=> comment, 2 <=> string
for i in range(len(s)):
if mode == 0: # default mode
if s[i]=='(':
diff += 1
elif s[i]==')':
diff -= 1
elif s[i]=='"':
mode=2
elif i>0 and s[i-1]=='/' and s[i]=='/':
return diff
elif i>0 and s[i-1]=='/' and s[i]=='*':
mode=1
elif mode == 1: # comment
if i>0 and s[i-1]=='*' and s[i]=='/':
mode=0
elif mode == 2: # string
if s[i]=='"':
mode=0
return diff
fc = FileCache()
apis = set()
for line in fileinput.input():
if line[0] != '!': # Not a comment.
(entityName, fileName, lineNo, tagType) = string.split(line, "\t")[:4]
curLineNo = string.atoi(lineNo[:-2]) - 1 # -1 because line numbers in tags file start at 1.
contents = fc.grabFile(fileName)
if (not removePrivate or entityName[0] != '_') and not entityName.startswith("operator "):
if tagType[0] in "pf": # Function prototype.
try:
braces = bracesDiff(contents[curLineNo])
curDef = contents[curLineNo]
while braces > 0: # Search for end of prototype.
curLineNo = curLineNo + 1
braces = braces + bracesDiff(contents[curLineNo])
curDef = curDef + contents[curLineNo]
# Normalise the appearance of the prototype.
curDef = string.strip(curDef)
# Replace whitespace sequences with a single space character.
curDef = string.join(string.split(curDef))
# Remove space around the '('.
curDef = string.replace(string.replace(curDef, " (", '('), "( ", '(')
# Remove trailing semicolon.
curDef = string.replace(curDef, ";", '')
# Remove implementation if present.
if "{" in curDef and "}" in curDef:
startImpl = curDef.find("{")
endImpl = curDef.find("}")
curDef = curDef[:startImpl] + curDef[endImpl+1:]
else:
# Remove trailing brace.
curDef = curDef.rstrip("{")
# Remove return type.
curDef = curDef[string.find(curDef, entityName):]
# Remove virtual indicator.
if curDef.replace(" ", "").endswith(")=0"):
curDef = curDef.rstrip("0 ")
curDef = curDef.rstrip("= ")
# Remove trailing space.
curDef = curDef.rstrip()
if winMode:
if string.find(curDef, "A(") >= 0:
if "A" in include:
apis.add(string.replace(curDef, "A(", '('))
elif string.find(curDef, "W(") >= 0:
if "W" in include:
apis.add(string.replace(curDef, "W(", '('))
else: # A character set independent function.
apis.add(curDef)
else:
apis.add(curDef)
except IndexError:
pass
elif tagType[0] == 'd': # Macro definition.
curDef = contents[curLineNo]
if (not winMode) or (curDef[-1] not in "AW"):
apis.add(entityName)
else:
apis.add(entityName)
print "\n".join(sorted(list(apis)))
|