version 1.1, 2012/02/21 23:37:59
|
version 1.1.1.3, 2014/06/15 19:53:35
|
Line 52 ignored_files = {
|
Line 52 ignored_files = {
|
"test.c": "not part of the library", |
"test.c": "not part of the library", |
"testdso.c": "test for dynamid shared libraries", |
"testdso.c": "test for dynamid shared libraries", |
"testrecurse.c": "test for entities recursions", |
"testrecurse.c": "test for entities recursions", |
|
"xzlib.h": "Internal API only 2.8.0", |
|
"buf.h": "Internal API only 2.9.0", |
|
"enc.h": "Internal API only 2.9.0", |
|
"/save.h": "Internal API only 2.9.0", |
|
"timsort.h": "Internal header only for xpath.c 2.9.0", |
} |
} |
|
|
ignored_words = { |
ignored_words = { |
Line 79 ignored_words = {
|
Line 84 ignored_words = {
|
} |
} |
|
|
def escape(raw): |
def escape(raw): |
raw = string.replace(raw, '&', '&') | raw = raw.replace('&', '&') |
raw = string.replace(raw, '<', '<') | raw = raw.replace('<', '<') |
raw = string.replace(raw, '>', '>') | raw = raw.replace('>', '>') |
raw = string.replace(raw, "'", ''') | raw = raw.replace("'", ''') |
raw = string.replace(raw, '"', '"') | raw = raw.replace('"', '"') |
return raw |
return raw |
|
|
def uniq(items): |
def uniq(items): |
d = {} |
d = {} |
for item in items: |
for item in items: |
d[item]=1 |
d[item]=1 |
return d.keys() | return list(d.keys()) |
|
|
class identifier: |
class identifier: |
def __init__(self, name, header=None, module=None, type=None, lineno = 0, |
def __init__(self, name, header=None, module=None, type=None, lineno = 0, |
info=None, extra=None, conditionals = None): |
info=None, extra=None, conditionals = None): |
self.name = name |
self.name = name |
self.header = header | self.header = header |
self.module = module | self.module = module |
self.type = type | self.type = type |
self.info = info | self.info = info |
self.extra = extra | self.extra = extra |
self.lineno = lineno | self.lineno = lineno |
self.static = 0 | self.static = 0 |
if conditionals == None or len(conditionals) == 0: | if conditionals == None or len(conditionals) == 0: |
self.conditionals = None | self.conditionals = None |
else: | else: |
self.conditionals = conditionals[:] | self.conditionals = conditionals[:] |
if self.name == debugsym: | if self.name == debugsym: |
print "=> define %s : %s" % (debugsym, (module, type, info, | print("=> define %s : %s" % (debugsym, (module, type, info, |
extra, conditionals)) | extra, conditionals))) |
|
|
def __repr__(self): |
def __repr__(self): |
r = "%s %s:" % (self.type, self.name) |
r = "%s %s:" % (self.type, self.name) |
if self.static: | if self.static: |
r = r + " static" | r = r + " static" |
if self.module != None: | if self.module != None: |
r = r + " from %s" % (self.module) | r = r + " from %s" % (self.module) |
if self.info != None: | if self.info != None: |
r = r + " " + `self.info` | r = r + " " + repr(self.info) |
if self.extra != None: | if self.extra != None: |
r = r + " " + `self.extra` | r = r + " " + repr(self.extra) |
if self.conditionals != None: | if self.conditionals != None: |
r = r + " " + `self.conditionals` | r = r + " " + repr(self.conditionals) |
return r | return r |
|
|
|
|
def set_header(self, header): |
def set_header(self, header): |
Line 141 class identifier:
|
Line 146 class identifier:
|
def set_static(self, static): |
def set_static(self, static): |
self.static = static |
self.static = static |
def set_conditionals(self, conditionals): |
def set_conditionals(self, conditionals): |
if conditionals == None or len(conditionals) == 0: | if conditionals == None or len(conditionals) == 0: |
self.conditionals = None | self.conditionals = None |
else: | else: |
self.conditionals = conditionals[:] | self.conditionals = conditionals[:] |
|
|
def get_name(self): |
def get_name(self): |
return self.name |
return self.name |
Line 167 class identifier:
|
Line 172 class identifier:
|
|
|
def update(self, header, module, type = None, info = None, extra=None, |
def update(self, header, module, type = None, info = None, extra=None, |
conditionals=None): |
conditionals=None): |
if self.name == debugsym: | if self.name == debugsym: |
print "=> update %s : %s" % (debugsym, (module, type, info, | print("=> update %s : %s" % (debugsym, (module, type, info, |
extra, conditionals)) | extra, conditionals))) |
if header != None and self.header == None: |
if header != None and self.header == None: |
self.set_header(module) | self.set_header(module) |
if module != None and (self.module == None or self.header == self.module): |
if module != None and (self.module == None or self.header == self.module): |
self.set_module(module) | self.set_module(module) |
if type != None and self.type == None: |
if type != None and self.type == None: |
self.set_type(type) | self.set_type(type) |
if info != None: |
if info != None: |
self.set_info(info) | self.set_info(info) |
if extra != None: |
if extra != None: |
self.set_extra(extra) | self.set_extra(extra) |
if conditionals != None: |
if conditionals != None: |
self.set_conditionals(conditionals) | self.set_conditionals(conditionals) |
|
|
class index: |
class index: |
def __init__(self, name = "noname"): |
def __init__(self, name = "noname"): |
self.name = name |
self.name = name |
self.identifiers = {} |
self.identifiers = {} |
self.functions = {} |
self.functions = {} |
self.variables = {} | self.variables = {} |
self.includes = {} | self.includes = {} |
self.structs = {} | self.structs = {} |
self.enums = {} | self.enums = {} |
self.typedefs = {} | self.typedefs = {} |
self.macros = {} | self.macros = {} |
self.references = {} | self.references = {} |
self.info = {} | self.info = {} |
|
|
def add_ref(self, name, header, module, static, type, lineno, info=None, extra=None, conditionals = None): |
def add_ref(self, name, header, module, static, type, lineno, info=None, extra=None, conditionals = None): |
if name[0:2] == '__': |
if name[0:2] == '__': |
return None | return None |
d = None |
d = None |
try: |
try: |
d = self.identifiers[name] | d = self.identifiers[name] |
d.update(header, module, type, lineno, info, extra, conditionals) | d.update(header, module, type, lineno, info, extra, conditionals) |
except: | except: |
d = identifier(name, header, module, type, lineno, info, extra, conditionals) | d = identifier(name, header, module, type, lineno, info, extra, conditionals) |
self.identifiers[name] = d | self.identifiers[name] = d |
|
|
if d != None and static == 1: | if d != None and static == 1: |
d.set_static(1) | d.set_static(1) |
|
|
if d != None and name != None and type != None: | if d != None and name != None and type != None: |
self.references[name] = d | self.references[name] = d |
|
|
if name == debugsym: | if name == debugsym: |
print "New ref: %s" % (d) | print("New ref: %s" % (d)) |
|
|
return d | return d |
|
|
def add(self, name, header, module, static, type, lineno, info=None, extra=None, conditionals = None): |
def add(self, name, header, module, static, type, lineno, info=None, extra=None, conditionals = None): |
if name[0:2] == '__': |
if name[0:2] == '__': |
return None | return None |
d = None |
d = None |
try: |
try: |
d = self.identifiers[name] | d = self.identifiers[name] |
d.update(header, module, type, lineno, info, extra, conditionals) | d.update(header, module, type, lineno, info, extra, conditionals) |
except: | except: |
d = identifier(name, header, module, type, lineno, info, extra, conditionals) | d = identifier(name, header, module, type, lineno, info, extra, conditionals) |
self.identifiers[name] = d | self.identifiers[name] = d |
|
|
if d != None and static == 1: | if d != None and static == 1: |
d.set_static(1) | d.set_static(1) |
|
|
if d != None and name != None and type != None: | if d != None and name != None and type != None: |
if type == "function": | if type == "function": |
self.functions[name] = d | self.functions[name] = d |
elif type == "functype": | elif type == "functype": |
self.functions[name] = d | self.functions[name] = d |
elif type == "variable": | elif type == "variable": |
self.variables[name] = d | self.variables[name] = d |
elif type == "include": | elif type == "include": |
self.includes[name] = d | self.includes[name] = d |
elif type == "struct": | elif type == "struct": |
self.structs[name] = d | self.structs[name] = d |
elif type == "enum": | elif type == "enum": |
self.enums[name] = d | self.enums[name] = d |
elif type == "typedef": | elif type == "typedef": |
self.typedefs[name] = d | self.typedefs[name] = d |
elif type == "macro": | elif type == "macro": |
self.macros[name] = d | self.macros[name] = d |
else: | else: |
print "Unable to register type ", type | print("Unable to register type ", type) |
|
|
if name == debugsym: | if name == debugsym: |
print "New symbol: %s" % (d) | print("New symbol: %s" % (d)) |
|
|
return d | return d |
|
|
def merge(self, idx): |
def merge(self, idx): |
for id in idx.functions.keys(): | for id in list(idx.functions.keys()): |
# |
# |
# macro might be used to override functions or variables |
# macro might be used to override functions or variables |
# definitions |
# definitions |
# |
# |
if self.macros.has_key(id): | if id in self.macros: |
del self.macros[id] | del self.macros[id] |
if self.functions.has_key(id): | if id in self.functions: |
print "function %s from %s redeclared in %s" % ( | print("function %s from %s redeclared in %s" % ( |
id, self.functions[id].header, idx.functions[id].header) | id, self.functions[id].header, idx.functions[id].header)) |
else: | else: |
self.functions[id] = idx.functions[id] | self.functions[id] = idx.functions[id] |
self.identifiers[id] = idx.functions[id] | self.identifiers[id] = idx.functions[id] |
for id in idx.variables.keys(): | for id in list(idx.variables.keys()): |
# |
# |
# macro might be used to override functions or variables |
# macro might be used to override functions or variables |
# definitions |
# definitions |
# |
# |
if self.macros.has_key(id): | if id in self.macros: |
del self.macros[id] | del self.macros[id] |
if self.variables.has_key(id): | if id in self.variables: |
print "variable %s from %s redeclared in %s" % ( | print("variable %s from %s redeclared in %s" % ( |
id, self.variables[id].header, idx.variables[id].header) | id, self.variables[id].header, idx.variables[id].header)) |
else: | else: |
self.variables[id] = idx.variables[id] | self.variables[id] = idx.variables[id] |
self.identifiers[id] = idx.variables[id] | self.identifiers[id] = idx.variables[id] |
for id in idx.structs.keys(): | for id in list(idx.structs.keys()): |
if self.structs.has_key(id): | if id in self.structs: |
print "struct %s from %s redeclared in %s" % ( | print("struct %s from %s redeclared in %s" % ( |
id, self.structs[id].header, idx.structs[id].header) | id, self.structs[id].header, idx.structs[id].header)) |
else: | else: |
self.structs[id] = idx.structs[id] | self.structs[id] = idx.structs[id] |
self.identifiers[id] = idx.structs[id] | self.identifiers[id] = idx.structs[id] |
for id in idx.typedefs.keys(): | for id in list(idx.typedefs.keys()): |
if self.typedefs.has_key(id): | if id in self.typedefs: |
print "typedef %s from %s redeclared in %s" % ( | print("typedef %s from %s redeclared in %s" % ( |
id, self.typedefs[id].header, idx.typedefs[id].header) | id, self.typedefs[id].header, idx.typedefs[id].header)) |
else: | else: |
self.typedefs[id] = idx.typedefs[id] | self.typedefs[id] = idx.typedefs[id] |
self.identifiers[id] = idx.typedefs[id] | self.identifiers[id] = idx.typedefs[id] |
for id in idx.macros.keys(): | for id in list(idx.macros.keys()): |
# |
# |
# macro might be used to override functions or variables |
# macro might be used to override functions or variables |
# definitions |
# definitions |
# |
# |
if self.variables.has_key(id): | if id in self.variables: |
continue |
continue |
if self.functions.has_key(id): | if id in self.functions: |
continue |
continue |
if self.enums.has_key(id): | if id in self.enums: |
continue |
continue |
if self.macros.has_key(id): | if id in self.macros: |
print "macro %s from %s redeclared in %s" % ( | print("macro %s from %s redeclared in %s" % ( |
id, self.macros[id].header, idx.macros[id].header) | id, self.macros[id].header, idx.macros[id].header)) |
else: | else: |
self.macros[id] = idx.macros[id] | self.macros[id] = idx.macros[id] |
self.identifiers[id] = idx.macros[id] | self.identifiers[id] = idx.macros[id] |
for id in idx.enums.keys(): | for id in list(idx.enums.keys()): |
if self.enums.has_key(id): | if id in self.enums: |
print "enum %s from %s redeclared in %s" % ( | print("enum %s from %s redeclared in %s" % ( |
id, self.enums[id].header, idx.enums[id].header) | id, self.enums[id].header, idx.enums[id].header)) |
else: | else: |
self.enums[id] = idx.enums[id] | self.enums[id] = idx.enums[id] |
self.identifiers[id] = idx.enums[id] | self.identifiers[id] = idx.enums[id] |
|
|
def merge_public(self, idx): |
def merge_public(self, idx): |
for id in idx.functions.keys(): | for id in list(idx.functions.keys()): |
if self.functions.has_key(id): | if id in self.functions: |
# check that function condition agrees with header | # check that function condition agrees with header |
if idx.functions[id].conditionals != \ | if idx.functions[id].conditionals != \ |
self.functions[id].conditionals: | self.functions[id].conditionals: |
print "Header condition differs from Function for %s:" \ | print("Header condition differs from Function for %s:" \ |
% id | % id) |
print " H: %s" % self.functions[id].conditionals | print(" H: %s" % self.functions[id].conditionals) |
print " C: %s" % idx.functions[id].conditionals | print(" C: %s" % idx.functions[id].conditionals) |
up = idx.functions[id] | up = idx.functions[id] |
self.functions[id].update(None, up.module, up.type, up.info, up.extra) | self.functions[id].update(None, up.module, up.type, up.info, up.extra) |
# else: | # else: |
# print "Function %s from %s is not declared in headers" % ( | # print "Function %s from %s is not declared in headers" % ( |
# id, idx.functions[id].module) | # id, idx.functions[id].module) |
# TODO: do the same for variables. | # TODO: do the same for variables. |
|
|
def analyze_dict(self, type, dict): |
def analyze_dict(self, type, dict): |
count = 0 |
count = 0 |
public = 0 | public = 0 |
for name in dict.keys(): | for name in list(dict.keys()): |
id = dict[name] | id = dict[name] |
count = count + 1 | count = count + 1 |
if id.static == 0: | if id.static == 0: |
public = public + 1 | public = public + 1 |
if count != public: |
if count != public: |
print " %d %s , %d public" % (count, type, public) | print(" %d %s , %d public" % (count, type, public)) |
elif count != 0: | elif count != 0: |
print " %d public %s" % (count, type) | print(" %d public %s" % (count, type)) |
|
|
|
|
def analyze(self): |
def analyze(self): |
self.analyze_dict("functions", self.functions) | self.analyze_dict("functions", self.functions) |
self.analyze_dict("variables", self.variables) | self.analyze_dict("variables", self.variables) |
self.analyze_dict("structs", self.structs) | self.analyze_dict("structs", self.structs) |
self.analyze_dict("typedefs", self.typedefs) | self.analyze_dict("typedefs", self.typedefs) |
self.analyze_dict("macros", self.macros) | self.analyze_dict("macros", self.macros) |
|
|
class CLexer: |
class CLexer: |
"""A lexer for the C language, tokenize the input by reading and |
"""A lexer for the C language, tokenize the input by reading and |
analyzing it line by line""" |
analyzing it line by line""" |
def __init__(self, input): |
def __init__(self, input): |
self.input = input |
self.input = input |
self.tokens = [] | self.tokens = [] |
self.line = "" | self.line = "" |
self.lineno = 0 | self.lineno = 0 |
|
|
def getline(self): |
def getline(self): |
line = '' |
line = '' |
while line == '': | while line == '': |
line = self.input.readline() | line = self.input.readline() |
if not line: | if not line: |
return None | return None |
self.lineno = self.lineno + 1 | self.lineno = self.lineno + 1 |
line = string.lstrip(line) | line = line.lstrip() |
line = string.rstrip(line) | line = line.rstrip() |
if line == '': | if line == '': |
continue | continue |
while line[-1] == '\\': | while line[-1] == '\\': |
line = line[:-1] | line = line[:-1] |
n = self.input.readline() | n = self.input.readline() |
self.lineno = self.lineno + 1 | self.lineno = self.lineno + 1 |
n = string.lstrip(n) | n = n.lstrip() |
n = string.rstrip(n) | n = n.rstrip() |
if not n: | if not n: |
break | break |
else: | else: |
line = line + n | line = line + n |
return line |
return line |
|
|
def getlineno(self): |
def getlineno(self): |
Line 401 class CLexer:
|
Line 406 class CLexer:
|
self.tokens.insert(0, token); |
self.tokens.insert(0, token); |
|
|
def debug(self): |
def debug(self): |
print "Last token: ", self.last | print("Last token: ", self.last) |
print "Token queue: ", self.tokens | print("Token queue: ", self.tokens) |
print "Line %d end: " % (self.lineno), self.line | print("Line %d end: " % (self.lineno), self.line) |
|
|
def token(self): |
def token(self): |
while self.tokens == []: |
while self.tokens == []: |
if self.line == "": | if self.line == "": |
line = self.getline() | line = self.getline() |
else: | else: |
line = self.line | line = self.line |
self.line = "" | self.line = "" |
if line == None: | if line == None: |
return None | return None |
|
|
if line[0] == '#': | if line[0] == '#': |
self.tokens = map((lambda x: ('preproc', x)), | self.tokens = list(map((lambda x: ('preproc', x)), |
string.split(line)) | line.split())) |
break; | break; |
l = len(line) | l = len(line) |
if line[0] == '"' or line[0] == "'": | if line[0] == '"' or line[0] == "'": |
end = line[0] | end = line[0] |
line = line[1:] | line = line[1:] |
found = 0 | found = 0 |
tok = "" | tok = "" |
while found == 0: | while found == 0: |
i = 0 | i = 0 |
l = len(line) | l = len(line) |
while i < l: | while i < l: |
if line[i] == end: | if line[i] == end: |
self.line = line[i+1:] | self.line = line[i+1:] |
line = line[:i] | line = line[:i] |
l = i | l = i |
found = 1 | found = 1 |
break | break |
if line[i] == '\\': | if line[i] == '\\': |
i = i + 1 | i = i + 1 |
i = i + 1 | i = i + 1 |
tok = tok + line | tok = tok + line |
if found == 0: | if found == 0: |
line = self.getline() | line = self.getline() |
if line == None: | if line == None: |
return None | return None |
self.last = ('string', tok) | self.last = ('string', tok) |
return self.last | return self.last |
|
|
if l >= 2 and line[0] == '/' and line[1] == '*': | if l >= 2 and line[0] == '/' and line[1] == '*': |
line = line[2:] | line = line[2:] |
found = 0 | found = 0 |
tok = "" | tok = "" |
while found == 0: | while found == 0: |
i = 0 | i = 0 |
l = len(line) | l = len(line) |
while i < l: | while i < l: |
if line[i] == '*' and i+1 < l and line[i+1] == '/': | if line[i] == '*' and i+1 < l and line[i+1] == '/': |
self.line = line[i+2:] | self.line = line[i+2:] |
line = line[:i-1] | line = line[:i-1] |
l = i | l = i |
found = 1 | found = 1 |
break | break |
i = i + 1 | i = i + 1 |
if tok != "": | if tok != "": |
tok = tok + "\n" | tok = tok + "\n" |
tok = tok + line | tok = tok + line |
if found == 0: | if found == 0: |
line = self.getline() | line = self.getline() |
if line == None: | if line == None: |
return None | return None |
self.last = ('comment', tok) | self.last = ('comment', tok) |
return self.last | return self.last |
if l >= 2 and line[0] == '/' and line[1] == '/': | if l >= 2 and line[0] == '/' and line[1] == '/': |
line = line[2:] | line = line[2:] |
self.last = ('comment', line) | self.last = ('comment', line) |
return self.last | return self.last |
i = 0 | i = 0 |
while i < l: | while i < l: |
if line[i] == '/' and i+1 < l and line[i+1] == '/': | if line[i] == '/' and i+1 < l and line[i+1] == '/': |
self.line = line[i:] | self.line = line[i:] |
line = line[:i] | line = line[:i] |
break | break |
if line[i] == '/' and i+1 < l and line[i+1] == '*': | if line[i] == '/' and i+1 < l and line[i+1] == '*': |
self.line = line[i:] | self.line = line[i:] |
line = line[:i] | line = line[:i] |
break | break |
if line[i] == '"' or line[i] == "'": | if line[i] == '"' or line[i] == "'": |
self.line = line[i:] | self.line = line[i:] |
line = line[:i] | line = line[:i] |
break | break |
i = i + 1 | i = i + 1 |
l = len(line) | l = len(line) |
i = 0 | i = 0 |
while i < l: | while i < l: |
if line[i] == ' ' or line[i] == '\t': | if line[i] == ' ' or line[i] == '\t': |
i = i + 1 | i = i + 1 |
continue | continue |
o = ord(line[i]) | o = ord(line[i]) |
if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \ | if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \ |
(o >= 48 and o <= 57): | (o >= 48 and o <= 57): |
s = i | s = i |
while i < l: | while i < l: |
o = ord(line[i]) | o = ord(line[i]) |
if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \ | if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \ |
(o >= 48 and o <= 57) or string.find( | (o >= 48 and o <= 57) or \ |
" \t(){}:;,+-*/%&!|[]=><", line[i]) == -1: | (" \t(){}:;,+-*/%&!|[]=><".find(line[i])) == -1: |
i = i + 1 | i = i + 1 |
else: | else: |
break | break |
self.tokens.append(('name', line[s:i])) | self.tokens.append(('name', line[s:i])) |
continue | continue |
if string.find("(){}:;,[]", line[i]) != -1: | if "(){}:;,[]".find(line[i]) != -1: |
# if line[i] == '(' or line[i] == ')' or line[i] == '{' or \ |
# if line[i] == '(' or line[i] == ')' or line[i] == '{' or \ |
# line[i] == '}' or line[i] == ':' or line[i] == ';' or \ | # line[i] == '}' or line[i] == ':' or line[i] == ';' or \ |
# line[i] == ',' or line[i] == '[' or line[i] == ']': | # line[i] == ',' or line[i] == '[' or line[i] == ']': |
self.tokens.append(('sep', line[i])) | self.tokens.append(('sep', line[i])) |
i = i + 1 | i = i + 1 |
continue | continue |
if string.find("+-*><=/%&!|.", line[i]) != -1: | # if line[i] == '+' or line[i] == '-' or line[i] == '*' or \ |
# if line[i] == '+' or line[i] == '-' or line[i] == '*' or \ |
# if line[i] == '+' or line[i] == '-' or line[i] == '*' or \ |
# line[i] == '>' or line[i] == '<' or line[i] == '=' or \ | # line[i] == '>' or line[i] == '<' or line[i] == '=' or \ |
# line[i] == '/' or line[i] == '%' or line[i] == '&' or \ | # line[i] == '/' or line[i] == '%' or line[i] == '&' or \ |
# line[i] == '!' or line[i] == '|' or line[i] == '.': | # line[i] == '!' or line[i] == '|' or line[i] == '.': |
if line[i] == '.' and i + 2 < l and \ | if line[i] == '.' and i + 2 < l and \ |
line[i+1] == '.' and line[i+2] == '.': | line[i+1] == '.' and line[i+2] == '.': |
self.tokens.append(('name', '...')) | self.tokens.append(('name', '...')) |
i = i + 3 | i = i + 3 |
continue | continue |
|
|
j = i + 1 | j = i + 1 |
if j < l and ( | if j < l and ( |
string.find("+-*><=/%&!|", line[j]) != -1): | "+-*><=/%&!|".find(line[j]) != -1): |
# line[j] == '+' or line[j] == '-' or line[j] == '*' or \ | # line[j] == '+' or line[j] == '-' or line[j] == '*' or \ |
# line[j] == '>' or line[j] == '<' or line[j] == '=' or \ | # line[j] == '>' or line[j] == '<' or line[j] == '=' or \ |
# line[j] == '/' or line[j] == '%' or line[j] == '&' or \ | # line[j] == '/' or line[j] == '%' or line[j] == '&' or \ |
# line[j] == '!' or line[j] == '|'): | # line[j] == '!' or line[j] == '|'): |
self.tokens.append(('op', line[i:j+1])) | self.tokens.append(('op', line[i:j+1])) |
i = j + 1 | i = j + 1 |
else: | else: |
self.tokens.append(('op', line[i])) | self.tokens.append(('op', line[i])) |
i = i + 1 | i = i + 1 |
continue | continue |
s = i | s = i |
while i < l: | while i < l: |
o = ord(line[i]) | o = ord(line[i]) |
if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \ | if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \ |
(o >= 48 and o <= 57) or ( | (o >= 48 and o <= 57) or ( |
string.find(" \t(){}:;,+-*/%&!|[]=><", line[i]) == -1): | " \t(){}:;,+-*/%&!|[]=><".find(line[i]) == -1): |
# line[i] != ' ' and line[i] != '\t' and | # line[i] != ' ' and line[i] != '\t' and |
# line[i] != '(' and line[i] != ')' and | # line[i] != '(' and line[i] != ')' and |
# line[i] != '{' and line[i] != '}' and | # line[i] != '{' and line[i] != '}' and |
# line[i] != ':' and line[i] != ';' and | # line[i] != ':' and line[i] != ';' and |
# line[i] != ',' and line[i] != '+' and | # line[i] != ',' and line[i] != '+' and |
# line[i] != '-' and line[i] != '*' and | # line[i] != '-' and line[i] != '*' and |
# line[i] != '/' and line[i] != '%' and | # line[i] != '/' and line[i] != '%' and |
# line[i] != '&' and line[i] != '!' and | # line[i] != '&' and line[i] != '!' and |
# line[i] != '|' and line[i] != '[' and | # line[i] != '|' and line[i] != '[' and |
# line[i] != ']' and line[i] != '=' and | # line[i] != ']' and line[i] != '=' and |
# line[i] != '*' and line[i] != '>' and | # line[i] != '*' and line[i] != '>' and |
# line[i] != '<'): | # line[i] != '<'): |
i = i + 1 | i = i + 1 |
else: | else: |
break | break |
self.tokens.append(('name', line[s:i])) | self.tokens.append(('name', line[s:i])) |
|
|
tok = self.tokens[0] | tok = self.tokens[0] |
self.tokens = self.tokens[1:] | self.tokens = self.tokens[1:] |
self.last = tok | self.last = tok |
return tok | return tok |
|
|
class CParser: |
class CParser: |
"""The C module parser""" |
"""The C module parser""" |
def __init__(self, filename, idx = None): |
def __init__(self, filename, idx = None): |
self.filename = filename |
self.filename = filename |
if len(filename) > 2 and filename[-2:] == '.h': | if len(filename) > 2 and filename[-2:] == '.h': |
self.is_header = 1 | self.is_header = 1 |
else: | else: |
self.is_header = 0 | self.is_header = 0 |
self.input = open(filename) |
self.input = open(filename) |
self.lexer = CLexer(self.input) | self.lexer = CLexer(self.input) |
if idx == None: | if idx == None: |
self.index = index() | self.index = index() |
else: | else: |
self.index = idx | self.index = idx |
self.top_comment = "" | self.top_comment = "" |
self.last_comment = "" | self.last_comment = "" |
self.comment = None | self.comment = None |
self.collect_ref = 0 | self.collect_ref = 0 |
self.no_error = 0 | self.no_error = 0 |
self.conditionals = [] | self.conditionals = [] |
self.defines = [] | self.defines = [] |
|
|
def collect_references(self): |
def collect_references(self): |
self.collect_ref = 1 |
self.collect_ref = 1 |
Line 603 class CParser:
|
Line 608 class CParser:
|
return self.lexer.getlineno() |
return self.lexer.getlineno() |
|
|
def index_add(self, name, module, static, type, info=None, extra = None): |
def index_add(self, name, module, static, type, info=None, extra = None): |
if self.is_header == 1: | if self.is_header == 1: |
self.index.add(name, module, module, static, type, self.lineno(), | self.index.add(name, module, module, static, type, self.lineno(), |
info, extra, self.conditionals) | info, extra, self.conditionals) |
else: | else: |
self.index.add(name, None, module, static, type, self.lineno(), | self.index.add(name, None, module, static, type, self.lineno(), |
info, extra, self.conditionals) | info, extra, self.conditionals) |
|
|
def index_add_ref(self, name, module, static, type, info=None, |
def index_add_ref(self, name, module, static, type, info=None, |
extra = None): |
extra = None): |
if self.is_header == 1: | if self.is_header == 1: |
self.index.add_ref(name, module, module, static, type, | self.index.add_ref(name, module, module, static, type, |
self.lineno(), info, extra, self.conditionals) | self.lineno(), info, extra, self.conditionals) |
else: | else: |
self.index.add_ref(name, None, module, static, type, self.lineno(), | self.index.add_ref(name, None, module, static, type, self.lineno(), |
info, extra, self.conditionals) | info, extra, self.conditionals) |
|
|
def warning(self, msg): |
def warning(self, msg): |
if self.no_error: |
if self.no_error: |
return | return |
print msg | print(msg) |
|
|
def error(self, msg, token=-1): |
def error(self, msg, token=-1): |
if self.no_error: |
if self.no_error: |
return | return |
|
|
print "Parse Error: " + msg | print("Parse Error: " + msg) |
if token != -1: | if token != -1: |
print "Got token ", token | print("Got token ", token) |
self.lexer.debug() | self.lexer.debug() |
sys.exit(1) | sys.exit(1) |
|
|
def debug(self, msg, token=-1): |
def debug(self, msg, token=-1): |
print "Debug: " + msg | print("Debug: " + msg) |
if token != -1: | if token != -1: |
print "Got token ", token | print("Got token ", token) |
self.lexer.debug() | self.lexer.debug() |
|
|
def parseTopComment(self, comment): |
def parseTopComment(self, comment): |
res = {} | res = {} |
lines = string.split(comment, "\n") | lines = comment.split("\n") |
item = None | item = None |
for line in lines: | for line in lines: |
while line != "" and (line[0] == ' ' or line[0] == '\t'): | while line != "" and (line[0] == ' ' or line[0] == '\t'): |
line = line[1:] | line = line[1:] |
while line != "" and line[0] == '*': | while line != "" and line[0] == '*': |
line = line[1:] | line = line[1:] |
while line != "" and (line[0] == ' ' or line[0] == '\t'): | while line != "" and (line[0] == ' ' or line[0] == '\t'): |
line = line[1:] | line = line[1:] |
try: | try: |
(it, line) = string.split(line, ":", 1) | (it, line) = line.split(":", 1) |
item = it | item = it |
while line != "" and (line[0] == ' ' or line[0] == '\t'): | while line != "" and (line[0] == ' ' or line[0] == '\t'): |
line = line[1:] | line = line[1:] |
if res.has_key(item): | if item in res: |
res[item] = res[item] + " " + line | res[item] = res[item] + " " + line |
else: | else: |
res[item] = line | res[item] = line |
except: | except: |
if item != None: | if item != None: |
if res.has_key(item): | if item in res: |
res[item] = res[item] + " " + line | res[item] = res[item] + " " + line |
else: | else: |
res[item] = line | res[item] = line |
self.index.info = res | self.index.info = res |
|
|
def parseComment(self, token): |
def parseComment(self, token): |
if self.top_comment == "": |
if self.top_comment == "": |
self.top_comment = token[1] | self.top_comment = token[1] |
if self.comment == None or token[1][0] == '*': | if self.comment == None or token[1][0] == '*': |
self.comment = token[1]; | self.comment = token[1]; |
else: | else: |
self.comment = self.comment + token[1] | self.comment = self.comment + token[1] |
token = self.lexer.token() | token = self.lexer.token() |
|
|
if string.find(self.comment, "DOC_DISABLE") != -1: | if self.comment.find("DOC_DISABLE") != -1: |
self.stop_error() | self.stop_error() |
|
|
if string.find(self.comment, "DOC_ENABLE") != -1: | if self.comment.find("DOC_ENABLE") != -1: |
self.start_error() | self.start_error() |
|
|
return token | return token |
|
|
# |
# |
# Parse a comment block associate to a typedef |
# Parse a comment block associate to a typedef |
# |
# |
def parseTypeComment(self, name, quiet = 0): |
def parseTypeComment(self, name, quiet = 0): |
if name[0:2] == '__': |
if name[0:2] == '__': |
quiet = 1 | quiet = 1 |
|
|
args = [] |
args = [] |
desc = "" | desc = "" |
|
|
if self.comment == None: |
if self.comment == None: |
if not quiet: | if not quiet: |
self.warning("Missing comment for type %s" % (name)) | self.warning("Missing comment for type %s" % (name)) |
return((args, desc)) | return((args, desc)) |
if self.comment[0] != '*': |
if self.comment[0] != '*': |
if not quiet: | if not quiet: |
self.warning("Missing * in type comment for %s" % (name)) | self.warning("Missing * in type comment for %s" % (name)) |
return((args, desc)) | return((args, desc)) |
lines = string.split(self.comment, '\n') | lines = self.comment.split('\n') |
if lines[0] == '*': | if lines[0] == '*': |
del lines[0] | del lines[0] |
if lines[0] != "* %s:" % (name): | if lines[0] != "* %s:" % (name): |
if not quiet: | if not quiet: |
self.warning("Misformatted type comment for %s" % (name)) | self.warning("Misformatted type comment for %s" % (name)) |
self.warning(" Expecting '* %s:' got '%s'" % (name, lines[0])) | self.warning(" Expecting '* %s:' got '%s'" % (name, lines[0])) |
return((args, desc)) | return((args, desc)) |
del lines[0] | del lines[0] |
while len(lines) > 0 and lines[0] == '*': | while len(lines) > 0 and lines[0] == '*': |
del lines[0] | del lines[0] |
desc = "" | desc = "" |
while len(lines) > 0: | while len(lines) > 0: |
l = lines[0] | l = lines[0] |
while len(l) > 0 and l[0] == '*': | while len(l) > 0 and l[0] == '*': |
l = l[1:] | l = l[1:] |
l = string.strip(l) | l = l.strip() |
desc = desc + " " + l | desc = desc + " " + l |
del lines[0] | del lines[0] |
|
|
desc = string.strip(desc) | desc = desc.strip() |
|
|
if quiet == 0: | if quiet == 0: |
if desc == "": | if desc == "": |
self.warning("Type comment for %s lack description of the macro" % (name)) | self.warning("Type comment for %s lack description of the macro" % (name)) |
|
|
return(desc) | return(desc) |
# |
# |
# Parse a comment block associate to a macro |
# Parse a comment block associate to a macro |
# |
# |
def parseMacroComment(self, name, quiet = 0): |
def parseMacroComment(self, name, quiet = 0): |
if name[0:2] == '__': |
if name[0:2] == '__': |
quiet = 1 | quiet = 1 |
|
|
args = [] |
args = [] |
desc = "" | desc = "" |
|
|
if self.comment == None: |
if self.comment == None: |
if not quiet: | if not quiet: |
self.warning("Missing comment for macro %s" % (name)) | self.warning("Missing comment for macro %s" % (name)) |
return((args, desc)) | return((args, desc)) |
if self.comment[0] != '*': |
if self.comment[0] != '*': |
if not quiet: | if not quiet: |
self.warning("Missing * in macro comment for %s" % (name)) | self.warning("Missing * in macro comment for %s" % (name)) |
return((args, desc)) | return((args, desc)) |
lines = string.split(self.comment, '\n') | lines = self.comment.split('\n') |
if lines[0] == '*': | if lines[0] == '*': |
del lines[0] | del lines[0] |
if lines[0] != "* %s:" % (name): | if lines[0] != "* %s:" % (name): |
if not quiet: | if not quiet: |
self.warning("Misformatted macro comment for %s" % (name)) | self.warning("Misformatted macro comment for %s" % (name)) |
self.warning(" Expecting '* %s:' got '%s'" % (name, lines[0])) | self.warning(" Expecting '* %s:' got '%s'" % (name, lines[0])) |
return((args, desc)) | return((args, desc)) |
del lines[0] | del lines[0] |
while lines[0] == '*': | while lines[0] == '*': |
del lines[0] | del lines[0] |
while len(lines) > 0 and lines[0][0:3] == '* @': | while len(lines) > 0 and lines[0][0:3] == '* @': |
l = lines[0][3:] | l = lines[0][3:] |
try: | try: |
(arg, desc) = string.split(l, ':', 1) | (arg, desc) = l.split(':', 1) |
desc=string.strip(desc) | desc=desc.strip() |
arg=string.strip(arg) | arg=arg.strip() |
except: |
except: |
if not quiet: | if not quiet: |
self.warning("Misformatted macro comment for %s" % (name)) | self.warning("Misformatted macro comment for %s" % (name)) |
self.warning(" problem with '%s'" % (lines[0])) | self.warning(" problem with '%s'" % (lines[0])) |
del lines[0] | del lines[0] |
continue | continue |
del lines[0] | del lines[0] |
l = string.strip(lines[0]) | l = lines[0].strip() |
while len(l) > 2 and l[0:3] != '* @': | while len(l) > 2 and l[0:3] != '* @': |
while l[0] == '*': | while l[0] == '*': |
l = l[1:] | l = l[1:] |
desc = desc + ' ' + string.strip(l) | desc = desc + ' ' + l.strip() |
del lines[0] | del lines[0] |
if len(lines) == 0: | if len(lines) == 0: |
break | break |
l = lines[0] | l = lines[0] |
args.append((arg, desc)) |
args.append((arg, desc)) |
while len(lines) > 0 and lines[0] == '*': | while len(lines) > 0 and lines[0] == '*': |
del lines[0] | del lines[0] |
desc = "" | desc = "" |
while len(lines) > 0: | while len(lines) > 0: |
l = lines[0] | l = lines[0] |
while len(l) > 0 and l[0] == '*': | while len(l) > 0 and l[0] == '*': |
l = l[1:] | l = l[1:] |
l = string.strip(l) | l = l.strip() |
desc = desc + " " + l | desc = desc + " " + l |
del lines[0] | del lines[0] |
|
|
desc = string.strip(desc) | desc = desc.strip() |
|
|
if quiet == 0: | if quiet == 0: |
if desc == "": | if desc == "": |
self.warning("Macro comment for %s lack description of the macro" % (name)) | self.warning("Macro comment for %s lack description of the macro" % (name)) |
|
|
return((args, desc)) | return((args, desc)) |
|
|
# |
# |
# Parse a comment block and merge the informations found in the |
# Parse a comment block and merge the informations found in the |
Line 808 class CParser:
|
Line 813 class CParser:
|
# |
# |
def mergeFunctionComment(self, name, description, quiet = 0): |
def mergeFunctionComment(self, name, description, quiet = 0): |
if name == 'main': |
if name == 'main': |
quiet = 1 | quiet = 1 |
if name[0:2] == '__': |
if name[0:2] == '__': |
quiet = 1 | quiet = 1 |
|
|
(ret, args) = description | (ret, args) = description |
desc = "" | desc = "" |
retdesc = "" | retdesc = "" |
|
|
if self.comment == None: |
if self.comment == None: |
if not quiet: | if not quiet: |
self.warning("Missing comment for function %s" % (name)) | self.warning("Missing comment for function %s" % (name)) |
return(((ret[0], retdesc), args, desc)) | return(((ret[0], retdesc), args, desc)) |
if self.comment[0] != '*': |
if self.comment[0] != '*': |
if not quiet: | if not quiet: |
self.warning("Missing * in function comment for %s" % (name)) | self.warning("Missing * in function comment for %s" % (name)) |
return(((ret[0], retdesc), args, desc)) | return(((ret[0], retdesc), args, desc)) |
lines = string.split(self.comment, '\n') | lines = self.comment.split('\n') |
if lines[0] == '*': | if lines[0] == '*': |
del lines[0] | del lines[0] |
if lines[0] != "* %s:" % (name): | if lines[0] != "* %s:" % (name): |
if not quiet: | if not quiet: |
self.warning("Misformatted function comment for %s" % (name)) | self.warning("Misformatted function comment for %s" % (name)) |
self.warning(" Expecting '* %s:' got '%s'" % (name, lines[0])) | self.warning(" Expecting '* %s:' got '%s'" % (name, lines[0])) |
return(((ret[0], retdesc), args, desc)) | return(((ret[0], retdesc), args, desc)) |
del lines[0] | del lines[0] |
while lines[0] == '*': | while lines[0] == '*': |
del lines[0] | del lines[0] |
nbargs = len(args) | nbargs = len(args) |
while len(lines) > 0 and lines[0][0:3] == '* @': | while len(lines) > 0 and lines[0][0:3] == '* @': |
l = lines[0][3:] | l = lines[0][3:] |
try: | try: |
(arg, desc) = string.split(l, ':', 1) | (arg, desc) = l.split(':', 1) |
desc=string.strip(desc) | desc=desc.strip() |
arg=string.strip(arg) | arg=arg.strip() |
except: |
except: |
if not quiet: | if not quiet: |
self.warning("Misformatted function comment for %s" % (name)) | self.warning("Misformatted function comment for %s" % (name)) |
self.warning(" problem with '%s'" % (lines[0])) | self.warning(" problem with '%s'" % (lines[0])) |
del lines[0] | del lines[0] |
continue | continue |
del lines[0] | del lines[0] |
l = string.strip(lines[0]) | l = lines[0].strip() |
while len(l) > 2 and l[0:3] != '* @': | while len(l) > 2 and l[0:3] != '* @': |
while l[0] == '*': | while l[0] == '*': |
l = l[1:] | l = l[1:] |
desc = desc + ' ' + string.strip(l) | desc = desc + ' ' + l.strip() |
del lines[0] | del lines[0] |
if len(lines) == 0: | if len(lines) == 0: |
break | break |
l = lines[0] | l = lines[0] |
i = 0 | i = 0 |
while i < nbargs: | while i < nbargs: |
if args[i][1] == arg: | if args[i][1] == arg: |
args[i] = (args[i][0], arg, desc) | args[i] = (args[i][0], arg, desc) |
break; | break; |
i = i + 1 | i = i + 1 |
if i >= nbargs: | if i >= nbargs: |
if not quiet: | if not quiet: |
self.warning("Unable to find arg %s from function comment for %s" % ( | self.warning("Unable to find arg %s from function comment for %s" % ( |
arg, name)) | arg, name)) |
while len(lines) > 0 and lines[0] == '*': | while len(lines) > 0 and lines[0] == '*': |
del lines[0] | del lines[0] |
desc = "" | desc = "" |
while len(lines) > 0: | while len(lines) > 0: |
l = lines[0] | l = lines[0] |
while len(l) > 0 and l[0] == '*': | while len(l) > 0 and l[0] == '*': |
l = l[1:] | l = l[1:] |
l = string.strip(l) | l = l.strip() |
if len(l) >= 6 and l[0:6] == "return" or l[0:6] == "Return": | if len(l) >= 6 and l[0:6] == "return" or l[0:6] == "Return": |
try: | try: |
l = string.split(l, ' ', 1)[1] | l = l.split(' ', 1)[1] |
except: | except: |
l = "" | l = "" |
retdesc = string.strip(l) | retdesc = l.strip() |
del lines[0] | del lines[0] |
while len(lines) > 0: | while len(lines) > 0: |
l = lines[0] | l = lines[0] |
while len(l) > 0 and l[0] == '*': | while len(l) > 0 and l[0] == '*': |
l = l[1:] | l = l[1:] |
l = string.strip(l) | l = l.strip() |
retdesc = retdesc + " " + l | retdesc = retdesc + " " + l |
del lines[0] | del lines[0] |
else: | else: |
desc = desc + " " + l | desc = desc + " " + l |
del lines[0] | del lines[0] |
|
|
retdesc = string.strip(retdesc) | retdesc = retdesc.strip() |
desc = string.strip(desc) | desc = desc.strip() |
|
|
if quiet == 0: | if quiet == 0: |
# | # |
# report missing comments | # report missing comments |
# | # |
i = 0 | i = 0 |
while i < nbargs: | while i < nbargs: |
if args[i][2] == None and args[i][0] != "void" and \ | if args[i][2] == None and args[i][0] != "void" and \ |
((args[i][1] != None) or (args[i][1] == '')): | ((args[i][1] != None) or (args[i][1] == '')): |
self.warning("Function comment for %s lacks description of arg %s" % (name, args[i][1])) | self.warning("Function comment for %s lacks description of arg %s" % (name, args[i][1])) |
i = i + 1 | i = i + 1 |
if retdesc == "" and ret[0] != "void": | if retdesc == "" and ret[0] != "void": |
self.warning("Function comment for %s lacks description of return value" % (name)) | self.warning("Function comment for %s lacks description of return value" % (name)) |
if desc == "": | if desc == "": |
self.warning("Function comment for %s lacks description of the function" % (name)) | self.warning("Function comment for %s lacks description of the function" % (name)) |
|
|
return(((ret[0], retdesc), args, desc)) | return(((ret[0], retdesc), args, desc)) |
|
|
def parsePreproc(self, token): |
def parsePreproc(self, token): |
if debug: | if debug: |
print "=> preproc ", token, self.lexer.tokens | print("=> preproc ", token, self.lexer.tokens) |
name = token[1] |
name = token[1] |
if name == "#include": | if name == "#include": |
token = self.lexer.token() | token = self.lexer.token() |
if token == None: | if token == None: |
return None | return None |
if token[0] == 'preproc': | if token[0] == 'preproc': |
self.index_add(token[1], self.filename, not self.is_header, | self.index_add(token[1], self.filename, not self.is_header, |
"include") | "include") |
return self.lexer.token() | return self.lexer.token() |
return token | return token |
if name == "#define": | if name == "#define": |
token = self.lexer.token() | token = self.lexer.token() |
if token == None: | if token == None: |
return None | return None |
if token[0] == 'preproc': | if token[0] == 'preproc': |
# TODO macros with arguments | # TODO macros with arguments |
name = token[1] | name = token[1] |
lst = [] | lst = [] |
token = self.lexer.token() | token = self.lexer.token() |
while token != None and token[0] == 'preproc' and \ | while token != None and token[0] == 'preproc' and \ |
token[1][0] != '#': | token[1][0] != '#': |
lst.append(token[1]) | lst.append(token[1]) |
token = self.lexer.token() | token = self.lexer.token() |
try: |
try: |
name = string.split(name, '(') [0] | name = name.split('(') [0] |
except: |
except: |
pass |
pass |
info = self.parseMacroComment(name, not self.is_header) |
info = self.parseMacroComment(name, not self.is_header) |
self.index_add(name, self.filename, not self.is_header, | self.index_add(name, self.filename, not self.is_header, |
"macro", info) | "macro", info) |
return token | return token |
|
|
# | # |
# Processing of conditionals modified by Bill 1/1/05 | # Processing of conditionals modified by Bill 1/1/05 |
# | # |
# We process conditionals (i.e. tokens from #ifdef, #ifndef, | # We process conditionals (i.e. tokens from #ifdef, #ifndef, |
# #if, #else and #endif) for headers and mainline code, | # #if, #else and #endif) for headers and mainline code, |
# store the ones from the header in libxml2-api.xml, and later | # store the ones from the header in libxml2-api.xml, and later |
# (in the routine merge_public) verify that the two (header and | # (in the routine merge_public) verify that the two (header and |
# mainline code) agree. | # mainline code) agree. |
# | # |
# There is a small problem with processing the headers. Some of | # There is a small problem with processing the headers. Some of |
# the variables are not concerned with enabling / disabling of | # the variables are not concerned with enabling / disabling of |
# library functions (e.g. '__XML_PARSER_H__'), and we don't want | # library functions (e.g. '__XML_PARSER_H__'), and we don't want |
# them to be included in libxml2-api.xml, or involved in | # them to be included in libxml2-api.xml, or involved in |
# the check between the header and the mainline code. To | # the check between the header and the mainline code. To |
# accomplish this, we ignore any conditional which doesn't include | # accomplish this, we ignore any conditional which doesn't include |
# the string 'ENABLED' | # the string 'ENABLED' |
# | # |
if name == "#ifdef": | if name == "#ifdef": |
apstr = self.lexer.tokens[0][1] | apstr = self.lexer.tokens[0][1] |
try: | try: |
self.defines.append(apstr) | self.defines.append(apstr) |
if string.find(apstr, 'ENABLED') != -1: | if apstr.find('ENABLED') != -1: |
self.conditionals.append("defined(%s)" % apstr) | self.conditionals.append("defined(%s)" % apstr) |
except: | except: |
pass | pass |
elif name == "#ifndef": | elif name == "#ifndef": |
apstr = self.lexer.tokens[0][1] | apstr = self.lexer.tokens[0][1] |
try: | try: |
self.defines.append(apstr) | self.defines.append(apstr) |
if string.find(apstr, 'ENABLED') != -1: | if apstr.find('ENABLED') != -1: |
self.conditionals.append("!defined(%s)" % apstr) | self.conditionals.append("!defined(%s)" % apstr) |
except: | except: |
pass | pass |
elif name == "#if": | elif name == "#if": |
apstr = "" | apstr = "" |
for tok in self.lexer.tokens: | for tok in self.lexer.tokens: |
if apstr != "": | if apstr != "": |
apstr = apstr + " " | apstr = apstr + " " |
apstr = apstr + tok[1] | apstr = apstr + tok[1] |
try: | try: |
self.defines.append(apstr) | self.defines.append(apstr) |
if string.find(apstr, 'ENABLED') != -1: | if apstr.find('ENABLED') != -1: |
self.conditionals.append(apstr) | self.conditionals.append(apstr) |
except: | except: |
pass | pass |
elif name == "#else": | elif name == "#else": |
if self.conditionals != [] and \ | if self.conditionals != [] and \ |
string.find(self.defines[-1], 'ENABLED') != -1: | self.defines[-1].find('ENABLED') != -1: |
self.conditionals[-1] = "!(%s)" % self.conditionals[-1] | self.conditionals[-1] = "!(%s)" % self.conditionals[-1] |
elif name == "#endif": | elif name == "#endif": |
if self.conditionals != [] and \ | if self.conditionals != [] and \ |
string.find(self.defines[-1], 'ENABLED') != -1: | self.defines[-1].find('ENABLED') != -1: |
self.conditionals = self.conditionals[:-1] | self.conditionals = self.conditionals[:-1] |
self.defines = self.defines[:-1] | self.defines = self.defines[:-1] |
token = self.lexer.token() | token = self.lexer.token() |
while token != None and token[0] == 'preproc' and \ | while token != None and token[0] == 'preproc' and \ |
token[1][0] != '#': | token[1][0] != '#': |
token = self.lexer.token() | token = self.lexer.token() |
return token | return token |
|
|
# |
# |
# token acquisition on top of the lexer, it handle internally |
# token acquisition on top of the lexer, it handle internally |
Line 1018 class CParser:
|
Line 1023 class CParser:
|
global ignored_words |
global ignored_words |
|
|
token = self.lexer.token() |
token = self.lexer.token() |
while token != None: | while token != None: |
if token[0] == 'comment': | if token[0] == 'comment': |
token = self.parseComment(token) | token = self.parseComment(token) |
continue | continue |
elif token[0] == 'preproc': | elif token[0] == 'preproc': |
token = self.parsePreproc(token) | token = self.parsePreproc(token) |
continue | continue |
elif token[0] == "name" and token[1] == "__const": | elif token[0] == "name" and token[1] == "__const": |
token = ("name", "const") | token = ("name", "const") |
return token | return token |
elif token[0] == "name" and token[1] == "__attribute": | elif token[0] == "name" and token[1] == "__attribute": |
token = self.lexer.token() | token = self.lexer.token() |
while token != None and token[1] != ";": | while token != None and token[1] != ";": |
token = self.lexer.token() | token = self.lexer.token() |
return token | return token |
elif token[0] == "name" and ignored_words.has_key(token[1]): | elif token[0] == "name" and token[1] in ignored_words: |
(n, info) = ignored_words[token[1]] | (n, info) = ignored_words[token[1]] |
i = 0 | i = 0 |
while i < n: | while i < n: |
token = self.lexer.token() | token = self.lexer.token() |
i = i + 1 | i = i + 1 |
token = self.lexer.token() | token = self.lexer.token() |
continue | continue |
else: | else: |
if debug: | if debug: |
print "=> ", token | print("=> ", token) |
return token | return token |
return None | return None |
|
|
# |
# |
# Parse a typedef, it records the type and its name. |
# Parse a typedef, it records the type and its name. |
# |
# |
def parseTypedef(self, token): |
def parseTypedef(self, token): |
if token == None: |
if token == None: |
return None | return None |
token = self.parseType(token) | token = self.parseType(token) |
if token == None: | if token == None: |
self.error("parsing typedef") | self.error("parsing typedef") |
return None | return None |
base_type = self.type | base_type = self.type |
type = base_type | type = base_type |
#self.debug("end typedef type", token) | #self.debug("end typedef type", token) |
while token != None: | while token != None: |
if token[0] == "name": | if token[0] == "name": |
name = token[1] | name = token[1] |
signature = self.signature | signature = self.signature |
if signature != None: | if signature != None: |
type = string.split(type, '(')[0] | type = type.split('(')[0] |
d = self.mergeFunctionComment(name, | d = self.mergeFunctionComment(name, |
((type, None), signature), 1) | ((type, None), signature), 1) |
self.index_add(name, self.filename, not self.is_header, | self.index_add(name, self.filename, not self.is_header, |
"functype", d) | "functype", d) |
else: | else: |
if base_type == "struct": | if base_type == "struct": |
self.index_add(name, self.filename, not self.is_header, | self.index_add(name, self.filename, not self.is_header, |
"struct", type) | "struct", type) |
base_type = "struct " + name | base_type = "struct " + name |
else: | else: |
# TODO report missing or misformatted comments | # TODO report missing or misformatted comments |
info = self.parseTypeComment(name, 1) | info = self.parseTypeComment(name, 1) |
self.index_add(name, self.filename, not self.is_header, | self.index_add(name, self.filename, not self.is_header, |
"typedef", type, info) | "typedef", type, info) |
token = self.token() | token = self.token() |
else: | else: |
self.error("parsing typedef: expecting a name") | self.error("parsing typedef: expecting a name") |
return token | return token |
#self.debug("end typedef", token) | #self.debug("end typedef", token) |
if token != None and token[0] == 'sep' and token[1] == ',': | if token != None and token[0] == 'sep' and token[1] == ',': |
type = base_type | type = base_type |
token = self.token() | token = self.token() |
while token != None and token[0] == "op": | while token != None and token[0] == "op": |
type = type + token[1] | type = type + token[1] |
token = self.token() | token = self.token() |
elif token != None and token[0] == 'sep' and token[1] == ';': | elif token != None and token[0] == 'sep' and token[1] == ';': |
break; | break; |
elif token != None and token[0] == 'name': | elif token != None and token[0] == 'name': |
type = base_type | type = base_type |
continue; | continue; |
else: | else: |
self.error("parsing typedef: expecting ';'", token) | self.error("parsing typedef: expecting ';'", token) |
return token | return token |
token = self.token() | token = self.token() |
return token | return token |
|
|
# |
# |
# Parse a C code block, used for functions it parse till |
# Parse a C code block, used for functions it parse till |
Line 1108 class CParser:
|
Line 1113 class CParser:
|
# |
# |
def parseBlock(self, token): |
def parseBlock(self, token): |
while token != None: |
while token != None: |
if token[0] == "sep" and token[1] == "{": | if token[0] == "sep" and token[1] == "{": |
token = self.token() | token = self.token() |
token = self.parseBlock(token) | token = self.parseBlock(token) |
elif token[0] == "sep" and token[1] == "}": | elif token[0] == "sep" and token[1] == "}": |
self.comment = None | self.comment = None |
token = self.token() | token = self.token() |
return token | return token |
else: | else: |
if self.collect_ref == 1: | if self.collect_ref == 1: |
oldtok = token | oldtok = token |
token = self.token() | token = self.token() |
if oldtok[0] == "name" and oldtok[1][0:3] == "xml": | if oldtok[0] == "name" and oldtok[1][0:3] == "xml": |
if token[0] == "sep" and token[1] == "(": | if token[0] == "sep" and token[1] == "(": |
self.index_add_ref(oldtok[1], self.filename, | self.index_add_ref(oldtok[1], self.filename, |
0, "function") | 0, "function") |
token = self.token() | token = self.token() |
elif token[0] == "name": | elif token[0] == "name": |
token = self.token() | token = self.token() |
if token[0] == "sep" and (token[1] == ";" or | if token[0] == "sep" and (token[1] == ";" or |
token[1] == "," or token[1] == "="): | token[1] == "," or token[1] == "="): |
self.index_add_ref(oldtok[1], self.filename, | self.index_add_ref(oldtok[1], self.filename, |
0, "type") | 0, "type") |
elif oldtok[0] == "name" and oldtok[1][0:4] == "XML_": | elif oldtok[0] == "name" and oldtok[1][0:4] == "XML_": |
self.index_add_ref(oldtok[1], self.filename, | self.index_add_ref(oldtok[1], self.filename, |
0, "typedef") | 0, "typedef") |
elif oldtok[0] == "name" and oldtok[1][0:7] == "LIBXML_": | elif oldtok[0] == "name" and oldtok[1][0:7] == "LIBXML_": |
self.index_add_ref(oldtok[1], self.filename, | self.index_add_ref(oldtok[1], self.filename, |
0, "typedef") | 0, "typedef") |
|
|
else: | else: |
token = self.token() | token = self.token() |
return token | return token |
|
|
# |
# |
# Parse a C struct definition till the balancing } |
# Parse a C struct definition till the balancing } |
# |
# |
def parseStruct(self, token): |
def parseStruct(self, token): |
fields = [] |
fields = [] |
#self.debug("start parseStruct", token) | #self.debug("start parseStruct", token) |
while token != None: |
while token != None: |
if token[0] == "sep" and token[1] == "{": | if token[0] == "sep" and token[1] == "{": |
token = self.token() | token = self.token() |
token = self.parseTypeBlock(token) | token = self.parseTypeBlock(token) |
elif token[0] == "sep" and token[1] == "}": | elif token[0] == "sep" and token[1] == "}": |
self.struct_fields = fields | self.struct_fields = fields |
#self.debug("end parseStruct", token) | #self.debug("end parseStruct", token) |
#print fields | #print fields |
token = self.token() | token = self.token() |
return token | return token |
else: | else: |
base_type = self.type | base_type = self.type |
#self.debug("before parseType", token) | #self.debug("before parseType", token) |
token = self.parseType(token) | token = self.parseType(token) |
#self.debug("after parseType", token) | #self.debug("after parseType", token) |
if token != None and token[0] == "name": | if token != None and token[0] == "name": |
fname = token[1] | fname = token[1] |
token = self.token() | token = self.token() |
if token[0] == "sep" and token[1] == ";": | if token[0] == "sep" and token[1] == ";": |
self.comment = None | self.comment = None |
token = self.token() | token = self.token() |
fields.append((self.type, fname, self.comment)) | fields.append((self.type, fname, self.comment)) |
self.comment = None | self.comment = None |
else: | else: |
self.error("parseStruct: expecting ;", token) | self.error("parseStruct: expecting ;", token) |
elif token != None and token[0] == "sep" and token[1] == "{": | elif token != None and token[0] == "sep" and token[1] == "{": |
token = self.token() | token = self.token() |
token = self.parseTypeBlock(token) | token = self.parseTypeBlock(token) |
if token != None and token[0] == "name": | if token != None and token[0] == "name": |
token = self.token() | token = self.token() |
if token != None and token[0] == "sep" and token[1] == ";": | if token != None and token[0] == "sep" and token[1] == ";": |
token = self.token() | token = self.token() |
else: | else: |
self.error("parseStruct: expecting ;", token) | self.error("parseStruct: expecting ;", token) |
else: | else: |
self.error("parseStruct: name", token) | self.error("parseStruct: name", token) |
token = self.token() | token = self.token() |
self.type = base_type; | self.type = base_type; |
self.struct_fields = fields |
self.struct_fields = fields |
#self.debug("end parseStruct", token) | #self.debug("end parseStruct", token) |
#print fields | #print fields |
return token | return token |
|
|
# |
# |
# Parse a C enum block, parse till the balancing } |
# Parse a C enum block, parse till the balancing } |
# |
# |
def parseEnumBlock(self, token): |
def parseEnumBlock(self, token): |
self.enums = [] |
self.enums = [] |
name = None | name = None |
self.comment = None | self.comment = None |
comment = "" | comment = "" |
value = "0" | value = "0" |
while token != None: |
while token != None: |
if token[0] == "sep" and token[1] == "{": | if token[0] == "sep" and token[1] == "{": |
token = self.token() | token = self.token() |
token = self.parseTypeBlock(token) | token = self.parseTypeBlock(token) |
elif token[0] == "sep" and token[1] == "}": | elif token[0] == "sep" and token[1] == "}": |
if name != None: | if name != None: |
if self.comment != None: | if self.comment != None: |
comment = self.comment | comment = self.comment |
self.comment = None | self.comment = None |
self.enums.append((name, value, comment)) | self.enums.append((name, value, comment)) |
token = self.token() | token = self.token() |
return token | return token |
elif token[0] == "name": | elif token[0] == "name": |
if name != None: | if name != None: |
if self.comment != None: | if self.comment != None: |
comment = string.strip(self.comment) | comment = self.comment.strip() |
self.comment = None | self.comment = None |
self.enums.append((name, value, comment)) | self.enums.append((name, value, comment)) |
name = token[1] | name = token[1] |
comment = "" | comment = "" |
token = self.token() | token = self.token() |
if token[0] == "op" and token[1][0] == "=": | if token[0] == "op" and token[1][0] == "=": |
value = "" | value = "" |
if len(token[1]) > 1: | if len(token[1]) > 1: |
value = token[1][1:] | value = token[1][1:] |
token = self.token() | token = self.token() |
while token[0] != "sep" or (token[1] != ',' and | while token[0] != "sep" or (token[1] != ',' and |
token[1] != '}'): | token[1] != '}'): |
value = value + token[1] | value = value + token[1] |
token = self.token() | token = self.token() |
else: | else: |
try: | try: |
value = "%d" % (int(value) + 1) | value = "%d" % (int(value) + 1) |
except: | except: |
self.warning("Failed to compute value of enum %s" % (name)) | self.warning("Failed to compute value of enum %s" % (name)) |
value="" | value="" |
if token[0] == "sep" and token[1] == ",": | if token[0] == "sep" and token[1] == ",": |
token = self.token() | token = self.token() |
else: | else: |
token = self.token() | token = self.token() |
return token | return token |
|
|
# |
# |
# Parse a C definition block, used for structs it parse till |
# Parse a C definition block, used for structs it parse till |
Line 1247 class CParser:
|
Line 1252 class CParser:
|
# |
# |
def parseTypeBlock(self, token): |
def parseTypeBlock(self, token): |
while token != None: |
while token != None: |
if token[0] == "sep" and token[1] == "{": | if token[0] == "sep" and token[1] == "{": |
token = self.token() | token = self.token() |
token = self.parseTypeBlock(token) | token = self.parseTypeBlock(token) |
elif token[0] == "sep" and token[1] == "}": | elif token[0] == "sep" and token[1] == "}": |
token = self.token() | token = self.token() |
return token | return token |
else: | else: |
token = self.token() | token = self.token() |
return token | return token |
|
|
# |
# |
# Parse a type: the fact that the type name can either occur after |
# Parse a type: the fact that the type name can either occur after |
Line 1264 class CParser:
|
Line 1269 class CParser:
|
# |
# |
def parseType(self, token): |
def parseType(self, token): |
self.type = "" |
self.type = "" |
self.struct_fields = [] | self.struct_fields = [] |
self.signature = None |
self.signature = None |
if token == None: | if token == None: |
return token | return token |
|
|
while token[0] == "name" and ( | while token[0] == "name" and ( |
token[1] == "const" or \ | token[1] == "const" or \ |
token[1] == "unsigned" or \ | token[1] == "unsigned" or \ |
token[1] == "signed"): | token[1] == "signed"): |
if self.type == "": | if self.type == "": |
self.type = token[1] | self.type = token[1] |
else: | else: |
self.type = self.type + " " + token[1] | self.type = self.type + " " + token[1] |
token = self.token() | token = self.token() |
|
|
if token[0] == "name" and (token[1] == "long" or token[1] == "short"): |
if token[0] == "name" and (token[1] == "long" or token[1] == "short"): |
if self.type == "": | if self.type == "": |
self.type = token[1] | self.type = token[1] |
else: | else: |
self.type = self.type + " " + token[1] | self.type = self.type + " " + token[1] |
if token[0] == "name" and token[1] == "int": | if token[0] == "name" and token[1] == "int": |
if self.type == "": | if self.type == "": |
self.type = tmp[1] | self.type = tmp[1] |
else: | else: |
self.type = self.type + " " + tmp[1] | self.type = self.type + " " + tmp[1] |
|
|
elif token[0] == "name" and token[1] == "struct": |
elif token[0] == "name" and token[1] == "struct": |
if self.type == "": | if self.type == "": |
self.type = token[1] | self.type = token[1] |
else: | else: |
self.type = self.type + " " + token[1] | self.type = self.type + " " + token[1] |
token = self.token() | token = self.token() |
nametok = None | nametok = None |
if token[0] == "name": | if token[0] == "name": |
nametok = token | nametok = token |
token = self.token() | token = self.token() |
if token != None and token[0] == "sep" and token[1] == "{": | if token != None and token[0] == "sep" and token[1] == "{": |
token = self.token() | token = self.token() |
token = self.parseStruct(token) | token = self.parseStruct(token) |
elif token != None and token[0] == "op" and token[1] == "*": | elif token != None and token[0] == "op" and token[1] == "*": |
self.type = self.type + " " + nametok[1] + " *" | self.type = self.type + " " + nametok[1] + " *" |
token = self.token() | token = self.token() |
while token != None and token[0] == "op" and token[1] == "*": | while token != None and token[0] == "op" and token[1] == "*": |
self.type = self.type + " *" | self.type = self.type + " *" |
token = self.token() | token = self.token() |
if token[0] == "name": | if token[0] == "name": |
nametok = token | nametok = token |
token = self.token() | token = self.token() |
else: | else: |
self.error("struct : expecting name", token) | self.error("struct : expecting name", token) |
return token | return token |
elif token != None and token[0] == "name" and nametok != None: | elif token != None and token[0] == "name" and nametok != None: |
self.type = self.type + " " + nametok[1] | self.type = self.type + " " + nametok[1] |
return token | return token |
|
|
if nametok != None: | if nametok != None: |
self.lexer.push(token) | self.lexer.push(token) |
token = nametok | token = nametok |
return token | return token |
|
|
elif token[0] == "name" and token[1] == "enum": |
elif token[0] == "name" and token[1] == "enum": |
if self.type == "": | if self.type == "": |
self.type = token[1] | self.type = token[1] |
else: | else: |
self.type = self.type + " " + token[1] | self.type = self.type + " " + token[1] |
self.enums = [] | self.enums = [] |
token = self.token() | token = self.token() |
if token != None and token[0] == "sep" and token[1] == "{": | if token != None and token[0] == "sep" and token[1] == "{": |
token = self.token() | token = self.token() |
token = self.parseEnumBlock(token) | token = self.parseEnumBlock(token) |
else: | else: |
self.error("parsing enum: expecting '{'", token) | self.error("parsing enum: expecting '{'", token) |
enum_type = None | enum_type = None |
if token != None and token[0] != "name": | if token != None and token[0] != "name": |
self.lexer.push(token) | self.lexer.push(token) |
token = ("name", "enum") | token = ("name", "enum") |
else: | else: |
enum_type = token[1] | enum_type = token[1] |
for enum in self.enums: | for enum in self.enums: |
self.index_add(enum[0], self.filename, | self.index_add(enum[0], self.filename, |
not self.is_header, "enum", | not self.is_header, "enum", |
(enum[1], enum[2], enum_type)) | (enum[1], enum[2], enum_type)) |
return token | return token |
|
|
elif token[0] == "name": | elif token[0] == "name": |
if self.type == "": | if self.type == "": |
self.type = token[1] | self.type = token[1] |
else: | else: |
self.type = self.type + " " + token[1] | self.type = self.type + " " + token[1] |
else: | else: |
self.error("parsing type %s: expecting a name" % (self.type), | self.error("parsing type %s: expecting a name" % (self.type), |
token) | token) |
return token | return token |
token = self.token() | token = self.token() |
while token != None and (token[0] == "op" or |
while token != None and (token[0] == "op" or |
token[0] == "name" and token[1] == "const"): | token[0] == "name" and token[1] == "const"): |
self.type = self.type + " " + token[1] | self.type = self.type + " " + token[1] |
token = self.token() | token = self.token() |
|
|
# | # |
# if there is a parenthesis here, this means a function type | # if there is a parenthesis here, this means a function type |
# | # |
if token != None and token[0] == "sep" and token[1] == '(': | if token != None and token[0] == "sep" and token[1] == '(': |
self.type = self.type + token[1] | self.type = self.type + token[1] |
token = self.token() | token = self.token() |
while token != None and token[0] == "op" and token[1] == '*': | while token != None and token[0] == "op" and token[1] == '*': |
self.type = self.type + token[1] | self.type = self.type + token[1] |
token = self.token() | token = self.token() |
if token == None or token[0] != "name" : | if token == None or token[0] != "name" : |
self.error("parsing function type, name expected", token); | self.error("parsing function type, name expected", token); |
return token | return token |
self.type = self.type + token[1] | self.type = self.type + token[1] |
nametok = token | nametok = token |
token = self.token() | token = self.token() |
if token != None and token[0] == "sep" and token[1] == ')': | if token != None and token[0] == "sep" and token[1] == ')': |
self.type = self.type + token[1] | self.type = self.type + token[1] |
token = self.token() | token = self.token() |
if token != None and token[0] == "sep" and token[1] == '(': | if token != None and token[0] == "sep" and token[1] == '(': |
token = self.token() | token = self.token() |
type = self.type; | type = self.type; |
token = self.parseSignature(token); | token = self.parseSignature(token); |
self.type = type; | self.type = type; |
else: | else: |
self.error("parsing function type, '(' expected", token); | self.error("parsing function type, '(' expected", token); |
return token | return token |
else: | else: |
self.error("parsing function type, ')' expected", token); | self.error("parsing function type, ')' expected", token); |
return token | return token |
self.lexer.push(token) | self.lexer.push(token) |
token = nametok | token = nametok |
return token | return token |
|
|
# |
# |
# do some lookahead for arrays | # do some lookahead for arrays |
# | # |
if token != None and token[0] == "name": | if token != None and token[0] == "name": |
nametok = token | nametok = token |
token = self.token() | token = self.token() |
if token != None and token[0] == "sep" and token[1] == '[': | if token != None and token[0] == "sep" and token[1] == '[': |
self.type = self.type + nametok[1] | self.type = self.type + nametok[1] |
while token != None and token[0] == "sep" and token[1] == '[': | while token != None and token[0] == "sep" and token[1] == '[': |
self.type = self.type + token[1] | self.type = self.type + token[1] |
token = self.token() | token = self.token() |
while token != None and token[0] != 'sep' and \ | while token != None and token[0] != 'sep' and \ |
token[1] != ']' and token[1] != ';': | token[1] != ']' and token[1] != ';': |
self.type = self.type + token[1] | self.type = self.type + token[1] |
token = self.token() | token = self.token() |
if token != None and token[0] == 'sep' and token[1] == ']': | if token != None and token[0] == 'sep' and token[1] == ']': |
self.type = self.type + token[1] | self.type = self.type + token[1] |
token = self.token() | token = self.token() |
else: | else: |
self.error("parsing array type, ']' expected", token); | self.error("parsing array type, ']' expected", token); |
return token | return token |
elif token != None and token[0] == "sep" and token[1] == ':': | elif token != None and token[0] == "sep" and token[1] == ':': |
# remove :12 in case it's a limited int size | # remove :12 in case it's a limited int size |
token = self.token() | token = self.token() |
token = self.token() | token = self.token() |
self.lexer.push(token) | self.lexer.push(token) |
token = nametok | token = nametok |
|
|
return token | return token |
|
|
# |
# |
# Parse a signature: '(' has been parsed and we scan the type definition |
# Parse a signature: '(' has been parsed and we scan the type definition |
# up to the ')' included |
# up to the ')' included |
def parseSignature(self, token): |
def parseSignature(self, token): |
signature = [] |
signature = [] |
if token != None and token[0] == "sep" and token[1] == ')': | if token != None and token[0] == "sep" and token[1] == ')': |
self.signature = [] | self.signature = [] |
token = self.token() | token = self.token() |
return token | return token |
while token != None: | while token != None: |
token = self.parseType(token) | token = self.parseType(token) |
if token != None and token[0] == "name": | if token != None and token[0] == "name": |
signature.append((self.type, token[1], None)) | signature.append((self.type, token[1], None)) |
token = self.token() | token = self.token() |
elif token != None and token[0] == "sep" and token[1] == ',': | elif token != None and token[0] == "sep" and token[1] == ',': |
token = self.token() | token = self.token() |
continue | continue |
elif token != None and token[0] == "sep" and token[1] == ')': | elif token != None and token[0] == "sep" and token[1] == ')': |
# only the type was provided | # only the type was provided |
if self.type == "...": | if self.type == "...": |
signature.append((self.type, "...", None)) | signature.append((self.type, "...", None)) |
else: | else: |
signature.append((self.type, None, None)) | signature.append((self.type, None, None)) |
if token != None and token[0] == "sep": | if token != None and token[0] == "sep": |
if token[1] == ',': | if token[1] == ',': |
token = self.token() | token = self.token() |
continue | continue |
elif token[1] == ')': | elif token[1] == ')': |
token = self.token() | token = self.token() |
break | break |
self.signature = signature | self.signature = signature |
return token | return token |
|
|
# |
# |
# Parse a global definition, be it a type, variable or function |
# Parse a global definition, be it a type, variable or function |
Line 1466 class CParser:
|
Line 1471 class CParser:
|
def parseGlobal(self, token): |
def parseGlobal(self, token): |
static = 0 |
static = 0 |
if token[1] == 'extern': |
if token[1] == 'extern': |
token = self.token() | token = self.token() |
if token == None: | if token == None: |
return token | return token |
if token[0] == 'string': | if token[0] == 'string': |
if token[1] == 'C': | if token[1] == 'C': |
token = self.token() | token = self.token() |
if token == None: | if token == None: |
return token | return token |
if token[0] == 'sep' and token[1] == "{": | if token[0] == 'sep' and token[1] == "{": |
token = self.token() | token = self.token() |
# print 'Entering extern "C line ', self.lineno() | # print 'Entering extern "C line ', self.lineno() |
while token != None and (token[0] != 'sep' or | while token != None and (token[0] != 'sep' or |
token[1] != "}"): | token[1] != "}"): |
if token[0] == 'name': | if token[0] == 'name': |
token = self.parseGlobal(token) | token = self.parseGlobal(token) |
else: | else: |
self.error( | self.error( |
"token %s %s unexpected at the top level" % ( | "token %s %s unexpected at the top level" % ( |
token[0], token[1])) | token[0], token[1])) |
token = self.parseGlobal(token) | token = self.parseGlobal(token) |
# print 'Exiting extern "C" line', self.lineno() | # print 'Exiting extern "C" line', self.lineno() |
token = self.token() | token = self.token() |
return token | return token |
else: | else: |
return token | return token |
elif token[1] == 'static': | elif token[1] == 'static': |
static = 1 | static = 1 |
token = self.token() | token = self.token() |
if token == None or token[0] != 'name': | if token == None or token[0] != 'name': |
return token | return token |
|
|
if token[1] == 'typedef': | if token[1] == 'typedef': |
token = self.token() | token = self.token() |
return self.parseTypedef(token) | return self.parseTypedef(token) |
else: | else: |
token = self.parseType(token) | token = self.parseType(token) |
type_orig = self.type | type_orig = self.type |
if token == None or token[0] != "name": | if token == None or token[0] != "name": |
return token | return token |
type = type_orig | type = type_orig |
self.name = token[1] | self.name = token[1] |
token = self.token() | token = self.token() |
while token != None and (token[0] == "sep" or token[0] == "op"): | while token != None and (token[0] == "sep" or token[0] == "op"): |
if token[0] == "sep": | if token[0] == "sep": |
if token[1] == "[": | if token[1] == "[": |
type = type + token[1] | type = type + token[1] |
token = self.token() | token = self.token() |
while token != None and (token[0] != "sep" or \ | while token != None and (token[0] != "sep" or \ |
token[1] != ";"): | token[1] != ";"): |
type = type + token[1] | type = type + token[1] |
token = self.token() | token = self.token() |
|
|
if token != None and token[0] == "op" and token[1] == "=": | if token != None and token[0] == "op" and token[1] == "=": |
# | # |
# Skip the initialization of the variable | # Skip the initialization of the variable |
# | # |
token = self.token() | token = self.token() |
if token[0] == 'sep' and token[1] == '{': | if token[0] == 'sep' and token[1] == '{': |
token = self.token() | token = self.token() |
token = self.parseBlock(token) | token = self.parseBlock(token) |
else: | else: |
self.comment = None | self.comment = None |
while token != None and (token[0] != "sep" or \ | while token != None and (token[0] != "sep" or \ |
(token[1] != ';' and token[1] != ',')): | (token[1] != ';' and token[1] != ',')): |
token = self.token() | token = self.token() |
self.comment = None | self.comment = None |
if token == None or token[0] != "sep" or (token[1] != ';' and | if token == None or token[0] != "sep" or (token[1] != ';' and |
token[1] != ','): | token[1] != ','): |
self.error("missing ';' or ',' after value") | self.error("missing ';' or ',' after value") |
|
|
if token != None and token[0] == "sep": | if token != None and token[0] == "sep": |
if token[1] == ";": | if token[1] == ";": |
self.comment = None | self.comment = None |
token = self.token() | token = self.token() |
if type == "struct": | if type == "struct": |
self.index_add(self.name, self.filename, | self.index_add(self.name, self.filename, |
not self.is_header, "struct", self.struct_fields) | not self.is_header, "struct", self.struct_fields) |
else: | else: |
self.index_add(self.name, self.filename, | self.index_add(self.name, self.filename, |
not self.is_header, "variable", type) | not self.is_header, "variable", type) |
break | break |
elif token[1] == "(": | elif token[1] == "(": |
token = self.token() | token = self.token() |
token = self.parseSignature(token) | token = self.parseSignature(token) |
if token == None: | if token == None: |
return None | return None |
if token[0] == "sep" and token[1] == ";": | if token[0] == "sep" and token[1] == ";": |
d = self.mergeFunctionComment(self.name, | d = self.mergeFunctionComment(self.name, |
((type, None), self.signature), 1) | ((type, None), self.signature), 1) |
self.index_add(self.name, self.filename, static, | self.index_add(self.name, self.filename, static, |
"function", d) | "function", d) |
token = self.token() | token = self.token() |
elif token[0] == "sep" and token[1] == "{": | elif token[0] == "sep" and token[1] == "{": |
d = self.mergeFunctionComment(self.name, | d = self.mergeFunctionComment(self.name, |
((type, None), self.signature), static) | ((type, None), self.signature), static) |
self.index_add(self.name, self.filename, static, | self.index_add(self.name, self.filename, static, |
"function", d) | "function", d) |
token = self.token() | token = self.token() |
token = self.parseBlock(token); | token = self.parseBlock(token); |
elif token[1] == ',': | elif token[1] == ',': |
self.comment = None | self.comment = None |
self.index_add(self.name, self.filename, static, | self.index_add(self.name, self.filename, static, |
"variable", type) | "variable", type) |
type = type_orig | type = type_orig |
token = self.token() | token = self.token() |
while token != None and token[0] == "sep": | while token != None and token[0] == "sep": |
type = type + token[1] | type = type + token[1] |
token = self.token() | token = self.token() |
if token != None and token[0] == "name": | if token != None and token[0] == "name": |
self.name = token[1] | self.name = token[1] |
token = self.token() | token = self.token() |
else: | else: |
break | break |
|
|
return token | return token |
|
|
def parse(self): |
def parse(self): |
self.warning("Parsing %s" % (self.filename)) |
self.warning("Parsing %s" % (self.filename)) |
token = self.token() |
token = self.token() |
while token != None: | while token != None: |
if token[0] == 'name': |
if token[0] == 'name': |
token = self.parseGlobal(token) | token = self.parseGlobal(token) |
else: |
else: |
self.error("token %s %s unexpected at the top level" % ( | self.error("token %s %s unexpected at the top level" % ( |
token[0], token[1])) | token[0], token[1])) |
token = self.parseGlobal(token) | token = self.parseGlobal(token) |
return | return |
self.parseTopComment(self.top_comment) | self.parseTopComment(self.top_comment) |
return self.index |
return self.index |
|
|
|
|
Line 1602 class docBuilder:
|
Line 1607 class docBuilder:
|
def __init__(self, name, directories=['.'], excludes=[]): |
def __init__(self, name, directories=['.'], excludes=[]): |
self.name = name |
self.name = name |
self.directories = directories |
self.directories = directories |
self.excludes = excludes + ignored_files.keys() | self.excludes = excludes + list(ignored_files.keys()) |
self.modules = {} | self.modules = {} |
self.headers = {} | self.headers = {} |
self.idx = index() | self.idx = index() |
self.xref = {} |
self.xref = {} |
self.index = {} | self.index = {} |
if name == 'libxml2': | if name == 'libxml2': |
self.basename = 'libxml' | self.basename = 'libxml' |
else: | else: |
self.basename = name | self.basename = name |
|
|
def indexString(self, id, str): |
def indexString(self, id, str): |
if str == None: | if str == None: |
return | return |
str = string.replace(str, "'", ' ') | str = str.replace("'", ' ') |
str = string.replace(str, '"', ' ') | str = str.replace('"', ' ') |
str = string.replace(str, "/", ' ') | str = str.replace("/", ' ') |
str = string.replace(str, '*', ' ') | str = str.replace('*', ' ') |
str = string.replace(str, "[", ' ') | str = str.replace("[", ' ') |
str = string.replace(str, "]", ' ') | str = str.replace("]", ' ') |
str = string.replace(str, "(", ' ') | str = str.replace("(", ' ') |
str = string.replace(str, ")", ' ') | str = str.replace(")", ' ') |
str = string.replace(str, "<", ' ') | str = str.replace("<", ' ') |
str = string.replace(str, '>', ' ') | str = str.replace('>', ' ') |
str = string.replace(str, "&", ' ') | str = str.replace("&", ' ') |
str = string.replace(str, '#', ' ') | str = str.replace('#', ' ') |
str = string.replace(str, ",", ' ') | str = str.replace(",", ' ') |
str = string.replace(str, '.', ' ') | str = str.replace('.', ' ') |
str = string.replace(str, ';', ' ') | str = str.replace(';', ' ') |
tokens = string.split(str) | tokens = str.split() |
for token in tokens: | for token in tokens: |
try: | try: |
c = token[0] | c = token[0] |
if string.find(string.letters, c) < 0: | if string.ascii_letters.find(c) < 0: |
pass | pass |
elif len(token) < 3: | elif len(token) < 3: |
pass | pass |
else: | else: |
lower = string.lower(token) | lower = token.lower() |
# TODO: generalize this a bit | # TODO: generalize this a bit |
if lower == 'and' or lower == 'the': | if lower == 'and' or lower == 'the': |
pass | pass |
elif self.xref.has_key(token): | elif token in self.xref: |
self.xref[token].append(id) | self.xref[token].append(id) |
else: | else: |
self.xref[token] = [id] | self.xref[token] = [id] |
except: | except: |
pass | pass |
|
|
def analyze(self): |
def analyze(self): |
print "Project %s : %d headers, %d modules" % (self.name, len(self.headers.keys()), len(self.modules.keys())) | print("Project %s : %d headers, %d modules" % (self.name, len(list(self.headers.keys())), len(list(self.modules.keys())))) |
self.idx.analyze() | self.idx.analyze() |
|
|
def scanHeaders(self): |
def scanHeaders(self): |
for header in self.headers.keys(): | for header in list(self.headers.keys()): |
parser = CParser(header) | parser = CParser(header) |
idx = parser.parse() | idx = parser.parse() |
self.headers[header] = idx; | self.headers[header] = idx; |
self.idx.merge(idx) | self.idx.merge(idx) |
|
|
def scanModules(self): |
def scanModules(self): |
for module in self.modules.keys(): | for module in list(self.modules.keys()): |
parser = CParser(module) | parser = CParser(module) |
idx = parser.parse() | idx = parser.parse() |
# idx.analyze() | # idx.analyze() |
self.modules[module] = idx | self.modules[module] = idx |
self.idx.merge_public(idx) | self.idx.merge_public(idx) |
|
|
def scan(self): |
def scan(self): |
for directory in self.directories: |
for directory in self.directories: |
files = glob.glob(directory + "/*.c") | files = glob.glob(directory + "/*.c") |
for file in files: | for file in files: |
skip = 0 | skip = 0 |
for excl in self.excludes: | for excl in self.excludes: |
if string.find(file, excl) != -1: | if file.find(excl) != -1: |
skip = 1; | print("Skipping %s" % file) |
break | skip = 1 |
if skip == 0: | break |
self.modules[file] = None; | if skip == 0: |
files = glob.glob(directory + "/*.h") | self.modules[file] = None; |
for file in files: | files = glob.glob(directory + "/*.h") |
skip = 0 | for file in files: |
for excl in self.excludes: | skip = 0 |
if string.find(file, excl) != -1: | for excl in self.excludes: |
skip = 1; | if file.find(excl) != -1: |
break | print("Skipping %s" % file) |
if skip == 0: | skip = 1 |
self.headers[file] = None; | break |
self.scanHeaders() | if skip == 0: |
self.scanModules() | self.headers[file] = None; |
| self.scanHeaders() |
| self.scanModules() |
|
|
def modulename_file(self, file): |
def modulename_file(self, file): |
module = os.path.basename(file) |
module = os.path.basename(file) |
if module[-2:] == '.h': | if module[-2:] == '.h': |
module = module[:-2] | module = module[:-2] |
elif module[-2:] == '.c': | elif module[-2:] == '.c': |
module = module[:-2] | module = module[:-2] |
return module | return module |
|
|
def serialize_enum(self, output, name): |
def serialize_enum(self, output, name): |
id = self.idx.enums[name] |
id = self.idx.enums[name] |
output.write(" <enum name='%s' file='%s'" % (name, |
output.write(" <enum name='%s' file='%s'" % (name, |
self.modulename_file(id.header))) | self.modulename_file(id.header))) |
if id.info != None: | if id.info != None: |
info = id.info | info = id.info |
if info[0] != None and info[0] != '': | if info[0] != None and info[0] != '': |
try: | try: |
val = eval(info[0]) | val = eval(info[0]) |
except: | except: |
val = info[0] | val = info[0] |
output.write(" value='%s'" % (val)); | output.write(" value='%s'" % (val)); |
if info[2] != None and info[2] != '': | if info[2] != None and info[2] != '': |
output.write(" type='%s'" % info[2]); | output.write(" type='%s'" % info[2]); |
if info[1] != None and info[1] != '': | if info[1] != None and info[1] != '': |
output.write(" info='%s'" % escape(info[1])); | output.write(" info='%s'" % escape(info[1])); |
output.write("/>\n") |
output.write("/>\n") |
|
|
def serialize_macro(self, output, name): |
def serialize_macro(self, output, name): |
id = self.idx.macros[name] |
id = self.idx.macros[name] |
output.write(" <macro name='%s' file='%s'>\n" % (name, |
output.write(" <macro name='%s' file='%s'>\n" % (name, |
self.modulename_file(id.header))) | self.modulename_file(id.header))) |
if id.info != None: | if id.info != None: |
try: |
try: |
(args, desc) = id.info | (args, desc) = id.info |
if desc != None and desc != "": | if desc != None and desc != "": |
output.write(" <info>%s</info>\n" % (escape(desc))) | output.write(" <info>%s</info>\n" % (escape(desc))) |
self.indexString(name, desc) | self.indexString(name, desc) |
for arg in args: | for arg in args: |
(name, desc) = arg | (name, desc) = arg |
if desc != None and desc != "": | if desc != None and desc != "": |
output.write(" <arg name='%s' info='%s'/>\n" % ( | output.write(" <arg name='%s' info='%s'/>\n" % ( |
name, escape(desc))) | name, escape(desc))) |
self.indexString(name, desc) | self.indexString(name, desc) |
else: | else: |
output.write(" <arg name='%s'/>\n" % (name)) | output.write(" <arg name='%s'/>\n" % (name)) |
except: |
except: |
pass |
pass |
output.write(" </macro>\n") |
output.write(" </macro>\n") |
|
|
def serialize_typedef(self, output, name): |
def serialize_typedef(self, output, name): |
id = self.idx.typedefs[name] |
id = self.idx.typedefs[name] |
if id.info[0:7] == 'struct ': | if id.info[0:7] == 'struct ': |
output.write(" <struct name='%s' file='%s' type='%s'" % ( | output.write(" <struct name='%s' file='%s' type='%s'" % ( |
name, self.modulename_file(id.header), id.info)) | name, self.modulename_file(id.header), id.info)) |
name = id.info[7:] | name = id.info[7:] |
if self.idx.structs.has_key(name) and ( \ | if name in self.idx.structs and ( \ |
type(self.idx.structs[name].info) == type(()) or | type(self.idx.structs[name].info) == type(()) or |
type(self.idx.structs[name].info) == type([])): | type(self.idx.structs[name].info) == type([])): |
output.write(">\n"); | output.write(">\n"); |
try: | try: |
for field in self.idx.structs[name].info: | for field in self.idx.structs[name].info: |
desc = field[2] | desc = field[2] |
self.indexString(name, desc) | self.indexString(name, desc) |
if desc == None: | if desc == None: |
desc = '' | desc = '' |
else: | else: |
desc = escape(desc) | desc = escape(desc) |
output.write(" <field name='%s' type='%s' info='%s'/>\n" % (field[1] , field[0], desc)) | output.write(" <field name='%s' type='%s' info='%s'/>\n" % (field[1] , field[0], desc)) |
except: | except: |
print "Failed to serialize struct %s" % (name) | print("Failed to serialize struct %s" % (name)) |
output.write(" </struct>\n") | output.write(" </struct>\n") |
else: | else: |
output.write("/>\n"); | output.write("/>\n"); |
else : | else : |
output.write(" <typedef name='%s' file='%s' type='%s'" % ( | output.write(" <typedef name='%s' file='%s' type='%s'" % ( |
name, self.modulename_file(id.header), id.info)) | name, self.modulename_file(id.header), id.info)) |
try: |
try: |
desc = id.extra | desc = id.extra |
if desc != None and desc != "": | if desc != None and desc != "": |
output.write(">\n <info>%s</info>\n" % (escape(desc))) | output.write(">\n <info>%s</info>\n" % (escape(desc))) |
output.write(" </typedef>\n") | output.write(" </typedef>\n") |
else: | else: |
output.write("/>\n") | output.write("/>\n") |
except: | except: |
output.write("/>\n") | output.write("/>\n") |
|
|
def serialize_variable(self, output, name): |
def serialize_variable(self, output, name): |
id = self.idx.variables[name] |
id = self.idx.variables[name] |
if id.info != None: | if id.info != None: |
output.write(" <variable name='%s' file='%s' type='%s'/>\n" % ( | output.write(" <variable name='%s' file='%s' type='%s'/>\n" % ( |
name, self.modulename_file(id.header), id.info)) | name, self.modulename_file(id.header), id.info)) |
else: | else: |
output.write(" <variable name='%s' file='%s'/>\n" % ( | output.write(" <variable name='%s' file='%s'/>\n" % ( |
name, self.modulename_file(id.header))) | name, self.modulename_file(id.header))) |
|
|
def serialize_function(self, output, name): |
def serialize_function(self, output, name): |
id = self.idx.functions[name] |
id = self.idx.functions[name] |
if name == debugsym: | if name == debugsym: |
print "=>", id | print("=>", id) |
|
|
output.write(" <%s name='%s' file='%s' module='%s'>\n" % (id.type, |
output.write(" <%s name='%s' file='%s' module='%s'>\n" % (id.type, |
name, self.modulename_file(id.header), | name, self.modulename_file(id.header), |
self.modulename_file(id.module))) | self.modulename_file(id.module))) |
# | # |
# Processing of conditionals modified by Bill 1/1/05 | # Processing of conditionals modified by Bill 1/1/05 |
# | # |
if id.conditionals != None: | if id.conditionals != None: |
apstr = "" | apstr = "" |
for cond in id.conditionals: | for cond in id.conditionals: |
if apstr != "": | if apstr != "": |
apstr = apstr + " && " | apstr = apstr + " && " |
apstr = apstr + cond | apstr = apstr + cond |
output.write(" <cond>%s</cond>\n"% (apstr)); | output.write(" <cond>%s</cond>\n"% (apstr)); |
try: | try: |
(ret, params, desc) = id.info | (ret, params, desc) = id.info |
if (desc == None or desc == '') and \ | if (desc == None or desc == '') and \ |
name[0:9] != "xmlThrDef" and name != "xmlDllMain": | name[0:9] != "xmlThrDef" and name != "xmlDllMain": |
print "%s %s from %s has no description" % (id.type, name, | print("%s %s from %s has no description" % (id.type, name, |
self.modulename_file(id.module)) | self.modulename_file(id.module))) |
|
|
output.write(" <info>%s</info>\n" % (escape(desc))) | output.write(" <info>%s</info>\n" % (escape(desc))) |
self.indexString(name, desc) | self.indexString(name, desc) |
if ret[0] != None: | if ret[0] != None: |
if ret[0] == "void": | if ret[0] == "void": |
output.write(" <return type='void'/>\n") | output.write(" <return type='void'/>\n") |
else: | else: |
output.write(" <return type='%s' info='%s'/>\n" % ( | output.write(" <return type='%s' info='%s'/>\n" % ( |
ret[0], escape(ret[1]))) | ret[0], escape(ret[1]))) |
self.indexString(name, ret[1]) | self.indexString(name, ret[1]) |
for param in params: | for param in params: |
if param[0] == 'void': | if param[0] == 'void': |
continue | continue |
if param[2] == None: | if param[2] == None: |
output.write(" <arg name='%s' type='%s' info=''/>\n" % (param[1], param[0])) | output.write(" <arg name='%s' type='%s' info=''/>\n" % (param[1], param[0])) |
else: | else: |
output.write(" <arg name='%s' type='%s' info='%s'/>\n" % (param[1], param[0], escape(param[2]))) | output.write(" <arg name='%s' type='%s' info='%s'/>\n" % (param[1], param[0], escape(param[2]))) |
self.indexString(name, param[2]) | self.indexString(name, param[2]) |
except: | except: |
print "Failed to save function %s info: " % name, `id.info` | print("Failed to save function %s info: " % name, repr(id.info)) |
output.write(" </%s>\n" % (id.type)) |
output.write(" </%s>\n" % (id.type)) |
|
|
def serialize_exports(self, output, file): |
def serialize_exports(self, output, file): |
module = self.modulename_file(file) |
module = self.modulename_file(file) |
output.write(" <file name='%s'>\n" % (module)) | output.write(" <file name='%s'>\n" % (module)) |
dict = self.headers[file] | dict = self.headers[file] |
if dict.info != None: | if dict.info != None: |
for data in ('Summary', 'Description', 'Author'): | for data in ('Summary', 'Description', 'Author'): |
try: | try: |
output.write(" <%s>%s</%s>\n" % ( | output.write(" <%s>%s</%s>\n" % ( |
string.lower(data), | data.lower(), |
escape(dict.info[data]), | escape(dict.info[data]), |
string.lower(data))) | data.lower())) |
except: | except: |
print "Header %s lacks a %s description" % (module, data) | print("Header %s lacks a %s description" % (module, data)) |
if dict.info.has_key('Description'): | if 'Description' in dict.info: |
desc = dict.info['Description'] | desc = dict.info['Description'] |
if string.find(desc, "DEPRECATED") != -1: | if desc.find("DEPRECATED") != -1: |
output.write(" <deprecated/>\n") | output.write(" <deprecated/>\n") |
|
|
ids = dict.macros.keys() | ids = list(dict.macros.keys()) |
ids.sort() | ids.sort() |
for id in uniq(ids): | for id in uniq(ids): |
# Macros are sometime used to masquerade other types. | # Macros are sometime used to masquerade other types. |
if dict.functions.has_key(id): | if id in dict.functions: |
continue | continue |
if dict.variables.has_key(id): | if id in dict.variables: |
continue | continue |
if dict.typedefs.has_key(id): | if id in dict.typedefs: |
continue | continue |
if dict.structs.has_key(id): | if id in dict.structs: |
continue | continue |
if dict.enums.has_key(id): | if id in dict.enums: |
continue | continue |
output.write(" <exports symbol='%s' type='macro'/>\n" % (id)) | output.write(" <exports symbol='%s' type='macro'/>\n" % (id)) |
ids = dict.enums.keys() | ids = list(dict.enums.keys()) |
ids.sort() | ids.sort() |
for id in uniq(ids): | for id in uniq(ids): |
output.write(" <exports symbol='%s' type='enum'/>\n" % (id)) | output.write(" <exports symbol='%s' type='enum'/>\n" % (id)) |
ids = dict.typedefs.keys() | ids = list(dict.typedefs.keys()) |
ids.sort() | ids.sort() |
for id in uniq(ids): | for id in uniq(ids): |
output.write(" <exports symbol='%s' type='typedef'/>\n" % (id)) | output.write(" <exports symbol='%s' type='typedef'/>\n" % (id)) |
ids = dict.structs.keys() | ids = list(dict.structs.keys()) |
ids.sort() | ids.sort() |
for id in uniq(ids): | for id in uniq(ids): |
output.write(" <exports symbol='%s' type='struct'/>\n" % (id)) | output.write(" <exports symbol='%s' type='struct'/>\n" % (id)) |
ids = dict.variables.keys() | ids = list(dict.variables.keys()) |
ids.sort() | ids.sort() |
for id in uniq(ids): | for id in uniq(ids): |
output.write(" <exports symbol='%s' type='variable'/>\n" % (id)) | output.write(" <exports symbol='%s' type='variable'/>\n" % (id)) |
ids = dict.functions.keys() | ids = list(dict.functions.keys()) |
ids.sort() | ids.sort() |
for id in uniq(ids): | for id in uniq(ids): |
output.write(" <exports symbol='%s' type='function'/>\n" % (id)) | output.write(" <exports symbol='%s' type='function'/>\n" % (id)) |
output.write(" </file>\n") | output.write(" </file>\n") |
|
|
def serialize_xrefs_files(self, output): |
def serialize_xrefs_files(self, output): |
headers = self.headers.keys() | headers = list(self.headers.keys()) |
headers.sort() |
headers.sort() |
for file in headers: |
for file in headers: |
module = self.modulename_file(file) | module = self.modulename_file(file) |
output.write(" <file name='%s'>\n" % (module)) | output.write(" <file name='%s'>\n" % (module)) |
dict = self.headers[file] | dict = self.headers[file] |
ids = uniq(dict.functions.keys() + dict.variables.keys() + \ | ids = uniq(list(dict.functions.keys()) + list(dict.variables.keys()) + \ |
dict.macros.keys() + dict.typedefs.keys() + \ | list(dict.macros.keys()) + list(dict.typedefs.keys()) + \ |
dict.structs.keys() + dict.enums.keys()) | list(dict.structs.keys()) + list(dict.enums.keys())) |
ids.sort() | ids.sort() |
for id in ids: | for id in ids: |
output.write(" <ref name='%s'/>\n" % (id)) | output.write(" <ref name='%s'/>\n" % (id)) |
output.write(" </file>\n") | output.write(" </file>\n") |
pass |
pass |
|
|
def serialize_xrefs_functions(self, output): |
def serialize_xrefs_functions(self, output): |
funcs = {} |
funcs = {} |
for name in self.idx.functions.keys(): | for name in list(self.idx.functions.keys()): |
id = self.idx.functions[name] | id = self.idx.functions[name] |
try: | try: |
(ret, params, desc) = id.info | (ret, params, desc) = id.info |
for param in params: | for param in params: |
if param[0] == 'void': | if param[0] == 'void': |
continue | continue |
if funcs.has_key(param[0]): | if param[0] in funcs: |
funcs[param[0]].append(name) | funcs[param[0]].append(name) |
else: | else: |
funcs[param[0]] = [name] | funcs[param[0]] = [name] |
except: | except: |
pass | pass |
typ = funcs.keys() | typ = list(funcs.keys()) |
typ.sort() | typ.sort() |
for type in typ: | for type in typ: |
if type == '' or type == 'void' or type == "int" or \ | if type == '' or type == 'void' or type == "int" or \ |
type == "char *" or type == "const char *" : | type == "char *" or type == "const char *" : |
continue | continue |
output.write(" <type name='%s'>\n" % (type)) | output.write(" <type name='%s'>\n" % (type)) |
ids = funcs[type] | ids = funcs[type] |
ids.sort() | ids.sort() |
pid = '' # not sure why we have dups, but get rid of them! | pid = '' # not sure why we have dups, but get rid of them! |
for id in ids: | for id in ids: |
if id != pid: | if id != pid: |
output.write(" <ref name='%s'/>\n" % (id)) | output.write(" <ref name='%s'/>\n" % (id)) |
pid = id | pid = id |
output.write(" </type>\n") | output.write(" </type>\n") |
|
|
def serialize_xrefs_constructors(self, output): |
def serialize_xrefs_constructors(self, output): |
funcs = {} |
funcs = {} |
for name in self.idx.functions.keys(): | for name in list(self.idx.functions.keys()): |
id = self.idx.functions[name] | id = self.idx.functions[name] |
try: | try: |
(ret, params, desc) = id.info | (ret, params, desc) = id.info |
if ret[0] == "void": | if ret[0] == "void": |
continue | continue |
if funcs.has_key(ret[0]): | if ret[0] in funcs: |
funcs[ret[0]].append(name) | funcs[ret[0]].append(name) |
else: | else: |
funcs[ret[0]] = [name] | funcs[ret[0]] = [name] |
except: | except: |
pass | pass |
typ = funcs.keys() | typ = list(funcs.keys()) |
typ.sort() | typ.sort() |
for type in typ: | for type in typ: |
if type == '' or type == 'void' or type == "int" or \ | if type == '' or type == 'void' or type == "int" or \ |
type == "char *" or type == "const char *" : | type == "char *" or type == "const char *" : |
continue | continue |
output.write(" <type name='%s'>\n" % (type)) | output.write(" <type name='%s'>\n" % (type)) |
ids = funcs[type] | ids = funcs[type] |
ids.sort() | ids.sort() |
for id in ids: | for id in ids: |
output.write(" <ref name='%s'/>\n" % (id)) | output.write(" <ref name='%s'/>\n" % (id)) |
output.write(" </type>\n") | output.write(" </type>\n") |
|
|
def serialize_xrefs_alpha(self, output): |
def serialize_xrefs_alpha(self, output): |
letter = None | letter = None |
ids = self.idx.identifiers.keys() | ids = list(self.idx.identifiers.keys()) |
ids.sort() | ids.sort() |
for id in ids: | for id in ids: |
if id[0] != letter: | if id[0] != letter: |
if letter != None: | if letter != None: |
output.write(" </letter>\n") | output.write(" </letter>\n") |
letter = id[0] | letter = id[0] |
output.write(" <letter name='%s'>\n" % (letter)) | output.write(" <letter name='%s'>\n" % (letter)) |
output.write(" <ref name='%s'/>\n" % (id)) | output.write(" <ref name='%s'/>\n" % (id)) |
if letter != None: | if letter != None: |
output.write(" </letter>\n") | output.write(" </letter>\n") |
|
|
def serialize_xrefs_references(self, output): |
def serialize_xrefs_references(self, output): |
typ = self.idx.identifiers.keys() | typ = list(self.idx.identifiers.keys()) |
typ.sort() | typ.sort() |
for id in typ: | for id in typ: |
idf = self.idx.identifiers[id] | idf = self.idx.identifiers[id] |
module = idf.header | module = idf.header |
output.write(" <reference name='%s' href='%s'/>\n" % (id, | output.write(" <reference name='%s' href='%s'/>\n" % (id, |
'html/' + self.basename + '-' + | 'html/' + self.basename + '-' + |
self.modulename_file(module) + '.html#' + | self.modulename_file(module) + '.html#' + |
id)) | id)) |
|
|
def serialize_xrefs_index(self, output): |
def serialize_xrefs_index(self, output): |
index = self.xref |
index = self.xref |
typ = index.keys() | typ = list(index.keys()) |
typ.sort() | typ.sort() |
letter = None | letter = None |
count = 0 | count = 0 |
chunk = 0 | chunk = 0 |
chunks = [] | chunks = [] |
for id in typ: | for id in typ: |
if len(index[id]) > 30: | if len(index[id]) > 30: |
continue | continue |
if id[0] != letter: | if id[0] != letter: |
if letter == None or count > 200: | if letter == None or count > 200: |
if letter != None: | if letter != None: |
output.write(" </letter>\n") | output.write(" </letter>\n") |
output.write(" </chunk>\n") | output.write(" </chunk>\n") |
count = 0 | count = 0 |
chunks.append(["chunk%s" % (chunk -1), first_letter, letter]) | chunks.append(["chunk%s" % (chunk -1), first_letter, letter]) |
output.write(" <chunk name='chunk%s'>\n" % (chunk)) | output.write(" <chunk name='chunk%s'>\n" % (chunk)) |
first_letter = id[0] | first_letter = id[0] |
chunk = chunk + 1 | chunk = chunk + 1 |
elif letter != None: | elif letter != None: |
output.write(" </letter>\n") | output.write(" </letter>\n") |
letter = id[0] | letter = id[0] |
output.write(" <letter name='%s'>\n" % (letter)) | output.write(" <letter name='%s'>\n" % (letter)) |
output.write(" <word name='%s'>\n" % (id)) | output.write(" <word name='%s'>\n" % (id)) |
tokens = index[id]; | tokens = index[id]; |
tokens.sort() | tokens.sort() |
tok = None | tok = None |
for token in tokens: | for token in tokens: |
if tok == token: | if tok == token: |
continue | continue |
tok = token | tok = token |
output.write(" <ref name='%s'/>\n" % (token)) | output.write(" <ref name='%s'/>\n" % (token)) |
count = count + 1 | count = count + 1 |
output.write(" </word>\n") | output.write(" </word>\n") |
if letter != None: | if letter != None: |
output.write(" </letter>\n") | output.write(" </letter>\n") |
output.write(" </chunk>\n") | output.write(" </chunk>\n") |
if count != 0: | if count != 0: |
chunks.append(["chunk%s" % (chunk -1), first_letter, letter]) | chunks.append(["chunk%s" % (chunk -1), first_letter, letter]) |
output.write(" <chunks>\n") | output.write(" <chunks>\n") |
for ch in chunks: | for ch in chunks: |
output.write(" <chunk name='%s' start='%s' end='%s'/>\n" % ( | output.write(" <chunk name='%s' start='%s' end='%s'/>\n" % ( |
ch[0], ch[1], ch[2])) | ch[0], ch[1], ch[2])) |
output.write(" </chunks>\n") | output.write(" </chunks>\n") |
|
|
def serialize_xrefs(self, output): |
def serialize_xrefs(self, output): |
output.write(" <references>\n") | output.write(" <references>\n") |
self.serialize_xrefs_references(output) | self.serialize_xrefs_references(output) |
output.write(" </references>\n") | output.write(" </references>\n") |
output.write(" <alpha>\n") | output.write(" <alpha>\n") |
self.serialize_xrefs_alpha(output) | self.serialize_xrefs_alpha(output) |
output.write(" </alpha>\n") | output.write(" </alpha>\n") |
output.write(" <constructors>\n") | output.write(" <constructors>\n") |
self.serialize_xrefs_constructors(output) | self.serialize_xrefs_constructors(output) |
output.write(" </constructors>\n") | output.write(" </constructors>\n") |
output.write(" <functions>\n") | output.write(" <functions>\n") |
self.serialize_xrefs_functions(output) | self.serialize_xrefs_functions(output) |
output.write(" </functions>\n") | output.write(" </functions>\n") |
output.write(" <files>\n") | output.write(" <files>\n") |
self.serialize_xrefs_files(output) | self.serialize_xrefs_files(output) |
output.write(" </files>\n") | output.write(" </files>\n") |
output.write(" <index>\n") | output.write(" <index>\n") |
self.serialize_xrefs_index(output) | self.serialize_xrefs_index(output) |
output.write(" </index>\n") | output.write(" </index>\n") |
|
|
def serialize(self): |
def serialize(self): |
filename = "%s-api.xml" % self.name |
filename = "%s-api.xml" % self.name |
print "Saving XML description %s" % (filename) | print("Saving XML description %s" % (filename)) |
output = open(filename, "w") |
output = open(filename, "w") |
output.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n') |
output.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n') |
output.write("<api name='%s'>\n" % self.name) |
output.write("<api name='%s'>\n" % self.name) |
output.write(" <files>\n") |
output.write(" <files>\n") |
headers = self.headers.keys() | headers = list(self.headers.keys()) |
headers.sort() |
headers.sort() |
for file in headers: |
for file in headers: |
self.serialize_exports(output, file) |
self.serialize_exports(output, file) |
output.write(" </files>\n") |
output.write(" </files>\n") |
output.write(" <symbols>\n") |
output.write(" <symbols>\n") |
macros = self.idx.macros.keys() | macros = list(self.idx.macros.keys()) |
macros.sort() |
macros.sort() |
for macro in macros: |
for macro in macros: |
self.serialize_macro(output, macro) |
self.serialize_macro(output, macro) |
enums = self.idx.enums.keys() | enums = list(self.idx.enums.keys()) |
enums.sort() |
enums.sort() |
for enum in enums: |
for enum in enums: |
self.serialize_enum(output, enum) |
self.serialize_enum(output, enum) |
typedefs = self.idx.typedefs.keys() | typedefs = list(self.idx.typedefs.keys()) |
typedefs.sort() |
typedefs.sort() |
for typedef in typedefs: |
for typedef in typedefs: |
self.serialize_typedef(output, typedef) |
self.serialize_typedef(output, typedef) |
variables = self.idx.variables.keys() | variables = list(self.idx.variables.keys()) |
variables.sort() |
variables.sort() |
for variable in variables: |
for variable in variables: |
self.serialize_variable(output, variable) |
self.serialize_variable(output, variable) |
functions = self.idx.functions.keys() | functions = list(self.idx.functions.keys()) |
functions.sort() |
functions.sort() |
for function in functions: |
for function in functions: |
self.serialize_function(output, function) |
self.serialize_function(output, function) |
Line 2092 class docBuilder:
|
Line 2099 class docBuilder:
|
output.close() |
output.close() |
|
|
filename = "%s-refs.xml" % self.name |
filename = "%s-refs.xml" % self.name |
print "Saving XML Cross References %s" % (filename) | print("Saving XML Cross References %s" % (filename)) |
output = open(filename, "w") |
output = open(filename, "w") |
output.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n') |
output.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n') |
output.write("<apirefs name='%s'>\n" % self.name) |
output.write("<apirefs name='%s'>\n" % self.name) |
Line 2104 class docBuilder:
|
Line 2111 class docBuilder:
|
def rebuild(): |
def rebuild(): |
builder = None |
builder = None |
if glob.glob("parser.c") != [] : |
if glob.glob("parser.c") != [] : |
print "Rebuilding API description for libxml2" | print("Rebuilding API description for libxml2") |
builder = docBuilder("libxml2", [".", "."], | builder = docBuilder("libxml2", [".", "."], |
["xmlwin32version.h", "tst.c"]) | ["xmlwin32version.h", "tst.c"]) |
elif glob.glob("../parser.c") != [] : |
elif glob.glob("../parser.c") != [] : |
print "Rebuilding API description for libxml2" | print("Rebuilding API description for libxml2") |
builder = docBuilder("libxml2", ["..", "../include/libxml"], | builder = docBuilder("libxml2", ["..", "../include/libxml"], |
["xmlwin32version.h", "tst.c"]) | ["xmlwin32version.h", "tst.c"]) |
elif glob.glob("../libxslt/transform.c") != [] : |
elif glob.glob("../libxslt/transform.c") != [] : |
print "Rebuilding API description for libxslt" | print("Rebuilding API description for libxslt") |
builder = docBuilder("libxslt", ["../libxslt"], | builder = docBuilder("libxslt", ["../libxslt"], |
["win32config.h", "libxslt.h", "tst.c"]) | ["win32config.h", "libxslt.h", "tst.c"]) |
else: |
else: |
print "rebuild() failed, unable to guess the module" | print("rebuild() failed, unable to guess the module") |
return None | return None |
builder.scan() |
builder.scan() |
builder.analyze() |
builder.analyze() |
builder.serialize() |
builder.serialize() |
if glob.glob("../libexslt/exslt.c") != [] : |
if glob.glob("../libexslt/exslt.c") != [] : |
extra = docBuilder("libexslt", ["../libexslt"], ["libexslt.h"]) |
extra = docBuilder("libexslt", ["../libexslt"], ["libexslt.h"]) |
extra.scan() | extra.scan() |
extra.analyze() | extra.analyze() |
extra.serialize() | extra.serialize() |
return builder |
return builder |
|
|
# |
# |
Line 2141 if __name__ == "__main__":
|
Line 2148 if __name__ == "__main__":
|
debug = 1 |
debug = 1 |
parse(sys.argv[1]) |
parse(sys.argv[1]) |
else: |
else: |
rebuild() | rebuild() |