Blame doc/apibuild.py

Packit Service a31ea6
#!/usr/bin/python -u
Packit Service a31ea6
#
Packit Service a31ea6
# This is the API builder, it parses the C sources and build the
Packit Service a31ea6
# API formal description in XML.
Packit Service a31ea6
#
Packit Service a31ea6
# See Copyright for the status of this software.
Packit Service a31ea6
#
Packit Service a31ea6
# daniel@veillard.com
Packit Service a31ea6
#
Packit Service a31ea6
import os, sys
Packit Service a31ea6
import string
Packit Service a31ea6
import glob
Packit Service a31ea6
Packit Service a31ea6
debug=0
Packit Service a31ea6
#debugsym='ignorableWhitespaceSAXFunc'
Packit Service a31ea6
debugsym=None
Packit Service a31ea6
Packit Service a31ea6
#
Packit Service a31ea6
# C parser analysis code
Packit Service a31ea6
#
Packit Service a31ea6
ignored_files = {
Packit Service a31ea6
  "trio": "too many non standard macros",
Packit Service a31ea6
  "trio.c": "too many non standard macros",
Packit Service a31ea6
  "trionan.c": "too many non standard macros",
Packit Service a31ea6
  "triostr.c": "too many non standard macros",
Packit Service a31ea6
  "acconfig.h": "generated portability layer",
Packit Service a31ea6
  "config.h": "generated portability layer",
Packit Service a31ea6
  "libxml.h": "internal only",
Packit Service a31ea6
  "testOOM.c": "out of memory tester",
Packit Service a31ea6
  "testOOMlib.h": "out of memory tester",
Packit Service a31ea6
  "testOOMlib.c": "out of memory tester",
Packit Service a31ea6
  "rngparser.c": "not yet integrated",
Packit Service a31ea6
  "rngparser.h": "not yet integrated",
Packit Service a31ea6
  "elfgcchack.h": "not a normal header",
Packit Service a31ea6
  "testHTML.c": "test tool",
Packit Service a31ea6
  "testReader.c": "test tool",
Packit Service a31ea6
  "testSchemas.c": "test tool",
Packit Service a31ea6
  "testXPath.c": "test tool",
Packit Service a31ea6
  "testAutomata.c": "test tool",
Packit Service a31ea6
  "testModule.c": "test tool",
Packit Service a31ea6
  "testRegexp.c": "test tool",
Packit Service a31ea6
  "testThreads.c": "test tool",
Packit Service a31ea6
  "testC14N.c": "test tool",
Packit Service a31ea6
  "testRelax.c": "test tool",
Packit Service a31ea6
  "testThreadsWin32.c": "test tool",
Packit Service a31ea6
  "testSAX.c": "test tool",
Packit Service a31ea6
  "testURI.c": "test tool",
Packit Service a31ea6
  "testapi.c": "generated regression tests",
Packit Service a31ea6
  "runtest.c": "regression tests program",
Packit Service a31ea6
  "runsuite.c": "regression tests program",
Packit Service a31ea6
  "tst.c": "not part of the library",
Packit Service a31ea6
  "test.c": "not part of the library",
Packit Service a31ea6
  "testdso.c": "test for dynamid shared libraries",
Packit Service a31ea6
  "testrecurse.c": "test for entities recursions",
Packit Service a31ea6
  "xzlib.h": "Internal API only 2.8.0",
Packit Service a31ea6
  "buf.h": "Internal API only 2.9.0",
Packit Service a31ea6
  "enc.h": "Internal API only 2.9.0",
Packit Service a31ea6
  "/save.h": "Internal API only 2.9.0",
Packit Service a31ea6
  "timsort.h": "Internal header only for xpath.c 2.9.0",
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
ignored_words = {
Packit Service a31ea6
  "WINAPI": (0, "Windows keyword"),
Packit Service a31ea6
  "LIBXML_DLL_IMPORT": (0, "Special macro to flag external keywords"),
Packit Service a31ea6
  "XMLPUBVAR": (0, "Special macro for extern vars for win32"),
Packit Service a31ea6
  "XSLTPUBVAR": (0, "Special macro for extern vars for win32"),
Packit Service a31ea6
  "EXSLTPUBVAR": (0, "Special macro for extern vars for win32"),
Packit Service a31ea6
  "XMLPUBFUN": (0, "Special macro for extern funcs for win32"),
Packit Service a31ea6
  "XSLTPUBFUN": (0, "Special macro for extern funcs for win32"),
Packit Service a31ea6
  "EXSLTPUBFUN": (0, "Special macro for extern funcs for win32"),
Packit Service a31ea6
  "XMLCALL": (0, "Special macro for win32 calls"),
Packit Service a31ea6
  "XSLTCALL": (0, "Special macro for win32 calls"),
Packit Service a31ea6
  "XMLCDECL": (0, "Special macro for win32 calls"),
Packit Service a31ea6
  "EXSLTCALL": (0, "Special macro for win32 calls"),
Packit Service a31ea6
  "__declspec": (3, "Windows keyword"),
Packit Service a31ea6
  "__stdcall": (0, "Windows keyword"),
Packit Service a31ea6
  "ATTRIBUTE_UNUSED": (0, "macro keyword"),
Packit Service a31ea6
  "LIBEXSLT_PUBLIC": (0, "macro keyword"),
Packit Service a31ea6
  "X_IN_Y": (5, "macro function builder"),
Packit Service a31ea6
  "ATTRIBUTE_ALLOC_SIZE": (3, "macro for gcc checking extension"),
Packit Service a31ea6
  "ATTRIBUTE_PRINTF": (5, "macro for gcc printf args checking extension"),
Packit Service a31ea6
  "LIBXML_ATTR_FORMAT": (5, "macro for gcc printf args checking extension"),
Packit Service a31ea6
  "LIBXML_ATTR_ALLOC_SIZE": (3, "macro for gcc checking extension"),
Packit Service a31ea6
  "__XML_EXTERNC": (0, "Special macro added for os400"),
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
def escape(raw):
Packit Service a31ea6
    raw = raw.replace('&', '&')
Packit Service a31ea6
    raw = raw.replace('<', '<')
Packit Service a31ea6
    raw = raw.replace('>', '>')
Packit Service a31ea6
    raw = raw.replace("'", ''')
Packit Service a31ea6
    raw = raw.replace('"', '"')
Packit Service a31ea6
    return raw
Packit Service a31ea6
Packit Service a31ea6
def uniq(items):
Packit Service a31ea6
    d = {}
Packit Service a31ea6
    for item in items:
Packit Service a31ea6
        d[item]=1
Packit Service a31ea6
    return list(d.keys())
Packit Service a31ea6
Packit Service a31ea6
class identifier:
Packit Service a31ea6
    def __init__(self, name, header=None, module=None, type=None, lineno = 0,
Packit Service a31ea6
                 info=None, extra=None, conditionals = None):
Packit Service a31ea6
        self.name = name
Packit Service a31ea6
        self.header = header
Packit Service a31ea6
        self.module = module
Packit Service a31ea6
        self.type = type
Packit Service a31ea6
        self.info = info
Packit Service a31ea6
        self.extra = extra
Packit Service a31ea6
        self.lineno = lineno
Packit Service a31ea6
        self.static = 0
Packit Service a31ea6
        if conditionals == None or len(conditionals) == 0:
Packit Service a31ea6
            self.conditionals = None
Packit Service a31ea6
        else:
Packit Service a31ea6
            self.conditionals = conditionals[:]
Packit Service a31ea6
        if self.name == debugsym:
Packit Service a31ea6
            print("=> define %s : %s" % (debugsym, (module, type, info,
Packit Service a31ea6
                                         extra, conditionals)))
Packit Service a31ea6
Packit Service a31ea6
    def __repr__(self):
Packit Service a31ea6
        r = "%s %s:" % (self.type, self.name)
Packit Service a31ea6
        if self.static:
Packit Service a31ea6
            r = r + " static"
Packit Service a31ea6
        if self.module != None:
Packit Service a31ea6
            r = r + " from %s" % (self.module)
Packit Service a31ea6
        if self.info != None:
Packit Service a31ea6
            r = r + " " +  repr(self.info)
Packit Service a31ea6
        if self.extra != None:
Packit Service a31ea6
            r = r + " " + repr(self.extra)
Packit Service a31ea6
        if self.conditionals != None:
Packit Service a31ea6
            r = r + " " + repr(self.conditionals)
Packit Service a31ea6
        return r
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
    def set_header(self, header):
Packit Service a31ea6
        self.header = header
Packit Service a31ea6
    def set_module(self, module):
Packit Service a31ea6
        self.module = module
Packit Service a31ea6
    def set_type(self, type):
Packit Service a31ea6
        self.type = type
Packit Service a31ea6
    def set_info(self, info):
Packit Service a31ea6
        self.info = info
Packit Service a31ea6
    def set_extra(self, extra):
Packit Service a31ea6
        self.extra = extra
Packit Service a31ea6
    def set_lineno(self, lineno):
Packit Service a31ea6
        self.lineno = lineno
Packit Service a31ea6
    def set_static(self, static):
Packit Service a31ea6
        self.static = static
Packit Service a31ea6
    def set_conditionals(self, conditionals):
Packit Service a31ea6
        if conditionals == None or len(conditionals) == 0:
Packit Service a31ea6
            self.conditionals = None
Packit Service a31ea6
        else:
Packit Service a31ea6
            self.conditionals = conditionals[:]
Packit Service a31ea6
Packit Service a31ea6
    def get_name(self):
Packit Service a31ea6
        return self.name
Packit Service a31ea6
    def get_header(self):
Packit Service a31ea6
        return self.module
Packit Service a31ea6
    def get_module(self):
Packit Service a31ea6
        return self.module
Packit Service a31ea6
    def get_type(self):
Packit Service a31ea6
        return self.type
Packit Service a31ea6
    def get_info(self):
Packit Service a31ea6
        return self.info
Packit Service a31ea6
    def get_lineno(self):
Packit Service a31ea6
        return self.lineno
Packit Service a31ea6
    def get_extra(self):
Packit Service a31ea6
        return self.extra
Packit Service a31ea6
    def get_static(self):
Packit Service a31ea6
        return self.static
Packit Service a31ea6
    def get_conditionals(self):
Packit Service a31ea6
        return self.conditionals
Packit Service a31ea6
Packit Service a31ea6
    def update(self, header, module, type = None, info = None, extra=None,
Packit Service a31ea6
               conditionals=None):
Packit Service a31ea6
        if self.name == debugsym:
Packit Service a31ea6
            print("=> update %s : %s" % (debugsym, (module, type, info,
Packit Service a31ea6
                                         extra, conditionals)))
Packit Service a31ea6
        if header != None and self.header == None:
Packit Service a31ea6
            self.set_header(module)
Packit Service a31ea6
        if module != None and (self.module == None or self.header == self.module):
Packit Service a31ea6
            self.set_module(module)
Packit Service a31ea6
        if type != None and self.type == None:
Packit Service a31ea6
            self.set_type(type)
Packit Service a31ea6
        if info != None:
Packit Service a31ea6
            self.set_info(info)
Packit Service a31ea6
        if extra != None:
Packit Service a31ea6
            self.set_extra(extra)
Packit Service a31ea6
        if conditionals != None:
Packit Service a31ea6
            self.set_conditionals(conditionals)
Packit Service a31ea6
Packit Service a31ea6
class index:
Packit Service a31ea6
    def __init__(self, name = "noname"):
Packit Service a31ea6
        self.name = name
Packit Service a31ea6
        self.identifiers = {}
Packit Service a31ea6
        self.functions = {}
Packit Service a31ea6
        self.variables = {}
Packit Service a31ea6
        self.includes = {}
Packit Service a31ea6
        self.structs = {}
Packit Service a31ea6
        self.enums = {}
Packit Service a31ea6
        self.typedefs = {}
Packit Service a31ea6
        self.macros = {}
Packit Service a31ea6
        self.references = {}
Packit Service a31ea6
        self.info = {}
Packit Service a31ea6
Packit Service a31ea6
    def add_ref(self, name, header, module, static, type, lineno, info=None, extra=None, conditionals = None):
Packit Service a31ea6
        if name[0:2] == '__':
Packit Service a31ea6
            return None
Packit Service a31ea6
        d = None
Packit Service a31ea6
        try:
Packit Service a31ea6
           d = self.identifiers[name]
Packit Service a31ea6
           d.update(header, module, type, lineno, info, extra, conditionals)
Packit Service a31ea6
        except:
Packit Service a31ea6
           d = identifier(name, header, module, type, lineno, info, extra, conditionals)
Packit Service a31ea6
           self.identifiers[name] = d
Packit Service a31ea6
Packit Service a31ea6
        if d != None and static == 1:
Packit Service a31ea6
            d.set_static(1)
Packit Service a31ea6
Packit Service a31ea6
        if d != None and name != None and type != None:
Packit Service a31ea6
            self.references[name] = d
Packit Service a31ea6
Packit Service a31ea6
        if name == debugsym:
Packit Service a31ea6
            print("New ref: %s" % (d))
Packit Service a31ea6
Packit Service a31ea6
        return d
Packit Service a31ea6
Packit Service a31ea6
    def add(self, name, header, module, static, type, lineno, info=None, extra=None, conditionals = None):
Packit Service a31ea6
        if name[0:2] == '__':
Packit Service a31ea6
            return None
Packit Service a31ea6
        d = None
Packit Service a31ea6
        try:
Packit Service a31ea6
           d = self.identifiers[name]
Packit Service a31ea6
           d.update(header, module, type, lineno, info, extra, conditionals)
Packit Service a31ea6
        except:
Packit Service a31ea6
           d = identifier(name, header, module, type, lineno, info, extra, conditionals)
Packit Service a31ea6
           self.identifiers[name] = d
Packit Service a31ea6
Packit Service a31ea6
        if d != None and static == 1:
Packit Service a31ea6
            d.set_static(1)
Packit Service a31ea6
Packit Service a31ea6
        if d != None and name != None and type != None:
Packit Service a31ea6
            if type == "function":
Packit Service a31ea6
                self.functions[name] = d
Packit Service a31ea6
            elif type == "functype":
Packit Service a31ea6
                self.functions[name] = d
Packit Service a31ea6
            elif type == "variable":
Packit Service a31ea6
                self.variables[name] = d
Packit Service a31ea6
            elif type == "include":
Packit Service a31ea6
                self.includes[name] = d
Packit Service a31ea6
            elif type == "struct":
Packit Service a31ea6
                self.structs[name] = d
Packit Service a31ea6
            elif type == "enum":
Packit Service a31ea6
                self.enums[name] = d
Packit Service a31ea6
            elif type == "typedef":
Packit Service a31ea6
                self.typedefs[name] = d
Packit Service a31ea6
            elif type == "macro":
Packit Service a31ea6
                self.macros[name] = d
Packit Service a31ea6
            else:
Packit Service a31ea6
                print("Unable to register type ", type)
Packit Service a31ea6
Packit Service a31ea6
        if name == debugsym:
Packit Service a31ea6
            print("New symbol: %s" % (d))
Packit Service a31ea6
Packit Service a31ea6
        return d
Packit Service a31ea6
Packit Service a31ea6
    def merge(self, idx):
Packit Service a31ea6
        for id in list(idx.functions.keys()):
Packit Service a31ea6
              #
Packit Service a31ea6
              # macro might be used to override functions or variables
Packit Service a31ea6
              # definitions
Packit Service a31ea6
              #
Packit Service a31ea6
             if id in self.macros:
Packit Service a31ea6
                 del self.macros[id]
Packit Service a31ea6
             if id in self.functions:
Packit Service a31ea6
                 print("function %s from %s redeclared in %s" % (
Packit Service a31ea6
                    id, self.functions[id].header, idx.functions[id].header))
Packit Service a31ea6
             else:
Packit Service a31ea6
                 self.functions[id] = idx.functions[id]
Packit Service a31ea6
                 self.identifiers[id] = idx.functions[id]
Packit Service a31ea6
        for id in list(idx.variables.keys()):
Packit Service a31ea6
              #
Packit Service a31ea6
              # macro might be used to override functions or variables
Packit Service a31ea6
              # definitions
Packit Service a31ea6
              #
Packit Service a31ea6
             if id in self.macros:
Packit Service a31ea6
                 del self.macros[id]
Packit Service a31ea6
             if id in self.variables:
Packit Service a31ea6
                 print("variable %s from %s redeclared in %s" % (
Packit Service a31ea6
                    id, self.variables[id].header, idx.variables[id].header))
Packit Service a31ea6
             else:
Packit Service a31ea6
                 self.variables[id] = idx.variables[id]
Packit Service a31ea6
                 self.identifiers[id] = idx.variables[id]
Packit Service a31ea6
        for id in list(idx.structs.keys()):
Packit Service a31ea6
             if id in self.structs:
Packit Service a31ea6
                 print("struct %s from %s redeclared in %s" % (
Packit Service a31ea6
                    id, self.structs[id].header, idx.structs[id].header))
Packit Service a31ea6
             else:
Packit Service a31ea6
                 self.structs[id] = idx.structs[id]
Packit Service a31ea6
                 self.identifiers[id] = idx.structs[id]
Packit Service a31ea6
        for id in list(idx.typedefs.keys()):
Packit Service a31ea6
             if id in self.typedefs:
Packit Service a31ea6
                 print("typedef %s from %s redeclared in %s" % (
Packit Service a31ea6
                    id, self.typedefs[id].header, idx.typedefs[id].header))
Packit Service a31ea6
             else:
Packit Service a31ea6
                 self.typedefs[id] = idx.typedefs[id]
Packit Service a31ea6
                 self.identifiers[id] = idx.typedefs[id]
Packit Service a31ea6
        for id in list(idx.macros.keys()):
Packit Service a31ea6
              #
Packit Service a31ea6
              # macro might be used to override functions or variables
Packit Service a31ea6
              # definitions
Packit Service a31ea6
              #
Packit Service a31ea6
             if id in self.variables:
Packit Service a31ea6
                 continue
Packit Service a31ea6
             if id in self.functions:
Packit Service a31ea6
                 continue
Packit Service a31ea6
             if id in self.enums:
Packit Service a31ea6
                 continue
Packit Service a31ea6
             if id in self.macros:
Packit Service a31ea6
                 print("macro %s from %s redeclared in %s" % (
Packit Service a31ea6
                    id, self.macros[id].header, idx.macros[id].header))
Packit Service a31ea6
             else:
Packit Service a31ea6
                 self.macros[id] = idx.macros[id]
Packit Service a31ea6
                 self.identifiers[id] = idx.macros[id]
Packit Service a31ea6
        for id in list(idx.enums.keys()):
Packit Service a31ea6
             if id in self.enums:
Packit Service a31ea6
                 print("enum %s from %s redeclared in %s" % (
Packit Service a31ea6
                    id, self.enums[id].header, idx.enums[id].header))
Packit Service a31ea6
             else:
Packit Service a31ea6
                 self.enums[id] = idx.enums[id]
Packit Service a31ea6
                 self.identifiers[id] = idx.enums[id]
Packit Service a31ea6
Packit Service a31ea6
    def merge_public(self, idx):
Packit Service a31ea6
        for id in list(idx.functions.keys()):
Packit Service a31ea6
             if id in self.functions:
Packit Service a31ea6
                 # check that function condition agrees with header
Packit Service a31ea6
                 if idx.functions[id].conditionals != \
Packit Service a31ea6
                    self.functions[id].conditionals:
Packit Service a31ea6
                     print("Header condition differs from Function for %s:" \
Packit Service a31ea6
                        % id)
Packit Service a31ea6
                     print("  H: %s" % self.functions[id].conditionals)
Packit Service a31ea6
                     print("  C: %s" % idx.functions[id].conditionals)
Packit Service a31ea6
                 up = idx.functions[id]
Packit Service a31ea6
                 self.functions[id].update(None, up.module, up.type, up.info, up.extra)
Packit Service a31ea6
         #     else:
Packit Service a31ea6
         #         print "Function %s from %s is not declared in headers" % (
Packit Service a31ea6
         #                id, idx.functions[id].module)
Packit Service a31ea6
         # TODO: do the same for variables.
Packit Service a31ea6
Packit Service a31ea6
    def analyze_dict(self, type, dict):
Packit Service a31ea6
        count = 0
Packit Service a31ea6
        public = 0
Packit Service a31ea6
        for name in list(dict.keys()):
Packit Service a31ea6
            id = dict[name]
Packit Service a31ea6
            count = count + 1
Packit Service a31ea6
            if id.static == 0:
Packit Service a31ea6
                public = public + 1
Packit Service a31ea6
        if count != public:
Packit Service a31ea6
            print("  %d %s , %d public" % (count, type, public))
Packit Service a31ea6
        elif count != 0:
Packit Service a31ea6
            print("  %d public %s" % (count, type))
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
    def analyze(self):
Packit Service a31ea6
        self.analyze_dict("functions", self.functions)
Packit Service a31ea6
        self.analyze_dict("variables", self.variables)
Packit Service a31ea6
        self.analyze_dict("structs", self.structs)
Packit Service a31ea6
        self.analyze_dict("typedefs", self.typedefs)
Packit Service a31ea6
        self.analyze_dict("macros", self.macros)
Packit Service a31ea6
Packit Service a31ea6
class CLexer:
Packit Service a31ea6
    """A lexer for the C language, tokenize the input by reading and
Packit Service a31ea6
       analyzing it line by line"""
Packit Service a31ea6
    def __init__(self, input):
Packit Service a31ea6
        self.input = input
Packit Service a31ea6
        self.tokens = []
Packit Service a31ea6
        self.line = ""
Packit Service a31ea6
        self.lineno = 0
Packit Service a31ea6
Packit Service a31ea6
    def getline(self):
Packit Service a31ea6
        line = ''
Packit Service a31ea6
        while line == '':
Packit Service a31ea6
            line = self.input.readline()
Packit Service a31ea6
            if not line:
Packit Service a31ea6
                return None
Packit Service a31ea6
            self.lineno = self.lineno + 1
Packit Service a31ea6
            line = line.lstrip()
Packit Service a31ea6
            line = line.rstrip()
Packit Service a31ea6
            if line == '':
Packit Service a31ea6
                continue
Packit Service a31ea6
            while line[-1] == '\\':
Packit Service a31ea6
                line = line[:-1]
Packit Service a31ea6
                n = self.input.readline()
Packit Service a31ea6
                self.lineno = self.lineno + 1
Packit Service a31ea6
                n = n.lstrip()
Packit Service a31ea6
                n = n.rstrip()
Packit Service a31ea6
                if not n:
Packit Service a31ea6
                    break
Packit Service a31ea6
                else:
Packit Service a31ea6
                    line = line + n
Packit Service a31ea6
        return line
Packit Service a31ea6
Packit Service a31ea6
    def getlineno(self):
Packit Service a31ea6
        return self.lineno
Packit Service a31ea6
Packit Service a31ea6
    def push(self, token):
Packit Service a31ea6
        self.tokens.insert(0, token);
Packit Service a31ea6
Packit Service a31ea6
    def debug(self):
Packit Service a31ea6
        print("Last token: ", self.last)
Packit Service a31ea6
        print("Token queue: ", self.tokens)
Packit Service a31ea6
        print("Line %d end: " % (self.lineno), self.line)
Packit Service a31ea6
Packit Service a31ea6
    def token(self):
Packit Service a31ea6
        while self.tokens == []:
Packit Service a31ea6
            if self.line == "":
Packit Service a31ea6
                line = self.getline()
Packit Service a31ea6
            else:
Packit Service a31ea6
                line = self.line
Packit Service a31ea6
                self.line = ""
Packit Service a31ea6
            if line == None:
Packit Service a31ea6
                return None
Packit Service a31ea6
Packit Service a31ea6
            if line[0] == '#':
Packit Service a31ea6
                self.tokens = list(map((lambda x: ('preproc', x)),
Packit Service a31ea6
                                  line.split()))
Packit Service a31ea6
                break;
Packit Service a31ea6
            l = len(line)
Packit Service a31ea6
            if line[0] == '"' or line[0] == "'":
Packit Service a31ea6
                end = line[0]
Packit Service a31ea6
                line = line[1:]
Packit Service a31ea6
                found = 0
Packit Service a31ea6
                tok = ""
Packit Service a31ea6
                while found == 0:
Packit Service a31ea6
                    i = 0
Packit Service a31ea6
                    l = len(line)
Packit Service a31ea6
                    while i < l:
Packit Service a31ea6
                        if line[i] == end:
Packit Service a31ea6
                            self.line = line[i+1:]
Packit Service a31ea6
                            line = line[:i]
Packit Service a31ea6
                            l = i
Packit Service a31ea6
                            found = 1
Packit Service a31ea6
                            break
Packit Service a31ea6
                        if line[i] == '\\':
Packit Service a31ea6
                            i = i + 1
Packit Service a31ea6
                        i = i + 1
Packit Service a31ea6
                    tok = tok + line
Packit Service a31ea6
                    if found == 0:
Packit Service a31ea6
                        line = self.getline()
Packit Service a31ea6
                        if line == None:
Packit Service a31ea6
                            return None
Packit Service a31ea6
                self.last = ('string', tok)
Packit Service a31ea6
                return self.last
Packit Service a31ea6
Packit Service a31ea6
            if l >= 2 and line[0] == '/' and line[1] == '*':
Packit Service a31ea6
                line = line[2:]
Packit Service a31ea6
                found = 0
Packit Service a31ea6
                tok = ""
Packit Service a31ea6
                while found == 0:
Packit Service a31ea6
                    i = 0
Packit Service a31ea6
                    l = len(line)
Packit Service a31ea6
                    while i < l:
Packit Service a31ea6
                        if line[i] == '*' and i+1 < l and line[i+1] == '/':
Packit Service a31ea6
                            self.line = line[i+2:]
Packit Service a31ea6
                            line = line[:i-1]
Packit Service a31ea6
                            l = i
Packit Service a31ea6
                            found = 1
Packit Service a31ea6
                            break
Packit Service a31ea6
                        i = i + 1
Packit Service a31ea6
                    if tok != "":
Packit Service a31ea6
                        tok = tok + "\n"
Packit Service a31ea6
                    tok = tok + line
Packit Service a31ea6
                    if found == 0:
Packit Service a31ea6
                        line = self.getline()
Packit Service a31ea6
                        if line == None:
Packit Service a31ea6
                            return None
Packit Service a31ea6
                self.last = ('comment', tok)
Packit Service a31ea6
                return self.last
Packit Service a31ea6
            if l >= 2 and line[0] == '/' and line[1] == '/':
Packit Service a31ea6
                line = line[2:]
Packit Service a31ea6
                self.last = ('comment', line)
Packit Service a31ea6
                return self.last
Packit Service a31ea6
            i = 0
Packit Service a31ea6
            while i < l:
Packit Service a31ea6
                if line[i] == '/' and i+1 < l and line[i+1] == '/':
Packit Service a31ea6
                    self.line = line[i:]
Packit Service a31ea6
                    line = line[:i]
Packit Service a31ea6
                    break
Packit Service a31ea6
                if line[i] == '/' and i+1 < l and line[i+1] == '*':
Packit Service a31ea6
                    self.line = line[i:]
Packit Service a31ea6
                    line = line[:i]
Packit Service a31ea6
                    break
Packit Service a31ea6
                if line[i] == '"' or line[i] == "'":
Packit Service a31ea6
                    self.line = line[i:]
Packit Service a31ea6
                    line = line[:i]
Packit Service a31ea6
                    break
Packit Service a31ea6
                i = i + 1
Packit Service a31ea6
            l = len(line)
Packit Service a31ea6
            i = 0
Packit Service a31ea6
            while i < l:
Packit Service a31ea6
                if line[i] == ' ' or line[i] == '\t':
Packit Service a31ea6
                    i = i + 1
Packit Service a31ea6
                    continue
Packit Service a31ea6
                o = ord(line[i])
Packit Service a31ea6
                if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \
Packit Service a31ea6
                   (o >= 48 and o <= 57):
Packit Service a31ea6
                    s = i
Packit Service a31ea6
                    while i < l:
Packit Service a31ea6
                        o = ord(line[i])
Packit Service a31ea6
                        if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \
Packit Service a31ea6
                           (o >= 48 and o <= 57) or \
Packit Service a31ea6
			   (" \t(){}:;,+-*/%&!|[]=><".find(line[i])) == -1:
Packit Service a31ea6
                            i = i + 1
Packit Service a31ea6
                        else:
Packit Service a31ea6
                            break
Packit Service a31ea6
                    self.tokens.append(('name', line[s:i]))
Packit Service a31ea6
                    continue
Packit Service a31ea6
                if "(){}:;,[]".find(line[i]) != -1:
Packit Service a31ea6
#                 if line[i] == '(' or line[i] == ')' or line[i] == '{' or \
Packit Service a31ea6
#                    line[i] == '}' or line[i] == ':' or line[i] == ';' or \
Packit Service a31ea6
#                    line[i] == ',' or line[i] == '[' or line[i] == ']':
Packit Service a31ea6
                    self.tokens.append(('sep', line[i]))
Packit Service a31ea6
                    i = i + 1
Packit Service a31ea6
                    continue
Packit Service a31ea6
                if "+-*><=/%&!|.".find(line[i]) != -1:
Packit Service a31ea6
#                 if line[i] == '+' or line[i] == '-' or line[i] == '*' or \
Packit Service a31ea6
#                    line[i] == '>' or line[i] == '<' or line[i] == '=' or \
Packit Service a31ea6
#                    line[i] == '/' or line[i] == '%' or line[i] == '&' or \
Packit Service a31ea6
#                    line[i] == '!' or line[i] == '|' or line[i] == '.':
Packit Service a31ea6
                    if line[i] == '.' and  i + 2 < l and \
Packit Service a31ea6
                       line[i+1] == '.' and line[i+2] == '.':
Packit Service a31ea6
                        self.tokens.append(('name', '...'))
Packit Service a31ea6
                        i = i + 3
Packit Service a31ea6
                        continue
Packit Service a31ea6
Packit Service a31ea6
                    j = i + 1
Packit Service a31ea6
                    if j < l and (
Packit Service a31ea6
                       "+-*><=/%&!|".find(line[j]) != -1):
Packit Service a31ea6
#                        line[j] == '+' or line[j] == '-' or line[j] == '*' or \
Packit Service a31ea6
#                        line[j] == '>' or line[j] == '<' or line[j] == '=' or \
Packit Service a31ea6
#                        line[j] == '/' or line[j] == '%' or line[j] == '&' or \
Packit Service a31ea6
#                        line[j] == '!' or line[j] == '|'):
Packit Service a31ea6
                        self.tokens.append(('op', line[i:j+1]))
Packit Service a31ea6
                        i = j + 1
Packit Service a31ea6
                    else:
Packit Service a31ea6
                        self.tokens.append(('op', line[i]))
Packit Service a31ea6
                        i = i + 1
Packit Service a31ea6
                    continue
Packit Service a31ea6
                s = i
Packit Service a31ea6
                while i < l:
Packit Service a31ea6
                    o = ord(line[i])
Packit Service a31ea6
                    if (o >= 97 and o <= 122) or (o >= 65 and o <= 90) or \
Packit Service a31ea6
                       (o >= 48 and o <= 57) or (
Packit Service a31ea6
                        " \t(){}:;,+-*/%&!|[]=><".find(line[i]) == -1):
Packit Service a31ea6
#                         line[i] != ' ' and line[i] != '\t' and
Packit Service a31ea6
#                         line[i] != '(' and line[i] != ')' and
Packit Service a31ea6
#                         line[i] != '{'  and line[i] != '}' and
Packit Service a31ea6
#                         line[i] != ':' and line[i] != ';' and
Packit Service a31ea6
#                         line[i] != ',' and line[i] != '+' and
Packit Service a31ea6
#                         line[i] != '-' and line[i] != '*' and
Packit Service a31ea6
#                         line[i] != '/' and line[i] != '%' and
Packit Service a31ea6
#                         line[i] != '&' and line[i] != '!' and
Packit Service a31ea6
#                         line[i] != '|' and line[i] != '[' and
Packit Service a31ea6
#                         line[i] != ']' and line[i] != '=' and
Packit Service a31ea6
#                         line[i] != '*' and line[i] != '>' and
Packit Service a31ea6
#                         line[i] != '<'):
Packit Service a31ea6
                        i = i + 1
Packit Service a31ea6
                    else:
Packit Service a31ea6
                        break
Packit Service a31ea6
                self.tokens.append(('name', line[s:i]))
Packit Service a31ea6
Packit Service a31ea6
        tok = self.tokens[0]
Packit Service a31ea6
        self.tokens = self.tokens[1:]
Packit Service a31ea6
        self.last = tok
Packit Service a31ea6
        return tok
Packit Service a31ea6
Packit Service a31ea6
class CParser:
Packit Service a31ea6
    """The C module parser"""
Packit Service a31ea6
    def __init__(self, filename, idx = None):
Packit Service a31ea6
        self.filename = filename
Packit Service a31ea6
        if len(filename) > 2 and filename[-2:] == '.h':
Packit Service a31ea6
            self.is_header = 1
Packit Service a31ea6
        else:
Packit Service a31ea6
            self.is_header = 0
Packit Service a31ea6
        self.input = open(filename)
Packit Service a31ea6
        self.lexer = CLexer(self.input)
Packit Service a31ea6
        if idx == None:
Packit Service a31ea6
            self.index = index()
Packit Service a31ea6
        else:
Packit Service a31ea6
            self.index = idx
Packit Service a31ea6
        self.top_comment = ""
Packit Service a31ea6
        self.last_comment = ""
Packit Service a31ea6
        self.comment = None
Packit Service a31ea6
        self.collect_ref = 0
Packit Service a31ea6
        self.no_error = 0
Packit Service a31ea6
        self.conditionals = []
Packit Service a31ea6
        self.defines = []
Packit Service a31ea6
Packit Service a31ea6
    def collect_references(self):
Packit Service a31ea6
        self.collect_ref = 1
Packit Service a31ea6
Packit Service a31ea6
    def stop_error(self):
Packit Service a31ea6
        self.no_error = 1
Packit Service a31ea6
Packit Service a31ea6
    def start_error(self):
Packit Service a31ea6
        self.no_error = 0
Packit Service a31ea6
Packit Service a31ea6
    def lineno(self):
Packit Service a31ea6
        return self.lexer.getlineno()
Packit Service a31ea6
Packit Service a31ea6
    def index_add(self, name, module, static, type, info=None, extra = None):
Packit Service a31ea6
        if self.is_header == 1:
Packit Service a31ea6
            self.index.add(name, module, module, static, type, self.lineno(),
Packit Service a31ea6
                           info, extra, self.conditionals)
Packit Service a31ea6
        else:
Packit Service a31ea6
            self.index.add(name, None, module, static, type, self.lineno(),
Packit Service a31ea6
                           info, extra, self.conditionals)
Packit Service a31ea6
Packit Service a31ea6
    def index_add_ref(self, name, module, static, type, info=None,
Packit Service a31ea6
                      extra = None):
Packit Service a31ea6
        if self.is_header == 1:
Packit Service a31ea6
            self.index.add_ref(name, module, module, static, type,
Packit Service a31ea6
                               self.lineno(), info, extra, self.conditionals)
Packit Service a31ea6
        else:
Packit Service a31ea6
            self.index.add_ref(name, None, module, static, type, self.lineno(),
Packit Service a31ea6
                               info, extra, self.conditionals)
Packit Service a31ea6
Packit Service a31ea6
    def warning(self, msg):
Packit Service a31ea6
        if self.no_error:
Packit Service a31ea6
            return
Packit Service a31ea6
        print(msg)
Packit Service a31ea6
Packit Service a31ea6
    def error(self, msg, token=-1):
Packit Service a31ea6
        if self.no_error:
Packit Service a31ea6
            return
Packit Service a31ea6
Packit Service a31ea6
        print("Parse Error: " + msg)
Packit Service a31ea6
        if token != -1:
Packit Service a31ea6
            print("Got token ", token)
Packit Service a31ea6
        self.lexer.debug()
Packit Service a31ea6
        sys.exit(1)
Packit Service a31ea6
Packit Service a31ea6
    def debug(self, msg, token=-1):
Packit Service a31ea6
        print("Debug: " + msg)
Packit Service a31ea6
        if token != -1:
Packit Service a31ea6
            print("Got token ", token)
Packit Service a31ea6
        self.lexer.debug()
Packit Service a31ea6
Packit Service a31ea6
    def parseTopComment(self, comment):
Packit Service a31ea6
        res = {}
Packit Service a31ea6
        lines = comment.split("\n")
Packit Service a31ea6
        item = None
Packit Service a31ea6
        for line in lines:
Packit Service a31ea6
            while line != "" and (line[0] == ' ' or line[0] == '\t'):
Packit Service a31ea6
                line = line[1:]
Packit Service a31ea6
            while line != "" and line[0] == '*':
Packit Service a31ea6
                line = line[1:]
Packit Service a31ea6
            while line != "" and (line[0] == ' ' or line[0] == '\t'):
Packit Service a31ea6
                line = line[1:]
Packit Service a31ea6
            try:
Packit Service a31ea6
                (it, line) = line.split(":", 1)
Packit Service a31ea6
                item = it
Packit Service a31ea6
                while line != "" and (line[0] == ' ' or line[0] == '\t'):
Packit Service a31ea6
                    line = line[1:]
Packit Service a31ea6
                if item in res:
Packit Service a31ea6
                    res[item] = res[item] + " " + line
Packit Service a31ea6
                else:
Packit Service a31ea6
                    res[item] = line
Packit Service a31ea6
            except:
Packit Service a31ea6
                if item != None:
Packit Service a31ea6
                    if item in res:
Packit Service a31ea6
                        res[item] = res[item] + " " + line
Packit Service a31ea6
                    else:
Packit Service a31ea6
                        res[item] = line
Packit Service a31ea6
        self.index.info = res
Packit Service a31ea6
Packit Service a31ea6
    def parseComment(self, token):
Packit Service a31ea6
        if self.top_comment == "":
Packit Service a31ea6
            self.top_comment = token[1]
Packit Service a31ea6
        if self.comment == None or token[1][0] == '*':
Packit Service a31ea6
            self.comment = token[1];
Packit Service a31ea6
        else:
Packit Service a31ea6
            self.comment = self.comment + token[1]
Packit Service a31ea6
        token = self.lexer.token()
Packit Service a31ea6
Packit Service a31ea6
        if self.comment.find("DOC_DISABLE") != -1:
Packit Service a31ea6
            self.stop_error()
Packit Service a31ea6
Packit Service a31ea6
        if self.comment.find("DOC_ENABLE") != -1:
Packit Service a31ea6
            self.start_error()
Packit Service a31ea6
Packit Service a31ea6
        return token
Packit Service a31ea6
Packit Service a31ea6
    #
Packit Service a31ea6
    # Parse a comment block associate to a typedef
Packit Service a31ea6
    #
Packit Service a31ea6
    def parseTypeComment(self, name, quiet = 0):
Packit Service a31ea6
        if name[0:2] == '__':
Packit Service a31ea6
            quiet = 1
Packit Service a31ea6
Packit Service a31ea6
        args = []
Packit Service a31ea6
        desc = ""
Packit Service a31ea6
Packit Service a31ea6
        if self.comment == None:
Packit Service a31ea6
            if not quiet:
Packit Service a31ea6
                self.warning("Missing comment for type %s" % (name))
Packit Service a31ea6
            return((args, desc))
Packit Service a31ea6
        if self.comment[0] != '*':
Packit Service a31ea6
            if not quiet:
Packit Service a31ea6
                self.warning("Missing * in type comment for %s" % (name))
Packit Service a31ea6
            return((args, desc))
Packit Service a31ea6
        lines = self.comment.split('\n')
Packit Service a31ea6
        if lines[0] == '*':
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
        if lines[0] != "* %s:" % (name):
Packit Service a31ea6
            if not quiet:
Packit Service a31ea6
                self.warning("Misformatted type comment for %s" % (name))
Packit Service a31ea6
                self.warning("  Expecting '* %s:' got '%s'" % (name, lines[0]))
Packit Service a31ea6
            return((args, desc))
Packit Service a31ea6
        del lines[0]
Packit Service a31ea6
        while len(lines) > 0 and lines[0] == '*':
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
        desc = ""
Packit Service a31ea6
        while len(lines) > 0:
Packit Service a31ea6
            l = lines[0]
Packit Service a31ea6
            while len(l) > 0 and l[0] == '*':
Packit Service a31ea6
                l = l[1:]
Packit Service a31ea6
            l = l.strip()
Packit Service a31ea6
            desc = desc + " " + l
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
Packit Service a31ea6
        desc = desc.strip()
Packit Service a31ea6
Packit Service a31ea6
        if quiet == 0:
Packit Service a31ea6
            if desc == "":
Packit Service a31ea6
                self.warning("Type comment for %s lack description of the macro" % (name))
Packit Service a31ea6
Packit Service a31ea6
        return(desc)
Packit Service a31ea6
    #
Packit Service a31ea6
    # Parse a comment block associate to a macro
Packit Service a31ea6
    #
Packit Service a31ea6
    def parseMacroComment(self, name, quiet = 0):
Packit Service a31ea6
        if name[0:2] == '__':
Packit Service a31ea6
            quiet = 1
Packit Service a31ea6
Packit Service a31ea6
        args = []
Packit Service a31ea6
        desc = ""
Packit Service a31ea6
Packit Service a31ea6
        if self.comment == None:
Packit Service a31ea6
            if not quiet:
Packit Service a31ea6
                self.warning("Missing comment for macro %s" % (name))
Packit Service a31ea6
            return((args, desc))
Packit Service a31ea6
        if self.comment[0] != '*':
Packit Service a31ea6
            if not quiet:
Packit Service a31ea6
                self.warning("Missing * in macro comment for %s" % (name))
Packit Service a31ea6
            return((args, desc))
Packit Service a31ea6
        lines = self.comment.split('\n')
Packit Service a31ea6
        if lines[0] == '*':
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
        if lines[0] != "* %s:" % (name):
Packit Service a31ea6
            if not quiet:
Packit Service a31ea6
                self.warning("Misformatted macro comment for %s" % (name))
Packit Service a31ea6
                self.warning("  Expecting '* %s:' got '%s'" % (name, lines[0]))
Packit Service a31ea6
            return((args, desc))
Packit Service a31ea6
        del lines[0]
Packit Service a31ea6
        while lines[0] == '*':
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
        while len(lines) > 0 and lines[0][0:3] == '* @':
Packit Service a31ea6
            l = lines[0][3:]
Packit Service a31ea6
            try:
Packit Service a31ea6
                (arg, desc) = l.split(':', 1)
Packit Service a31ea6
                desc=desc.strip()
Packit Service a31ea6
                arg=arg.strip()
Packit Service a31ea6
            except:
Packit Service a31ea6
                if not quiet:
Packit Service a31ea6
                    self.warning("Misformatted macro comment for %s" % (name))
Packit Service a31ea6
                    self.warning("  problem with '%s'" % (lines[0]))
Packit Service a31ea6
                del lines[0]
Packit Service a31ea6
                continue
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
            l = lines[0].strip()
Packit Service a31ea6
            while len(l) > 2 and l[0:3] != '* @':
Packit Service a31ea6
                while l[0] == '*':
Packit Service a31ea6
                    l = l[1:]
Packit Service a31ea6
                desc = desc + ' ' + l.strip()
Packit Service a31ea6
                del lines[0]
Packit Service a31ea6
                if len(lines) == 0:
Packit Service a31ea6
                    break
Packit Service a31ea6
                l = lines[0]
Packit Service a31ea6
            args.append((arg, desc))
Packit Service a31ea6
        while len(lines) > 0 and lines[0] == '*':
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
        desc = ""
Packit Service a31ea6
        while len(lines) > 0:
Packit Service a31ea6
            l = lines[0]
Packit Service a31ea6
            while len(l) > 0 and l[0] == '*':
Packit Service a31ea6
                l = l[1:]
Packit Service a31ea6
            l = l.strip()
Packit Service a31ea6
            desc = desc + " " + l
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
Packit Service a31ea6
        desc = desc.strip()
Packit Service a31ea6
Packit Service a31ea6
        if quiet == 0:
Packit Service a31ea6
            if desc == "":
Packit Service a31ea6
                self.warning("Macro comment for %s lack description of the macro" % (name))
Packit Service a31ea6
Packit Service a31ea6
        return((args, desc))
Packit Service a31ea6
Packit Service a31ea6
     #
Packit Service a31ea6
     # Parse a comment block and merge the informations found in the
Packit Service a31ea6
     # parameters descriptions, finally returns a block as complete
Packit Service a31ea6
     # as possible
Packit Service a31ea6
     #
Packit Service a31ea6
    def mergeFunctionComment(self, name, description, quiet = 0):
Packit Service a31ea6
        if name == 'main':
Packit Service a31ea6
            quiet = 1
Packit Service a31ea6
        if name[0:2] == '__':
Packit Service a31ea6
            quiet = 1
Packit Service a31ea6
Packit Service a31ea6
        (ret, args) = description
Packit Service a31ea6
        desc = ""
Packit Service a31ea6
        retdesc = ""
Packit Service a31ea6
Packit Service a31ea6
        if self.comment == None:
Packit Service a31ea6
            if not quiet:
Packit Service a31ea6
                self.warning("Missing comment for function %s" % (name))
Packit Service a31ea6
            return(((ret[0], retdesc), args, desc))
Packit Service a31ea6
        if self.comment[0] != '*':
Packit Service a31ea6
            if not quiet:
Packit Service a31ea6
                self.warning("Missing * in function comment for %s" % (name))
Packit Service a31ea6
            return(((ret[0], retdesc), args, desc))
Packit Service a31ea6
        lines = self.comment.split('\n')
Packit Service a31ea6
        if lines[0] == '*':
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
        if lines[0] != "* %s:" % (name):
Packit Service a31ea6
            if not quiet:
Packit Service a31ea6
                self.warning("Misformatted function comment for %s" % (name))
Packit Service a31ea6
                self.warning("  Expecting '* %s:' got '%s'" % (name, lines[0]))
Packit Service a31ea6
            return(((ret[0], retdesc), args, desc))
Packit Service a31ea6
        del lines[0]
Packit Service a31ea6
        while lines[0] == '*':
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
        nbargs = len(args)
Packit Service a31ea6
        while len(lines) > 0 and lines[0][0:3] == '* @':
Packit Service a31ea6
            l = lines[0][3:]
Packit Service a31ea6
            try:
Packit Service a31ea6
                (arg, desc) = l.split(':', 1)
Packit Service a31ea6
                desc=desc.strip()
Packit Service a31ea6
                arg=arg.strip()
Packit Service a31ea6
            except:
Packit Service a31ea6
                if not quiet:
Packit Service a31ea6
                    self.warning("Misformatted function comment for %s" % (name))
Packit Service a31ea6
                    self.warning("  problem with '%s'" % (lines[0]))
Packit Service a31ea6
                del lines[0]
Packit Service a31ea6
                continue
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
            l = lines[0].strip()
Packit Service a31ea6
            while len(l) > 2 and l[0:3] != '* @':
Packit Service a31ea6
                while l[0] == '*':
Packit Service a31ea6
                    l = l[1:]
Packit Service a31ea6
                desc = desc + ' ' + l.strip()
Packit Service a31ea6
                del lines[0]
Packit Service a31ea6
                if len(lines) == 0:
Packit Service a31ea6
                    break
Packit Service a31ea6
                l = lines[0]
Packit Service a31ea6
            i = 0
Packit Service a31ea6
            while i < nbargs:
Packit Service a31ea6
                if args[i][1] == arg:
Packit Service a31ea6
                    args[i] = (args[i][0], arg, desc)
Packit Service a31ea6
                    break;
Packit Service a31ea6
                i = i + 1
Packit Service a31ea6
            if i >= nbargs:
Packit Service a31ea6
                if not quiet:
Packit Service a31ea6
                    self.warning("Unable to find arg %s from function comment for %s" % (
Packit Service a31ea6
                       arg, name))
Packit Service a31ea6
        while len(lines) > 0 and lines[0] == '*':
Packit Service a31ea6
            del lines[0]
Packit Service a31ea6
        desc = ""
Packit Service a31ea6
        while len(lines) > 0:
Packit Service a31ea6
            l = lines[0]
Packit Service a31ea6
            while len(l) > 0 and l[0] == '*':
Packit Service a31ea6
                l = l[1:]
Packit Service a31ea6
            l = l.strip()
Packit Service a31ea6
            if len(l) >= 6 and  l[0:6] == "return" or l[0:6] == "Return":
Packit Service a31ea6
                try:
Packit Service a31ea6
                    l = l.split(' ', 1)[1]
Packit Service a31ea6
                except:
Packit Service a31ea6
                    l = ""
Packit Service a31ea6
                retdesc = l.strip()
Packit Service a31ea6
                del lines[0]
Packit Service a31ea6
                while len(lines) > 0:
Packit Service a31ea6
                    l = lines[0]
Packit Service a31ea6
                    while len(l) > 0 and l[0] == '*':
Packit Service a31ea6
                        l = l[1:]
Packit Service a31ea6
                    l = l.strip()
Packit Service a31ea6
                    retdesc = retdesc + " " + l
Packit Service a31ea6
                    del lines[0]
Packit Service a31ea6
            else:
Packit Service a31ea6
                desc = desc + " " + l
Packit Service a31ea6
                del lines[0]
Packit Service a31ea6
Packit Service a31ea6
        retdesc = retdesc.strip()
Packit Service a31ea6
        desc = desc.strip()
Packit Service a31ea6
Packit Service a31ea6
        if quiet == 0:
Packit Service a31ea6
             #
Packit Service a31ea6
             # report missing comments
Packit Service a31ea6
             #
Packit Service a31ea6
            i = 0
Packit Service a31ea6
            while i < nbargs:
Packit Service a31ea6
                if args[i][2] == None and args[i][0] != "void" and \
Packit Service a31ea6
                   ((args[i][1] != None) or (args[i][1] == '')):
Packit Service a31ea6
                    self.warning("Function comment for %s lacks description of arg %s" % (name, args[i][1]))
Packit Service a31ea6
                i = i + 1
Packit Service a31ea6
            if retdesc == "" and ret[0] != "void":
Packit Service a31ea6
                self.warning("Function comment for %s lacks description of return value" % (name))
Packit Service a31ea6
            if desc == "":
Packit Service a31ea6
                self.warning("Function comment for %s lacks description of the function" % (name))
Packit Service a31ea6
Packit Service a31ea6
        return(((ret[0], retdesc), args, desc))
Packit Service a31ea6
Packit Service a31ea6
    def parsePreproc(self, token):
Packit Service a31ea6
        if debug:
Packit Service a31ea6
            print("=> preproc ", token, self.lexer.tokens)
Packit Service a31ea6
        name = token[1]
Packit Service a31ea6
        if name == "#include":
Packit Service a31ea6
            token = self.lexer.token()
Packit Service a31ea6
            if token == None:
Packit Service a31ea6
                return None
Packit Service a31ea6
            if token[0] == 'preproc':
Packit Service a31ea6
                self.index_add(token[1], self.filename, not self.is_header,
Packit Service a31ea6
                                "include")
Packit Service a31ea6
                return self.lexer.token()
Packit Service a31ea6
            return token
Packit Service a31ea6
        if name == "#define":
Packit Service a31ea6
            token = self.lexer.token()
Packit Service a31ea6
            if token == None:
Packit Service a31ea6
                return None
Packit Service a31ea6
            if token[0] == 'preproc':
Packit Service a31ea6
                 # TODO macros with arguments
Packit Service a31ea6
                name = token[1]
Packit Service a31ea6
                lst = []
Packit Service a31ea6
                token = self.lexer.token()
Packit Service a31ea6
                while token != None and token[0] == 'preproc' and \
Packit Service a31ea6
                      token[1][0] != '#':
Packit Service a31ea6
                    lst.append(token[1])
Packit Service a31ea6
                    token = self.lexer.token()
Packit Service a31ea6
                try:
Packit Service a31ea6
                    name = name.split('(') [0]
Packit Service a31ea6
                except:
Packit Service a31ea6
                    pass
Packit Service a31ea6
                info = self.parseMacroComment(name, not self.is_header)
Packit Service a31ea6
                self.index_add(name, self.filename, not self.is_header,
Packit Service a31ea6
                                "macro", info)
Packit Service a31ea6
                return token
Packit Service a31ea6
Packit Service a31ea6
        #
Packit Service a31ea6
        # Processing of conditionals modified by Bill 1/1/05
Packit Service a31ea6
        #
Packit Service a31ea6
        # We process conditionals (i.e. tokens from #ifdef, #ifndef,
Packit Service a31ea6
        # #if, #else and #endif) for headers and mainline code,
Packit Service a31ea6
        # store the ones from the header in libxml2-api.xml, and later
Packit Service a31ea6
        # (in the routine merge_public) verify that the two (header and
Packit Service a31ea6
        # mainline code) agree.
Packit Service a31ea6
        #
Packit Service a31ea6
        # There is a small problem with processing the headers. Some of
Packit Service a31ea6
        # the variables are not concerned with enabling / disabling of
Packit Service a31ea6
        # library functions (e.g. '__XML_PARSER_H__'), and we don't want
Packit Service a31ea6
        # them to be included in libxml2-api.xml, or involved in
Packit Service a31ea6
        # the check between the header and the mainline code.  To
Packit Service a31ea6
        # accomplish this, we ignore any conditional which doesn't include
Packit Service a31ea6
        # the string 'ENABLED'
Packit Service a31ea6
        #
Packit Service a31ea6
        if name == "#ifdef":
Packit Service a31ea6
            apstr = self.lexer.tokens[0][1]
Packit Service a31ea6
            try:
Packit Service a31ea6
                self.defines.append(apstr)
Packit Service a31ea6
                if apstr.find('ENABLED') != -1:
Packit Service a31ea6
                    self.conditionals.append("defined(%s)" % apstr)
Packit Service a31ea6
            except:
Packit Service a31ea6
                pass
Packit Service a31ea6
        elif name == "#ifndef":
Packit Service a31ea6
            apstr = self.lexer.tokens[0][1]
Packit Service a31ea6
            try:
Packit Service a31ea6
                self.defines.append(apstr)
Packit Service a31ea6
                if apstr.find('ENABLED') != -1:
Packit Service a31ea6
                    self.conditionals.append("!defined(%s)" % apstr)
Packit Service a31ea6
            except:
Packit Service a31ea6
                pass
Packit Service a31ea6
        elif name == "#if":
Packit Service a31ea6
            apstr = ""
Packit Service a31ea6
            for tok in self.lexer.tokens:
Packit Service a31ea6
                if apstr != "":
Packit Service a31ea6
                    apstr = apstr + " "
Packit Service a31ea6
                apstr = apstr + tok[1]
Packit Service a31ea6
            try:
Packit Service a31ea6
                self.defines.append(apstr)
Packit Service a31ea6
                if apstr.find('ENABLED') != -1:
Packit Service a31ea6
                    self.conditionals.append(apstr)
Packit Service a31ea6
            except:
Packit Service a31ea6
                pass
Packit Service a31ea6
        elif name == "#else":
Packit Service a31ea6
            if self.conditionals != [] and \
Packit Service a31ea6
               self.defines[-1].find('ENABLED') != -1:
Packit Service a31ea6
                self.conditionals[-1] = "!(%s)" % self.conditionals[-1]
Packit Service a31ea6
        elif name == "#endif":
Packit Service a31ea6
            if self.conditionals != [] and \
Packit Service a31ea6
               self.defines[-1].find('ENABLED') != -1:
Packit Service a31ea6
                self.conditionals = self.conditionals[:-1]
Packit Service a31ea6
            self.defines = self.defines[:-1]
Packit Service a31ea6
        token = self.lexer.token()
Packit Service a31ea6
        while token != None and token[0] == 'preproc' and \
Packit Service a31ea6
            token[1][0] != '#':
Packit Service a31ea6
            token = self.lexer.token()
Packit Service a31ea6
        return token
Packit Service a31ea6
Packit Service a31ea6
     #
Packit Service a31ea6
     # token acquisition on top of the lexer, it handle internally
Packit Service a31ea6
     # preprocessor and comments since they are logically not part of
Packit Service a31ea6
     # the program structure.
Packit Service a31ea6
     #
Packit Service a31ea6
    def token(self):
Packit Service a31ea6
        global ignored_words
Packit Service a31ea6
Packit Service a31ea6
        token = self.lexer.token()
Packit Service a31ea6
        while token != None:
Packit Service a31ea6
            if token[0] == 'comment':
Packit Service a31ea6
                token = self.parseComment(token)
Packit Service a31ea6
                continue
Packit Service a31ea6
            elif token[0] == 'preproc':
Packit Service a31ea6
                token = self.parsePreproc(token)
Packit Service a31ea6
                continue
Packit Service a31ea6
            elif token[0] == "name" and token[1] == "__const":
Packit Service a31ea6
                token = ("name", "const")
Packit Service a31ea6
                return token
Packit Service a31ea6
            elif token[0] == "name" and token[1] == "__attribute":
Packit Service a31ea6
                token = self.lexer.token()
Packit Service a31ea6
                while token != None and token[1] != ";":
Packit Service a31ea6
                    token = self.lexer.token()
Packit Service a31ea6
                return token
Packit Service a31ea6
            elif token[0] == "name" and token[1] in ignored_words:
Packit Service a31ea6
                (n, info) = ignored_words[token[1]]
Packit Service a31ea6
                i = 0
Packit Service a31ea6
                while i < n:
Packit Service a31ea6
                    token = self.lexer.token()
Packit Service a31ea6
                    i = i + 1
Packit Service a31ea6
                token = self.lexer.token()
Packit Service a31ea6
                continue
Packit Service a31ea6
            else:
Packit Service a31ea6
                if debug:
Packit Service a31ea6
                    print("=> ", token)
Packit Service a31ea6
                return token
Packit Service a31ea6
        return None
Packit Service a31ea6
Packit Service a31ea6
     #
Packit Service a31ea6
     # Parse a typedef, it records the type and its name.
Packit Service a31ea6
     #
Packit Service a31ea6
    def parseTypedef(self, token):
Packit Service a31ea6
        if token == None:
Packit Service a31ea6
            return None
Packit Service a31ea6
        token = self.parseType(token)
Packit Service a31ea6
        if token == None:
Packit Service a31ea6
            self.error("parsing typedef")
Packit Service a31ea6
            return None
Packit Service a31ea6
        base_type = self.type
Packit Service a31ea6
        type = base_type
Packit Service a31ea6
         #self.debug("end typedef type", token)
Packit Service a31ea6
        while token != None:
Packit Service a31ea6
            if token[0] == "name":
Packit Service a31ea6
                name = token[1]
Packit Service a31ea6
                signature = self.signature
Packit Service a31ea6
                if signature != None:
Packit Service a31ea6
                    type = type.split('(')[0]
Packit Service a31ea6
                    d = self.mergeFunctionComment(name,
Packit Service a31ea6
                            ((type, None), signature), 1)
Packit Service a31ea6
                    self.index_add(name, self.filename, not self.is_header,
Packit Service a31ea6
                                    "functype", d)
Packit Service a31ea6
                else:
Packit Service a31ea6
                    if base_type == "struct":
Packit Service a31ea6
                        self.index_add(name, self.filename, not self.is_header,
Packit Service a31ea6
                                        "struct", type)
Packit Service a31ea6
                        base_type = "struct " + name
Packit Service a31ea6
                    else:
Packit Service a31ea6
                        # TODO report missing or misformatted comments
Packit Service a31ea6
                        info = self.parseTypeComment(name, 1)
Packit Service a31ea6
                        self.index_add(name, self.filename, not self.is_header,
Packit Service a31ea6
                                    "typedef", type, info)
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
            else:
Packit Service a31ea6
                self.error("parsing typedef: expecting a name")
Packit Service a31ea6
                return token
Packit Service a31ea6
             #self.debug("end typedef", token)
Packit Service a31ea6
            if token != None and token[0] == 'sep' and token[1] == ',':
Packit Service a31ea6
                type = base_type
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                while token != None and token[0] == "op":
Packit Service a31ea6
                    type = type + token[1]
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
            elif token != None and token[0] == 'sep' and token[1] == ';':
Packit Service a31ea6
                break;
Packit Service a31ea6
            elif token != None and token[0] == 'name':
Packit Service a31ea6
                type = base_type
Packit Service a31ea6
                continue;
Packit Service a31ea6
            else:
Packit Service a31ea6
                self.error("parsing typedef: expecting ';'", token)
Packit Service a31ea6
                return token
Packit Service a31ea6
        token = self.token()
Packit Service a31ea6
        return token
Packit Service a31ea6
Packit Service a31ea6
     #
Packit Service a31ea6
     # Parse a C code block, used for functions it parse till
Packit Service a31ea6
     # the balancing } included
Packit Service a31ea6
     #
Packit Service a31ea6
    def parseBlock(self, token):
Packit Service a31ea6
        while token != None:
Packit Service a31ea6
            if token[0] == "sep" and token[1] == "{":
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                token = self.parseBlock(token)
Packit Service a31ea6
            elif token[0] == "sep" and token[1] == "}":
Packit Service a31ea6
                self.comment = None
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                return token
Packit Service a31ea6
            else:
Packit Service a31ea6
                if self.collect_ref == 1:
Packit Service a31ea6
                    oldtok = token
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    if oldtok[0] == "name" and oldtok[1][0:3] == "xml":
Packit Service a31ea6
                        if token[0] == "sep" and token[1] == "(":
Packit Service a31ea6
                            self.index_add_ref(oldtok[1], self.filename,
Packit Service a31ea6
                                                0, "function")
Packit Service a31ea6
                            token = self.token()
Packit Service a31ea6
                        elif token[0] == "name":
Packit Service a31ea6
                            token = self.token()
Packit Service a31ea6
                            if token[0] == "sep" and (token[1] == ";" or
Packit Service a31ea6
                               token[1] == "," or token[1] == "="):
Packit Service a31ea6
                                self.index_add_ref(oldtok[1], self.filename,
Packit Service a31ea6
                                                    0, "type")
Packit Service a31ea6
                    elif oldtok[0] == "name" and oldtok[1][0:4] == "XML_":
Packit Service a31ea6
                        self.index_add_ref(oldtok[1], self.filename,
Packit Service a31ea6
                                            0, "typedef")
Packit Service a31ea6
                    elif oldtok[0] == "name" and oldtok[1][0:7] == "LIBXML_":
Packit Service a31ea6
                        self.index_add_ref(oldtok[1], self.filename,
Packit Service a31ea6
                                            0, "typedef")
Packit Service a31ea6
Packit Service a31ea6
                else:
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
        return token
Packit Service a31ea6
Packit Service a31ea6
     #
Packit Service a31ea6
     # Parse a C struct definition till the balancing }
Packit Service a31ea6
     #
Packit Service a31ea6
    def parseStruct(self, token):
Packit Service a31ea6
        fields = []
Packit Service a31ea6
         #self.debug("start parseStruct", token)
Packit Service a31ea6
        while token != None:
Packit Service a31ea6
            if token[0] == "sep" and token[1] == "{":
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                token = self.parseTypeBlock(token)
Packit Service a31ea6
            elif token[0] == "sep" and token[1] == "}":
Packit Service a31ea6
                self.struct_fields = fields
Packit Service a31ea6
                 #self.debug("end parseStruct", token)
Packit Service a31ea6
                 #print fields
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                return token
Packit Service a31ea6
            else:
Packit Service a31ea6
                base_type = self.type
Packit Service a31ea6
                 #self.debug("before parseType", token)
Packit Service a31ea6
                token = self.parseType(token)
Packit Service a31ea6
                 #self.debug("after parseType", token)
Packit Service a31ea6
                if token != None and token[0] == "name":
Packit Service a31ea6
                    fname = token[1]
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    if token[0] == "sep" and token[1] == ";":
Packit Service a31ea6
                        self.comment = None
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
                        fields.append((self.type, fname, self.comment))
Packit Service a31ea6
                        self.comment = None
Packit Service a31ea6
                    else:
Packit Service a31ea6
                        self.error("parseStruct: expecting ;", token)
Packit Service a31ea6
                elif token != None and token[0] == "sep" and token[1] == "{":
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    token = self.parseTypeBlock(token)
Packit Service a31ea6
                    if token != None and token[0] == "name":
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
                    if token != None and token[0] == "sep" and token[1] == ";":
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
                    else:
Packit Service a31ea6
                        self.error("parseStruct: expecting ;", token)
Packit Service a31ea6
                else:
Packit Service a31ea6
                    self.error("parseStruct: name", token)
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                self.type = base_type;
Packit Service a31ea6
        self.struct_fields = fields
Packit Service a31ea6
         #self.debug("end parseStruct", token)
Packit Service a31ea6
         #print fields
Packit Service a31ea6
        return token
Packit Service a31ea6
Packit Service a31ea6
     #
Packit Service a31ea6
     # Parse a C enum block, parse till the balancing }
Packit Service a31ea6
     #
Packit Service a31ea6
    def parseEnumBlock(self, token):
Packit Service a31ea6
        self.enums = []
Packit Service a31ea6
        name = None
Packit Service a31ea6
        self.comment = None
Packit Service a31ea6
        comment = ""
Packit Service a31ea6
        value = "0"
Packit Service a31ea6
        while token != None:
Packit Service a31ea6
            if token[0] == "sep" and token[1] == "{":
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                token = self.parseTypeBlock(token)
Packit Service a31ea6
            elif token[0] == "sep" and token[1] == "}":
Packit Service a31ea6
                if name != None:
Packit Service a31ea6
                    if self.comment != None:
Packit Service a31ea6
                        comment = self.comment
Packit Service a31ea6
                        self.comment = None
Packit Service a31ea6
                    self.enums.append((name, value, comment))
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                return token
Packit Service a31ea6
            elif token[0] == "name":
Packit Service a31ea6
                    if name != None:
Packit Service a31ea6
                        if self.comment != None:
Packit Service a31ea6
                            comment = self.comment.strip()
Packit Service a31ea6
                            self.comment = None
Packit Service a31ea6
                        self.enums.append((name, value, comment))
Packit Service a31ea6
                    name = token[1]
Packit Service a31ea6
                    comment = ""
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    if token[0] == "op" and token[1][0] == "=":
Packit Service a31ea6
                        value = ""
Packit Service a31ea6
                        if len(token[1]) > 1:
Packit Service a31ea6
                            value = token[1][1:]
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
                        while token[0] != "sep" or (token[1] != ',' and
Packit Service a31ea6
                              token[1] != '}'):
Packit Service a31ea6
                            value = value + token[1]
Packit Service a31ea6
                            token = self.token()
Packit Service a31ea6
                    else:
Packit Service a31ea6
                        try:
Packit Service a31ea6
                            value = "%d" % (int(value) + 1)
Packit Service a31ea6
                        except:
Packit Service a31ea6
                            self.warning("Failed to compute value of enum %s" % (name))
Packit Service a31ea6
                            value=""
Packit Service a31ea6
                    if token[0] == "sep" and token[1] == ",":
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
            else:
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
        return token
Packit Service a31ea6
Packit Service a31ea6
     #
Packit Service a31ea6
     # Parse a C definition block, used for structs it parse till
Packit Service a31ea6
     # the balancing }
Packit Service a31ea6
     #
Packit Service a31ea6
    def parseTypeBlock(self, token):
Packit Service a31ea6
        while token != None:
Packit Service a31ea6
            if token[0] == "sep" and token[1] == "{":
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                token = self.parseTypeBlock(token)
Packit Service a31ea6
            elif token[0] == "sep" and token[1] == "}":
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                return token
Packit Service a31ea6
            else:
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
        return token
Packit Service a31ea6
Packit Service a31ea6
     #
Packit Service a31ea6
     # Parse a type: the fact that the type name can either occur after
Packit Service a31ea6
     #    the definition or within the definition makes it a little harder
Packit Service a31ea6
     #    if inside, the name token is pushed back before returning
Packit Service a31ea6
     #
Packit Service a31ea6
    def parseType(self, token):
Packit Service a31ea6
        self.type = ""
Packit Service a31ea6
        self.struct_fields = []
Packit Service a31ea6
        self.signature = None
Packit Service a31ea6
        if token == None:
Packit Service a31ea6
            return token
Packit Service a31ea6
Packit Service a31ea6
        while token[0] == "name" and (
Packit Service a31ea6
              token[1] == "const" or \
Packit Service a31ea6
              token[1] == "unsigned" or \
Packit Service a31ea6
              token[1] == "signed"):
Packit Service a31ea6
            if self.type == "":
Packit Service a31ea6
                self.type = token[1]
Packit Service a31ea6
            else:
Packit Service a31ea6
                self.type = self.type + " " + token[1]
Packit Service a31ea6
            token = self.token()
Packit Service a31ea6
Packit Service a31ea6
        if token[0] == "name" and (token[1] == "long" or token[1] == "short"):
Packit Service a31ea6
            if self.type == "":
Packit Service a31ea6
                self.type = token[1]
Packit Service a31ea6
            else:
Packit Service a31ea6
                self.type = self.type + " " + token[1]
Packit Service a31ea6
            if token[0] == "name" and token[1] == "int":
Packit Service a31ea6
                if self.type == "":
Packit Service a31ea6
                    self.type = tmp[1]
Packit Service a31ea6
                else:
Packit Service a31ea6
                    self.type = self.type + " " + tmp[1]
Packit Service a31ea6
Packit Service a31ea6
        elif token[0] == "name" and token[1] == "struct":
Packit Service a31ea6
            if self.type == "":
Packit Service a31ea6
                self.type = token[1]
Packit Service a31ea6
            else:
Packit Service a31ea6
                self.type = self.type + " " + token[1]
Packit Service a31ea6
            token = self.token()
Packit Service a31ea6
            nametok = None
Packit Service a31ea6
            if token[0] == "name":
Packit Service a31ea6
                nametok = token
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
            if token != None and token[0] == "sep" and token[1] == "{":
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                token = self.parseStruct(token)
Packit Service a31ea6
            elif token != None and token[0] == "op" and token[1] == "*":
Packit Service a31ea6
                self.type = self.type + " " + nametok[1] + " *"
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                while token != None and token[0] == "op" and token[1] == "*":
Packit Service a31ea6
                    self.type = self.type + " *"
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                if token[0] == "name":
Packit Service a31ea6
                    nametok = token
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                else:
Packit Service a31ea6
                    self.error("struct : expecting name", token)
Packit Service a31ea6
                    return token
Packit Service a31ea6
            elif token != None and token[0] == "name" and nametok != None:
Packit Service a31ea6
                self.type = self.type + " " + nametok[1]
Packit Service a31ea6
                return token
Packit Service a31ea6
Packit Service a31ea6
            if nametok != None:
Packit Service a31ea6
                self.lexer.push(token)
Packit Service a31ea6
                token = nametok
Packit Service a31ea6
            return token
Packit Service a31ea6
Packit Service a31ea6
        elif token[0] == "name" and token[1] == "enum":
Packit Service a31ea6
            if self.type == "":
Packit Service a31ea6
                self.type = token[1]
Packit Service a31ea6
            else:
Packit Service a31ea6
                self.type = self.type + " " + token[1]
Packit Service a31ea6
            self.enums = []
Packit Service a31ea6
            token = self.token()
Packit Service a31ea6
            if token != None and token[0] == "sep" and token[1] == "{":
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                token = self.parseEnumBlock(token)
Packit Service a31ea6
            else:
Packit Service a31ea6
                self.error("parsing enum: expecting '{'", token)
Packit Service a31ea6
            enum_type = None
Packit Service a31ea6
            if token != None and token[0] != "name":
Packit Service a31ea6
                self.lexer.push(token)
Packit Service a31ea6
                token = ("name", "enum")
Packit Service a31ea6
            else:
Packit Service a31ea6
                enum_type = token[1]
Packit Service a31ea6
            for enum in self.enums:
Packit Service a31ea6
                self.index_add(enum[0], self.filename,
Packit Service a31ea6
                               not self.is_header, "enum",
Packit Service a31ea6
                               (enum[1], enum[2], enum_type))
Packit Service a31ea6
            return token
Packit Service a31ea6
Packit Service a31ea6
        elif token[0] == "name":
Packit Service a31ea6
            if self.type == "":
Packit Service a31ea6
                self.type = token[1]
Packit Service a31ea6
            else:
Packit Service a31ea6
                self.type = self.type + " " + token[1]
Packit Service a31ea6
        else:
Packit Service a31ea6
            self.error("parsing type %s: expecting a name" % (self.type),
Packit Service a31ea6
                       token)
Packit Service a31ea6
            return token
Packit Service a31ea6
        token = self.token()
Packit Service a31ea6
        while token != None and (token[0] == "op" or
Packit Service a31ea6
              token[0] == "name" and token[1] == "const"):
Packit Service a31ea6
            self.type = self.type + " " + token[1]
Packit Service a31ea6
            token = self.token()
Packit Service a31ea6
Packit Service a31ea6
         #
Packit Service a31ea6
         # if there is a parenthesis here, this means a function type
Packit Service a31ea6
         #
Packit Service a31ea6
        if token != None and token[0] == "sep" and token[1] == '(':
Packit Service a31ea6
            self.type = self.type + token[1]
Packit Service a31ea6
            token = self.token()
Packit Service a31ea6
            while token != None and token[0] == "op" and token[1] == '*':
Packit Service a31ea6
                self.type = self.type + token[1]
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
            if token == None or token[0] != "name" :
Packit Service a31ea6
                self.error("parsing function type, name expected", token);
Packit Service a31ea6
                return token
Packit Service a31ea6
            self.type = self.type + token[1]
Packit Service a31ea6
            nametok = token
Packit Service a31ea6
            token = self.token()
Packit Service a31ea6
            if token != None and token[0] == "sep" and token[1] == ')':
Packit Service a31ea6
                self.type = self.type + token[1]
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                if token != None and token[0] == "sep" and token[1] == '(':
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    type = self.type;
Packit Service a31ea6
                    token = self.parseSignature(token);
Packit Service a31ea6
                    self.type = type;
Packit Service a31ea6
                else:
Packit Service a31ea6
                    self.error("parsing function type, '(' expected", token);
Packit Service a31ea6
                    return token
Packit Service a31ea6
            else:
Packit Service a31ea6
                self.error("parsing function type, ')' expected", token);
Packit Service a31ea6
                return token
Packit Service a31ea6
            self.lexer.push(token)
Packit Service a31ea6
            token = nametok
Packit Service a31ea6
            return token
Packit Service a31ea6
Packit Service a31ea6
         #
Packit Service a31ea6
         # do some lookahead for arrays
Packit Service a31ea6
         #
Packit Service a31ea6
        if token != None and token[0] == "name":
Packit Service a31ea6
            nametok = token
Packit Service a31ea6
            token = self.token()
Packit Service a31ea6
            if token != None and token[0] == "sep" and token[1] == '[':
Packit Service a31ea6
                self.type = self.type + nametok[1]
Packit Service a31ea6
                while token != None and token[0] == "sep" and token[1] == '[':
Packit Service a31ea6
                    self.type = self.type + token[1]
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    while token != None and token[0] != 'sep' and \
Packit Service a31ea6
                          token[1] != ']' and token[1] != ';':
Packit Service a31ea6
                        self.type = self.type + token[1]
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
                if token != None and token[0] == 'sep' and token[1] == ']':
Packit Service a31ea6
                    self.type = self.type + token[1]
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                else:
Packit Service a31ea6
                    self.error("parsing array type, ']' expected", token);
Packit Service a31ea6
                    return token
Packit Service a31ea6
            elif token != None and token[0] == "sep" and token[1] == ':':
Packit Service a31ea6
                 # remove :12 in case it's a limited int size
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
            self.lexer.push(token)
Packit Service a31ea6
            token = nametok
Packit Service a31ea6
Packit Service a31ea6
        return token
Packit Service a31ea6
Packit Service a31ea6
     #
Packit Service a31ea6
     # Parse a signature: '(' has been parsed and we scan the type definition
Packit Service a31ea6
     #    up to the ')' included
Packit Service a31ea6
    def parseSignature(self, token):
Packit Service a31ea6
        signature = []
Packit Service a31ea6
        if token != None and token[0] == "sep" and token[1] == ')':
Packit Service a31ea6
            self.signature = []
Packit Service a31ea6
            token = self.token()
Packit Service a31ea6
            return token
Packit Service a31ea6
        while token != None:
Packit Service a31ea6
            token = self.parseType(token)
Packit Service a31ea6
            if token != None and token[0] == "name":
Packit Service a31ea6
                signature.append((self.type, token[1], None))
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
            elif token != None and token[0] == "sep" and token[1] == ',':
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                continue
Packit Service a31ea6
            elif token != None and token[0] == "sep" and token[1] == ')':
Packit Service a31ea6
                 # only the type was provided
Packit Service a31ea6
                if self.type == "...":
Packit Service a31ea6
                    signature.append((self.type, "...", None))
Packit Service a31ea6
                else:
Packit Service a31ea6
                    signature.append((self.type, None, None))
Packit Service a31ea6
            if token != None and token[0] == "sep":
Packit Service a31ea6
                if token[1] == ',':
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    continue
Packit Service a31ea6
                elif token[1] == ')':
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    break
Packit Service a31ea6
        self.signature = signature
Packit Service a31ea6
        return token
Packit Service a31ea6
Packit Service a31ea6
     #
Packit Service a31ea6
     # Parse a global definition, be it a type, variable or function
Packit Service a31ea6
     # the extern "C" blocks are a bit nasty and require it to recurse.
Packit Service a31ea6
     #
Packit Service a31ea6
    def parseGlobal(self, token):
Packit Service a31ea6
        static = 0
Packit Service a31ea6
        if token[1] == 'extern':
Packit Service a31ea6
            token = self.token()
Packit Service a31ea6
            if token == None:
Packit Service a31ea6
                return token
Packit Service a31ea6
            if token[0] == 'string':
Packit Service a31ea6
                if token[1] == 'C':
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    if token == None:
Packit Service a31ea6
                        return token
Packit Service a31ea6
                    if token[0] == 'sep' and token[1] == "{":
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
#                         print 'Entering extern "C line ', self.lineno()
Packit Service a31ea6
                        while token != None and (token[0] != 'sep' or
Packit Service a31ea6
                              token[1] != "}"):
Packit Service a31ea6
                            if token[0] == 'name':
Packit Service a31ea6
                                token = self.parseGlobal(token)
Packit Service a31ea6
                            else:
Packit Service a31ea6
                                self.error(
Packit Service a31ea6
                                 "token %s %s unexpected at the top level" % (
Packit Service a31ea6
                                        token[0], token[1]))
Packit Service a31ea6
                                token = self.parseGlobal(token)
Packit Service a31ea6
#                         print 'Exiting extern "C" line', self.lineno()
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
                        return token
Packit Service a31ea6
                else:
Packit Service a31ea6
                    return token
Packit Service a31ea6
        elif token[1] == 'static':
Packit Service a31ea6
            static = 1
Packit Service a31ea6
            token = self.token()
Packit Service a31ea6
            if token == None or  token[0] != 'name':
Packit Service a31ea6
                return token
Packit Service a31ea6
Packit Service a31ea6
        if token[1] == 'typedef':
Packit Service a31ea6
            token = self.token()
Packit Service a31ea6
            return self.parseTypedef(token)
Packit Service a31ea6
        else:
Packit Service a31ea6
            token = self.parseType(token)
Packit Service a31ea6
            type_orig = self.type
Packit Service a31ea6
        if token == None or token[0] != "name":
Packit Service a31ea6
            return token
Packit Service a31ea6
        type = type_orig
Packit Service a31ea6
        self.name = token[1]
Packit Service a31ea6
        token = self.token()
Packit Service a31ea6
        while token != None and (token[0] == "sep" or token[0] == "op"):
Packit Service a31ea6
            if token[0] == "sep":
Packit Service a31ea6
                if token[1] == "[":
Packit Service a31ea6
                    type = type + token[1]
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    while token != None and (token[0] != "sep" or \
Packit Service a31ea6
                          token[1] != ";"):
Packit Service a31ea6
                        type = type + token[1]
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
Packit Service a31ea6
            if token != None and token[0] == "op" and token[1] == "=":
Packit Service a31ea6
                 #
Packit Service a31ea6
                 # Skip the initialization of the variable
Packit Service a31ea6
                 #
Packit Service a31ea6
                token = self.token()
Packit Service a31ea6
                if token[0] == 'sep' and token[1] == '{':
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    token = self.parseBlock(token)
Packit Service a31ea6
                else:
Packit Service a31ea6
                    self.comment = None
Packit Service a31ea6
                    while token != None and (token[0] != "sep" or \
Packit Service a31ea6
                          (token[1] != ';' and token[1] != ',')):
Packit Service a31ea6
                            token = self.token()
Packit Service a31ea6
                self.comment = None
Packit Service a31ea6
                if token == None or token[0] != "sep" or (token[1] != ';' and
Packit Service a31ea6
                   token[1] != ','):
Packit Service a31ea6
                    self.error("missing ';' or ',' after value")
Packit Service a31ea6
Packit Service a31ea6
            if token != None and token[0] == "sep":
Packit Service a31ea6
                if token[1] == ";":
Packit Service a31ea6
                    self.comment = None
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    if type == "struct":
Packit Service a31ea6
                        self.index_add(self.name, self.filename,
Packit Service a31ea6
                             not self.is_header, "struct", self.struct_fields)
Packit Service a31ea6
                    else:
Packit Service a31ea6
                        self.index_add(self.name, self.filename,
Packit Service a31ea6
                             not self.is_header, "variable", type)
Packit Service a31ea6
                    break
Packit Service a31ea6
                elif token[1] == "(":
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    token = self.parseSignature(token)
Packit Service a31ea6
                    if token == None:
Packit Service a31ea6
                        return None
Packit Service a31ea6
                    if token[0] == "sep" and token[1] == ";":
Packit Service a31ea6
                        d = self.mergeFunctionComment(self.name,
Packit Service a31ea6
                                ((type, None), self.signature), 1)
Packit Service a31ea6
                        self.index_add(self.name, self.filename, static,
Packit Service a31ea6
                                        "function", d)
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
                    elif token[0] == "sep" and token[1] == "{":
Packit Service a31ea6
                        d = self.mergeFunctionComment(self.name,
Packit Service a31ea6
                                ((type, None), self.signature), static)
Packit Service a31ea6
                        self.index_add(self.name, self.filename, static,
Packit Service a31ea6
                                        "function", d)
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
                        token = self.parseBlock(token);
Packit Service a31ea6
                elif token[1] == ',':
Packit Service a31ea6
                    self.comment = None
Packit Service a31ea6
                    self.index_add(self.name, self.filename, static,
Packit Service a31ea6
                                    "variable", type)
Packit Service a31ea6
                    type = type_orig
Packit Service a31ea6
                    token = self.token()
Packit Service a31ea6
                    while token != None and token[0] == "sep":
Packit Service a31ea6
                        type = type + token[1]
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
                    if token != None and token[0] == "name":
Packit Service a31ea6
                        self.name = token[1]
Packit Service a31ea6
                        token = self.token()
Packit Service a31ea6
                else:
Packit Service a31ea6
                    break
Packit Service a31ea6
Packit Service a31ea6
        return token
Packit Service a31ea6
Packit Service a31ea6
    def parse(self):
Packit Service a31ea6
        self.warning("Parsing %s" % (self.filename))
Packit Service a31ea6
        token = self.token()
Packit Service a31ea6
        while token != None:
Packit Service a31ea6
            if token[0] == 'name':
Packit Service a31ea6
                token = self.parseGlobal(token)
Packit Service a31ea6
            else:
Packit Service a31ea6
                self.error("token %s %s unexpected at the top level" % (
Packit Service a31ea6
                       token[0], token[1]))
Packit Service a31ea6
                token = self.parseGlobal(token)
Packit Service a31ea6
                return
Packit Service a31ea6
        self.parseTopComment(self.top_comment)
Packit Service a31ea6
        return self.index
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
class docBuilder:
Packit Service a31ea6
    """A documentation builder"""
Packit Service a31ea6
    def __init__(self, name, directories=['.'], excludes=[]):
Packit Service a31ea6
        self.name = name
Packit Service a31ea6
        self.directories = directories
Packit Service a31ea6
        self.excludes = excludes + list(ignored_files.keys())
Packit Service a31ea6
        self.modules = {}
Packit Service a31ea6
        self.headers = {}
Packit Service a31ea6
        self.idx = index()
Packit Service a31ea6
        self.xref = {}
Packit Service a31ea6
        self.index = {}
Packit Service a31ea6
        if name == 'libxml2':
Packit Service a31ea6
            self.basename = 'libxml'
Packit Service a31ea6
        else:
Packit Service a31ea6
            self.basename = name
Packit Service a31ea6
Packit Service a31ea6
    def indexString(self, id, str):
Packit Service a31ea6
        if str == None:
Packit Service a31ea6
            return
Packit Service a31ea6
        str = str.replace("'", ' ')
Packit Service a31ea6
        str = str.replace('"', ' ')
Packit Service a31ea6
        str = str.replace("/", ' ')
Packit Service a31ea6
        str = str.replace('*', ' ')
Packit Service a31ea6
        str = str.replace("[", ' ')
Packit Service a31ea6
        str = str.replace("]", ' ')
Packit Service a31ea6
        str = str.replace("(", ' ')
Packit Service a31ea6
        str = str.replace(")", ' ')
Packit Service a31ea6
        str = str.replace("<", ' ')
Packit Service a31ea6
        str = str.replace('>', ' ')
Packit Service a31ea6
        str = str.replace("&", ' ')
Packit Service a31ea6
        str = str.replace('#', ' ')
Packit Service a31ea6
        str = str.replace(",", ' ')
Packit Service a31ea6
        str = str.replace('.', ' ')
Packit Service a31ea6
        str = str.replace(';', ' ')
Packit Service a31ea6
        tokens = str.split()
Packit Service a31ea6
        for token in tokens:
Packit Service a31ea6
            try:
Packit Service a31ea6
                c = token[0]
Packit Service a31ea6
                if string.ascii_letters.find(c) < 0:
Packit Service a31ea6
                    pass
Packit Service a31ea6
                elif len(token) < 3:
Packit Service a31ea6
                    pass
Packit Service a31ea6
                else:
Packit Service a31ea6
                    lower = token.lower()
Packit Service a31ea6
                    # TODO: generalize this a bit
Packit Service a31ea6
                    if lower == 'and' or lower == 'the':
Packit Service a31ea6
                        pass
Packit Service a31ea6
                    elif token in self.xref:
Packit Service a31ea6
                        self.xref[token].append(id)
Packit Service a31ea6
                    else:
Packit Service a31ea6
                        self.xref[token] = [id]
Packit Service a31ea6
            except:
Packit Service a31ea6
                pass
Packit Service a31ea6
Packit Service a31ea6
    def analyze(self):
Packit Service a31ea6
        print("Project %s : %d headers, %d modules" % (self.name, len(list(self.headers.keys())), len(list(self.modules.keys()))))
Packit Service a31ea6
        self.idx.analyze()
Packit Service a31ea6
Packit Service a31ea6
    def scanHeaders(self):
Packit Service a31ea6
        for header in list(self.headers.keys()):
Packit Service a31ea6
            parser = CParser(header)
Packit Service a31ea6
            idx = parser.parse()
Packit Service a31ea6
            self.headers[header] = idx;
Packit Service a31ea6
            self.idx.merge(idx)
Packit Service a31ea6
Packit Service a31ea6
    def scanModules(self):
Packit Service a31ea6
        for module in list(self.modules.keys()):
Packit Service a31ea6
            parser = CParser(module)
Packit Service a31ea6
            idx = parser.parse()
Packit Service a31ea6
            # idx.analyze()
Packit Service a31ea6
            self.modules[module] = idx
Packit Service a31ea6
            self.idx.merge_public(idx)
Packit Service a31ea6
Packit Service a31ea6
    def scan(self):
Packit Service a31ea6
        for directory in self.directories:
Packit Service a31ea6
            files = glob.glob(directory + "/*.c")
Packit Service a31ea6
            for file in files:
Packit Service a31ea6
                skip = 0
Packit Service a31ea6
                for excl in self.excludes:
Packit Service a31ea6
                    if file.find(excl) != -1:
Packit Service a31ea6
                        print("Skipping %s" % file)
Packit Service a31ea6
                        skip = 1
Packit Service a31ea6
                        break
Packit Service a31ea6
                if skip == 0:
Packit Service a31ea6
                    self.modules[file] = None;
Packit Service a31ea6
            files = glob.glob(directory + "/*.h")
Packit Service a31ea6
            for file in files:
Packit Service a31ea6
                skip = 0
Packit Service a31ea6
                for excl in self.excludes:
Packit Service a31ea6
                    if file.find(excl) != -1:
Packit Service a31ea6
                        print("Skipping %s" % file)
Packit Service a31ea6
                        skip = 1
Packit Service a31ea6
                        break
Packit Service a31ea6
                if skip == 0:
Packit Service a31ea6
                    self.headers[file] = None;
Packit Service a31ea6
        self.scanHeaders()
Packit Service a31ea6
        self.scanModules()
Packit Service a31ea6
Packit Service a31ea6
    def modulename_file(self, file):
Packit Service a31ea6
        module = os.path.basename(file)
Packit Service a31ea6
        if module[-2:] == '.h':
Packit Service a31ea6
            module = module[:-2]
Packit Service a31ea6
        elif module[-2:] == '.c':
Packit Service a31ea6
            module = module[:-2]
Packit Service a31ea6
        return module
Packit Service a31ea6
Packit Service a31ea6
    def serialize_enum(self, output, name):
Packit Service a31ea6
        id = self.idx.enums[name]
Packit Service a31ea6
        output.write("    
Packit Service a31ea6
                     self.modulename_file(id.header)))
Packit Service a31ea6
        if id.info != None:
Packit Service a31ea6
            info = id.info
Packit Service a31ea6
            if info[0] != None and info[0] != '':
Packit Service a31ea6
                try:
Packit Service a31ea6
                    val = eval(info[0])
Packit Service a31ea6
                except:
Packit Service a31ea6
                    val = info[0]
Packit Service a31ea6
                output.write(" value='%s'" % (val));
Packit Service a31ea6
            if info[2] != None and info[2] != '':
Packit Service a31ea6
                output.write(" type='%s'" % info[2]);
Packit Service a31ea6
            if info[1] != None and info[1] != '':
Packit Service a31ea6
                output.write(" info='%s'" % escape(info[1]));
Packit Service a31ea6
        output.write("/>\n")
Packit Service a31ea6
Packit Service a31ea6
    def serialize_macro(self, output, name):
Packit Service a31ea6
        id = self.idx.macros[name]
Packit Service a31ea6
        output.write("    <macro name='%s' file='%s'>\n" % (name,
Packit Service a31ea6
                     self.modulename_file(id.header)))
Packit Service a31ea6
        if id.info != None:
Packit Service a31ea6
            try:
Packit Service a31ea6
                (args, desc) = id.info
Packit Service a31ea6
                if desc != None and desc != "":
Packit Service a31ea6
                    output.write("      <info>%s</info>\n" % (escape(desc)))
Packit Service a31ea6
                    self.indexString(name, desc)
Packit Service a31ea6
                for arg in args:
Packit Service a31ea6
                    (name, desc) = arg
Packit Service a31ea6
                    if desc != None and desc != "":
Packit Service a31ea6
                        output.write("      <arg name='%s' info='%s'/>\n" % (
Packit Service a31ea6
                                     name, escape(desc)))
Packit Service a31ea6
                        self.indexString(name, desc)
Packit Service a31ea6
                    else:
Packit Service a31ea6
                        output.write("      <arg name='%s'/>\n" % (name))
Packit Service a31ea6
            except:
Packit Service a31ea6
                pass
Packit Service a31ea6
        output.write("    </macro>\n")
Packit Service a31ea6
Packit Service a31ea6
    def serialize_typedef(self, output, name):
Packit Service a31ea6
        id = self.idx.typedefs[name]
Packit Service a31ea6
        if id.info[0:7] == 'struct ':
Packit Service a31ea6
            output.write("    
Packit Service a31ea6
                     name, self.modulename_file(id.header), id.info))
Packit Service a31ea6
            name = id.info[7:]
Packit Service a31ea6
            if name in self.idx.structs and ( \
Packit Service a31ea6
               type(self.idx.structs[name].info) == type(()) or
Packit Service a31ea6
                type(self.idx.structs[name].info) == type([])):
Packit Service a31ea6
                output.write(">\n");
Packit Service a31ea6
                try:
Packit Service a31ea6
                    for field in self.idx.structs[name].info:
Packit Service a31ea6
                        desc = field[2]
Packit Service a31ea6
                        self.indexString(name, desc)
Packit Service a31ea6
                        if desc == None:
Packit Service a31ea6
                            desc = ''
Packit Service a31ea6
                        else:
Packit Service a31ea6
                            desc = escape(desc)
Packit Service a31ea6
                        output.write("      <field name='%s' type='%s' info='%s'/>\n" % (field[1] , field[0], desc))
Packit Service a31ea6
                except:
Packit Service a31ea6
                    print("Failed to serialize struct %s" % (name))
Packit Service a31ea6
                output.write("    </struct>\n")
Packit Service a31ea6
            else:
Packit Service a31ea6
                output.write("/>\n");
Packit Service a31ea6
        else :
Packit Service a31ea6
            output.write("    
Packit Service a31ea6
                         name, self.modulename_file(id.header), id.info))
Packit Service a31ea6
            try:
Packit Service a31ea6
                desc = id.extra
Packit Service a31ea6
                if desc != None and desc != "":
Packit Service a31ea6
                    output.write(">\n      <info>%s</info>\n" % (escape(desc)))
Packit Service a31ea6
                    output.write("    </typedef>\n")
Packit Service a31ea6
                else:
Packit Service a31ea6
                    output.write("/>\n")
Packit Service a31ea6
            except:
Packit Service a31ea6
                output.write("/>\n")
Packit Service a31ea6
Packit Service a31ea6
    def serialize_variable(self, output, name):
Packit Service a31ea6
        id = self.idx.variables[name]
Packit Service a31ea6
        if id.info != None:
Packit Service a31ea6
            output.write("    <variable name='%s' file='%s' type='%s'/>\n" % (
Packit Service a31ea6
                    name, self.modulename_file(id.header), id.info))
Packit Service a31ea6
        else:
Packit Service a31ea6
            output.write("    <variable name='%s' file='%s'/>\n" % (
Packit Service a31ea6
                    name, self.modulename_file(id.header)))
Packit Service a31ea6
Packit Service a31ea6
    def serialize_function(self, output, name):
Packit Service a31ea6
        id = self.idx.functions[name]
Packit Service a31ea6
        if name == debugsym:
Packit Service a31ea6
            print("=>", id)
Packit Service a31ea6
Packit Service a31ea6
        output.write("    <%s name='%s' file='%s' module='%s'>\n" % (id.type,
Packit Service a31ea6
                     name, self.modulename_file(id.header),
Packit Service a31ea6
                     self.modulename_file(id.module)))
Packit Service a31ea6
        #
Packit Service a31ea6
        # Processing of conditionals modified by Bill 1/1/05
Packit Service a31ea6
        #
Packit Service a31ea6
        if id.conditionals != None:
Packit Service a31ea6
            apstr = ""
Packit Service a31ea6
            for cond in id.conditionals:
Packit Service a31ea6
                if apstr != "":
Packit Service a31ea6
                    apstr = apstr + " && "
Packit Service a31ea6
                apstr = apstr + cond
Packit Service a31ea6
            output.write("      <cond>%s</cond>\n"% (apstr));
Packit Service a31ea6
        try:
Packit Service a31ea6
            (ret, params, desc) = id.info
Packit Service a31ea6
            if (desc == None or desc == '') and \
Packit Service a31ea6
               name[0:9] != "xmlThrDef" and name != "xmlDllMain":
Packit Service a31ea6
                print("%s %s from %s has no description" % (id.type, name,
Packit Service a31ea6
                       self.modulename_file(id.module)))
Packit Service a31ea6
Packit Service a31ea6
            output.write("      <info>%s</info>\n" % (escape(desc)))
Packit Service a31ea6
            self.indexString(name, desc)
Packit Service a31ea6
            if ret[0] != None:
Packit Service a31ea6
                if ret[0] == "void":
Packit Service a31ea6
                    output.write("      <return type='void'/>\n")
Packit Service a31ea6
                else:
Packit Service a31ea6
                    output.write("      <return type='%s' info='%s'/>\n" % (
Packit Service a31ea6
                             ret[0], escape(ret[1])))
Packit Service a31ea6
                    self.indexString(name, ret[1])
Packit Service a31ea6
            for param in params:
Packit Service a31ea6
                if param[0] == 'void':
Packit Service a31ea6
                    continue
Packit Service a31ea6
                if param[2] == None:
Packit Service a31ea6
                    output.write("      <arg name='%s' type='%s' info=''/>\n" % (param[1], param[0]))
Packit Service a31ea6
                else:
Packit Service a31ea6
                    output.write("      <arg name='%s' type='%s' info='%s'/>\n" % (param[1], param[0], escape(param[2])))
Packit Service a31ea6
                    self.indexString(name, param[2])
Packit Service a31ea6
        except:
Packit Service a31ea6
            print("Failed to save function %s info: " % name, repr(id.info))
Packit Service a31ea6
        output.write("    </%s>\n" % (id.type))
Packit Service a31ea6
Packit Service a31ea6
    def serialize_exports(self, output, file):
Packit Service a31ea6
        module = self.modulename_file(file)
Packit Service a31ea6
        output.write("    <file name='%s'>\n" % (module))
Packit Service a31ea6
        dict = self.headers[file]
Packit Service a31ea6
        if dict.info != None:
Packit Service a31ea6
            for data in ('Summary', 'Description', 'Author'):
Packit Service a31ea6
                try:
Packit Service a31ea6
                    output.write("     <%s>%s</%s>\n" % (
Packit Service a31ea6
                                 data.lower(),
Packit Service a31ea6
                                 escape(dict.info[data]),
Packit Service a31ea6
                                 data.lower()))
Packit Service a31ea6
                except:
Packit Service a31ea6
                    print("Header %s lacks a %s description" % (module, data))
Packit Service a31ea6
            if 'Description' in dict.info:
Packit Service a31ea6
                desc = dict.info['Description']
Packit Service a31ea6
                if desc.find("DEPRECATED") != -1:
Packit Service a31ea6
                    output.write("     <deprecated/>\n")
Packit Service a31ea6
Packit Service a31ea6
        ids = list(dict.macros.keys())
Packit Service a31ea6
        ids.sort()
Packit Service a31ea6
        for id in uniq(ids):
Packit Service a31ea6
            # Macros are sometime used to masquerade other types.
Packit Service a31ea6
            if id in dict.functions:
Packit Service a31ea6
                continue
Packit Service a31ea6
            if id in dict.variables:
Packit Service a31ea6
                continue
Packit Service a31ea6
            if id in dict.typedefs:
Packit Service a31ea6
                continue
Packit Service a31ea6
            if id in dict.structs:
Packit Service a31ea6
                continue
Packit Service a31ea6
            if id in dict.enums:
Packit Service a31ea6
                continue
Packit Service a31ea6
            output.write("     <exports symbol='%s' type='macro'/>\n" % (id))
Packit Service a31ea6
        ids = list(dict.enums.keys())
Packit Service a31ea6
        ids.sort()
Packit Service a31ea6
        for id in uniq(ids):
Packit Service a31ea6
            output.write("     <exports symbol='%s' type='enum'/>\n" % (id))
Packit Service a31ea6
        ids = list(dict.typedefs.keys())
Packit Service a31ea6
        ids.sort()
Packit Service a31ea6
        for id in uniq(ids):
Packit Service a31ea6
            output.write("     <exports symbol='%s' type='typedef'/>\n" % (id))
Packit Service a31ea6
        ids = list(dict.structs.keys())
Packit Service a31ea6
        ids.sort()
Packit Service a31ea6
        for id in uniq(ids):
Packit Service a31ea6
            output.write("     <exports symbol='%s' type='struct'/>\n" % (id))
Packit Service a31ea6
        ids = list(dict.variables.keys())
Packit Service a31ea6
        ids.sort()
Packit Service a31ea6
        for id in uniq(ids):
Packit Service a31ea6
            output.write("     <exports symbol='%s' type='variable'/>\n" % (id))
Packit Service a31ea6
        ids = list(dict.functions.keys())
Packit Service a31ea6
        ids.sort()
Packit Service a31ea6
        for id in uniq(ids):
Packit Service a31ea6
            output.write("     <exports symbol='%s' type='function'/>\n" % (id))
Packit Service a31ea6
        output.write("    </file>\n")
Packit Service a31ea6
Packit Service a31ea6
    def serialize_xrefs_files(self, output):
Packit Service a31ea6
        headers = list(self.headers.keys())
Packit Service a31ea6
        headers.sort()
Packit Service a31ea6
        for file in headers:
Packit Service a31ea6
            module = self.modulename_file(file)
Packit Service a31ea6
            output.write("    <file name='%s'>\n" % (module))
Packit Service a31ea6
            dict = self.headers[file]
Packit Service a31ea6
            ids = uniq(list(dict.functions.keys()) + list(dict.variables.keys()) + \
Packit Service a31ea6
                  list(dict.macros.keys()) + list(dict.typedefs.keys()) + \
Packit Service a31ea6
                  list(dict.structs.keys()) + list(dict.enums.keys()))
Packit Service a31ea6
            ids.sort()
Packit Service a31ea6
            for id in ids:
Packit Service a31ea6
                output.write("      <ref name='%s'/>\n" % (id))
Packit Service a31ea6
            output.write("    </file>\n")
Packit Service a31ea6
        pass
Packit Service a31ea6
Packit Service a31ea6
    def serialize_xrefs_functions(self, output):
Packit Service a31ea6
        funcs = {}
Packit Service a31ea6
        for name in list(self.idx.functions.keys()):
Packit Service a31ea6
            id = self.idx.functions[name]
Packit Service a31ea6
            try:
Packit Service a31ea6
                (ret, params, desc) = id.info
Packit Service a31ea6
                for param in params:
Packit Service a31ea6
                    if param[0] == 'void':
Packit Service a31ea6
                        continue
Packit Service a31ea6
                    if param[0] in funcs:
Packit Service a31ea6
                        funcs[param[0]].append(name)
Packit Service a31ea6
                    else:
Packit Service a31ea6
                        funcs[param[0]] = [name]
Packit Service a31ea6
            except:
Packit Service a31ea6
                pass
Packit Service a31ea6
        typ = list(funcs.keys())
Packit Service a31ea6
        typ.sort()
Packit Service a31ea6
        for type in typ:
Packit Service a31ea6
            if type == '' or type == 'void' or type == "int" or \
Packit Service a31ea6
               type == "char *" or type == "const char *" :
Packit Service a31ea6
                continue
Packit Service a31ea6
            output.write("    <type name='%s'>\n" % (type))
Packit Service a31ea6
            ids = funcs[type]
Packit Service a31ea6
            ids.sort()
Packit Service a31ea6
            pid = ''        # not sure why we have dups, but get rid of them!
Packit Service a31ea6
            for id in ids:
Packit Service a31ea6
                if id != pid:
Packit Service a31ea6
                    output.write("      <ref name='%s'/>\n" % (id))
Packit Service a31ea6
                    pid = id
Packit Service a31ea6
            output.write("    </type>\n")
Packit Service a31ea6
Packit Service a31ea6
    def serialize_xrefs_constructors(self, output):
Packit Service a31ea6
        funcs = {}
Packit Service a31ea6
        for name in list(self.idx.functions.keys()):
Packit Service a31ea6
            id = self.idx.functions[name]
Packit Service a31ea6
            try:
Packit Service a31ea6
                (ret, params, desc) = id.info
Packit Service a31ea6
                if ret[0] == "void":
Packit Service a31ea6
                    continue
Packit Service a31ea6
                if ret[0] in funcs:
Packit Service a31ea6
                    funcs[ret[0]].append(name)
Packit Service a31ea6
                else:
Packit Service a31ea6
                    funcs[ret[0]] = [name]
Packit Service a31ea6
            except:
Packit Service a31ea6
                pass
Packit Service a31ea6
        typ = list(funcs.keys())
Packit Service a31ea6
        typ.sort()
Packit Service a31ea6
        for type in typ:
Packit Service a31ea6
            if type == '' or type == 'void' or type == "int" or \
Packit Service a31ea6
               type == "char *" or type == "const char *" :
Packit Service a31ea6
                continue
Packit Service a31ea6
            output.write("    <type name='%s'>\n" % (type))
Packit Service a31ea6
            ids = funcs[type]
Packit Service a31ea6
            ids.sort()
Packit Service a31ea6
            for id in ids:
Packit Service a31ea6
                output.write("      <ref name='%s'/>\n" % (id))
Packit Service a31ea6
            output.write("    </type>\n")
Packit Service a31ea6
Packit Service a31ea6
    def serialize_xrefs_alpha(self, output):
Packit Service a31ea6
        letter = None
Packit Service a31ea6
        ids = list(self.idx.identifiers.keys())
Packit Service a31ea6
        ids.sort()
Packit Service a31ea6
        for id in ids:
Packit Service a31ea6
            if id[0] != letter:
Packit Service a31ea6
                if letter != None:
Packit Service a31ea6
                    output.write("    </letter>\n")
Packit Service a31ea6
                letter = id[0]
Packit Service a31ea6
                output.write("    <letter name='%s'>\n" % (letter))
Packit Service a31ea6
            output.write("      <ref name='%s'/>\n" % (id))
Packit Service a31ea6
        if letter != None:
Packit Service a31ea6
            output.write("    </letter>\n")
Packit Service a31ea6
Packit Service a31ea6
    def serialize_xrefs_references(self, output):
Packit Service a31ea6
        typ = list(self.idx.identifiers.keys())
Packit Service a31ea6
        typ.sort()
Packit Service a31ea6
        for id in typ:
Packit Service a31ea6
            idf = self.idx.identifiers[id]
Packit Service a31ea6
            module = idf.header
Packit Service a31ea6
            output.write("    <reference name='%s' href='%s'/>\n" % (id,
Packit Service a31ea6
                         'html/' + self.basename + '-' +
Packit Service a31ea6
                         self.modulename_file(module) + '.html#' +
Packit Service a31ea6
                         id))
Packit Service a31ea6
Packit Service a31ea6
    def serialize_xrefs_index(self, output):
Packit Service a31ea6
        index = self.xref
Packit Service a31ea6
        typ = list(index.keys())
Packit Service a31ea6
        typ.sort()
Packit Service a31ea6
        letter = None
Packit Service a31ea6
        count = 0
Packit Service a31ea6
        chunk = 0
Packit Service a31ea6
        chunks = []
Packit Service a31ea6
        for id in typ:
Packit Service a31ea6
            if len(index[id]) > 30:
Packit Service a31ea6
                continue
Packit Service a31ea6
            if id[0] != letter:
Packit Service a31ea6
                if letter == None or count > 200:
Packit Service a31ea6
                    if letter != None:
Packit Service a31ea6
                        output.write("      </letter>\n")
Packit Service a31ea6
                        output.write("    </chunk>\n")
Packit Service a31ea6
                        count = 0
Packit Service a31ea6
                        chunks.append(["chunk%s" % (chunk -1), first_letter, letter])
Packit Service a31ea6
                    output.write("    <chunk name='chunk%s'>\n" % (chunk))
Packit Service a31ea6
                    first_letter = id[0]
Packit Service a31ea6
                    chunk = chunk + 1
Packit Service a31ea6
                elif letter != None:
Packit Service a31ea6
                    output.write("      </letter>\n")
Packit Service a31ea6
                letter = id[0]
Packit Service a31ea6
                output.write("      <letter name='%s'>\n" % (letter))
Packit Service a31ea6
            output.write("        <word name='%s'>\n" % (id))
Packit Service a31ea6
            tokens = index[id];
Packit Service a31ea6
            tokens.sort()
Packit Service a31ea6
            tok = None
Packit Service a31ea6
            for token in tokens:
Packit Service a31ea6
                if tok == token:
Packit Service a31ea6
                    continue
Packit Service a31ea6
                tok = token
Packit Service a31ea6
                output.write("          <ref name='%s'/>\n" % (token))
Packit Service a31ea6
                count = count + 1
Packit Service a31ea6
            output.write("        </word>\n")
Packit Service a31ea6
        if letter != None:
Packit Service a31ea6
            output.write("      </letter>\n")
Packit Service a31ea6
            output.write("    </chunk>\n")
Packit Service a31ea6
            if count != 0:
Packit Service a31ea6
                chunks.append(["chunk%s" % (chunk -1), first_letter, letter])
Packit Service a31ea6
            output.write("    <chunks>\n")
Packit Service a31ea6
            for ch in chunks:
Packit Service a31ea6
                output.write("      <chunk name='%s' start='%s' end='%s'/>\n" % (
Packit Service a31ea6
                             ch[0], ch[1], ch[2]))
Packit Service a31ea6
            output.write("    </chunks>\n")
Packit Service a31ea6
Packit Service a31ea6
    def serialize_xrefs(self, output):
Packit Service a31ea6
        output.write("  <references>\n")
Packit Service a31ea6
        self.serialize_xrefs_references(output)
Packit Service a31ea6
        output.write("  </references>\n")
Packit Service a31ea6
        output.write("  <alpha>\n")
Packit Service a31ea6
        self.serialize_xrefs_alpha(output)
Packit Service a31ea6
        output.write("  </alpha>\n")
Packit Service a31ea6
        output.write("  <constructors>\n")
Packit Service a31ea6
        self.serialize_xrefs_constructors(output)
Packit Service a31ea6
        output.write("  </constructors>\n")
Packit Service a31ea6
        output.write("  <functions>\n")
Packit Service a31ea6
        self.serialize_xrefs_functions(output)
Packit Service a31ea6
        output.write("  </functions>\n")
Packit Service a31ea6
        output.write("  <files>\n")
Packit Service a31ea6
        self.serialize_xrefs_files(output)
Packit Service a31ea6
        output.write("  </files>\n")
Packit Service a31ea6
        output.write("  <index>\n")
Packit Service a31ea6
        self.serialize_xrefs_index(output)
Packit Service a31ea6
        output.write("  </index>\n")
Packit Service a31ea6
Packit Service a31ea6
    def serialize(self):
Packit Service a31ea6
        filename = "%s-api.xml" % self.name
Packit Service a31ea6
        print("Saving XML description %s" % (filename))
Packit Service a31ea6
        output = open(filename, "w")
Packit Service a31ea6
        output.write('\n')
Packit Service a31ea6
        output.write("<api name='%s'>\n" % self.name)
Packit Service a31ea6
        output.write("  <files>\n")
Packit Service a31ea6
        headers = list(self.headers.keys())
Packit Service a31ea6
        headers.sort()
Packit Service a31ea6
        for file in headers:
Packit Service a31ea6
            self.serialize_exports(output, file)
Packit Service a31ea6
        output.write("  </files>\n")
Packit Service a31ea6
        output.write("  <symbols>\n")
Packit Service a31ea6
        macros = list(self.idx.macros.keys())
Packit Service a31ea6
        macros.sort()
Packit Service a31ea6
        for macro in macros:
Packit Service a31ea6
            self.serialize_macro(output, macro)
Packit Service a31ea6
        enums = list(self.idx.enums.keys())
Packit Service a31ea6
        enums.sort()
Packit Service a31ea6
        for enum in enums:
Packit Service a31ea6
            self.serialize_enum(output, enum)
Packit Service a31ea6
        typedefs = list(self.idx.typedefs.keys())
Packit Service a31ea6
        typedefs.sort()
Packit Service a31ea6
        for typedef in typedefs:
Packit Service a31ea6
            self.serialize_typedef(output, typedef)
Packit Service a31ea6
        variables = list(self.idx.variables.keys())
Packit Service a31ea6
        variables.sort()
Packit Service a31ea6
        for variable in variables:
Packit Service a31ea6
            self.serialize_variable(output, variable)
Packit Service a31ea6
        functions = list(self.idx.functions.keys())
Packit Service a31ea6
        functions.sort()
Packit Service a31ea6
        for function in functions:
Packit Service a31ea6
            self.serialize_function(output, function)
Packit Service a31ea6
        output.write("  </symbols>\n")
Packit Service a31ea6
        output.write("</api>\n")
Packit Service a31ea6
        output.close()
Packit Service a31ea6
Packit Service a31ea6
        filename = "%s-refs.xml" % self.name
Packit Service a31ea6
        print("Saving XML Cross References %s" % (filename))
Packit Service a31ea6
        output = open(filename, "w")
Packit Service a31ea6
        output.write('\n')
Packit Service a31ea6
        output.write("<apirefs name='%s'>\n" % self.name)
Packit Service a31ea6
        self.serialize_xrefs(output)
Packit Service a31ea6
        output.write("</apirefs>\n")
Packit Service a31ea6
        output.close()
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
def rebuild():
Packit Service a31ea6
    builder = None
Packit Service a31ea6
    if glob.glob("parser.c") != [] :
Packit Service a31ea6
        print("Rebuilding API description for libxml2")
Packit Service a31ea6
        builder = docBuilder("libxml2", [".", "."],
Packit Service a31ea6
                             ["xmlwin32version.h", "tst.c"])
Packit Service a31ea6
    elif glob.glob("../parser.c") != [] :
Packit Service a31ea6
        print("Rebuilding API description for libxml2")
Packit Service a31ea6
        builder = docBuilder("libxml2", ["..", "../include/libxml"],
Packit Service a31ea6
                             ["xmlwin32version.h", "tst.c"])
Packit Service a31ea6
    elif glob.glob("../libxslt/transform.c") != [] :
Packit Service a31ea6
        print("Rebuilding API description for libxslt")
Packit Service a31ea6
        builder = docBuilder("libxslt", ["../libxslt"],
Packit Service a31ea6
                             ["win32config.h", "libxslt.h", "tst.c"])
Packit Service a31ea6
    else:
Packit Service a31ea6
        print("rebuild() failed, unable to guess the module")
Packit Service a31ea6
        return None
Packit Service a31ea6
    builder.scan()
Packit Service a31ea6
    builder.analyze()
Packit Service a31ea6
    builder.serialize()
Packit Service a31ea6
    if glob.glob("../libexslt/exslt.c") != [] :
Packit Service a31ea6
        extra = docBuilder("libexslt", ["../libexslt"], ["libexslt.h"])
Packit Service a31ea6
        extra.scan()
Packit Service a31ea6
        extra.analyze()
Packit Service a31ea6
        extra.serialize()
Packit Service a31ea6
    return builder
Packit Service a31ea6
Packit Service a31ea6
#
Packit Service a31ea6
# for debugging the parser
Packit Service a31ea6
#
Packit Service a31ea6
def parse(filename):
Packit Service a31ea6
    parser = CParser(filename)
Packit Service a31ea6
    idx = parser.parse()
Packit Service a31ea6
    return idx
Packit Service a31ea6
Packit Service a31ea6
if __name__ == "__main__":
Packit Service a31ea6
    if len(sys.argv) > 1:
Packit Service a31ea6
        debug = 1
Packit Service a31ea6
        parse(sys.argv[1])
Packit Service a31ea6
    else:
Packit Service a31ea6
        rebuild()