Mercurial > pidgin
diff src/dbus-analyze-functions.py @ 11146:1c5398ccbeb0
[gaim-migrate @ 13217]
Gaim-DBUS signal export works with DBUS >= 0.35
Various gaim API functions available through DBUS
committer: Tailor Script <tailor@pidgin.im>
author | Piotr Zielinski <zielaj> |
---|---|
date | Fri, 22 Jul 2005 19:47:29 +0000 |
parents | |
children | ebb02ea3c789 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dbus-analyze-functions.py Fri Jul 22 19:47:29 2005 +0000 @@ -0,0 +1,292 @@ +# This programs takes a C header file as the input and produces: +# +# with option --mode=xml: xml dbus specification +# with option --mode=c: C wrappers +# + + + +import re +import string +import sys + +# mode: "c" or "xml" + +mode = None + +for arg in sys.argv[1:]: + if arg.startswith("--mode="): + mode = arg[len("--mode="):] + +# list of object types + +objecttypes = [] + +for objecttype in file("dbus-auto-structs.txt"): + objecttypes.append(objecttype.strip()) + +# a dictionary of simple types +# each TYPE maps into a pair (dbus-type-name, compatible-c-type-name) +# if compatible-c-type-name is None then it is the same as TYPE + +simpletypes = { + "int" : ("i", None), + "gint" : ("i", None), + "guint" : ("u", None), + "gboolean" : ("i", "int") + } + +for enum in file("dbus-auto-enums.txt"): + simpletypes[enum.strip()] = ("i", "int") + +# functions that shouldn't be exported + +excluded = ["gaim_accounts_load", "gaim_account_set_presence"] + +pointer = "#pointer#" +prefix = "gaim_object_" + +cparams = [] +cdecls = [] +ccode = [] +dargs = [] + +myexception = "My Exception" + + +def ctopascal(name): + newname = "" + for word in name.split("_"): + newname += word.capitalize() + return newname + +def dbus_print(function): + print '<method name="%s">' % ctopascal(function) + + for name, type, direction in dargs: + print '<arg type="%s" name="%s" direction="%s" />' % \ + (type, name, direction) + + print '</method>' + print + +def dbus_clear(): + global dargs + dargs = [] + +def c_print(function): + print "static gboolean %s%s(GaimObject *gaim_object," % (prefix, function), + + for param in cparams: + print "%s," % param, + + print "GError **error) {" + + for decl in cdecls: + print decl + + for code in ccode: + print code + + print "return TRUE;\n}\n" + +def c_clear(): + global cparams, cdecls, ccode + cparams = [] + cdecls = [] + ccode = [] + + +# processing an input parameter + +def inputvar(mytype, name): + global dargs, ccode, cparams, cdecls + const = False + if mytype[0] == "const": + mytype = mytype[1:] + const = True + + # simple types (int, gboolean, etc.) and enums + if (len(mytype) == 1) and (mytype[0] in simpletypes): + dbustype, ctype = simpletypes[mytype[0]] + dargs.append((name, dbustype, "in")) + if ctype is None: + cparams.append(mytype[0] + " " + name) + else: + cparams.append(ctype + " " + name + "_ORIG") + cdecls .append("%s %s;\n" % (mytype[0], name)) + ccode .append("%s = (%s) %s_ORIG;\n" % \ + (name, mytype[0], name)) + return + + # pointers ... + + if (len(mytype) == 2) and (mytype[1] == pointer): + # strings + if mytype[0] == "char": + if const: + dargs .append((name, "s", "in")) + cparams.append("const char *" + name) + ccode .append("NULLIFY(%s);" % name) + return + else: + raise myexception + + # known object types are transformed to integer handles + elif mytype[0] in objecttypes: + dargs .append((name, "i", "in")) + cparams.append("int " + name + "_ID") + cdecls .append("%s *%s;" % (mytype[0], name)) + ccode .append("GAIM_DBUS_ID_TO_POINTER(%s, %s_ID, %s);" % \ + (name, name, mytype[0])) + return + + # unknown pointers are always replaced with NULL + else: + dargs .append((name, "i", "in")) + cparams.append("int " + name + "_NULL") + cdecls .append("%s *%s;" % (mytype[0], name)) + ccode .append("%s = NULL;" % name) + return + + raise myexception + + + +# processing an output parameter + +def outputvar(mytype, name, call): + # the "void" type is simple ... + if mytype == ["void"]: + ccode.append("%s;" % call) # just call the function + return + + # a constant string + if mytype == ["const", "char", pointer]: + dargs .append((name, "s", "out")) + cparams.append("char **%s" % name) + ccode .append("*%s = g_strdup(null_to_empty(%s));" % (name, call)) + return + + # simple types (ints, booleans, enums, ...) + if (len(mytype) == 1) and (mytype[0] in simpletypes): + dbustype, ctype = simpletypes[mytype[0]] + + if ctype is None: + ctype = mytype[0] + + dargs .append((name, dbustype, "out")) + ccode .append("*%s = %s;" % (name, call)) + cparams.append("%s *%s" % (ctype, name)) + return + + # pointers ... + if (len(mytype) == 2) and (mytype[1] == pointer): + + # handles + if mytype[0] in objecttypes: + dargs .append((name, "i", "out")) + cparams.append("int *%s" % name) + ccode .append("GAIM_DBUS_POINTER_TO_ID(*%s, %s);" % (name, call)) + return + + # GList*, GSList*, assume that list is a list of objects + # not a list of strings!!! + if mytype[0] in ["GList", "GSList"]: + dargs .append((name, "ai", "out")) + cparams.append("GArray **%s" % name) + ccode .append("*%s = gaim_dbusify_%s(%s, TRUE);" % \ + (name, mytype[0],call)) + return + + raise myexception + + + +def processfunction(functionparam, paramlist): + dbus_clear() + c_clear() + + ftokens = functionparam.split() + functiontype, function = ftokens[:-1], ftokens[-1] + + if function in excluded: + return + + origfunction = function + function = function.lower() + + names = [] + for param in paramlist: + tokens = param.split() + if len(tokens) < 2: + raise myexception + type, name = tokens[:-1], tokens[-1] + inputvar(type, name) + names.append(name) + + outputvar(functiontype, "RESULT", + "%s(%s)" % (origfunction, ", ".join(names))) + + if mode == "c": + c_print(function) + + if mode == "xml": + dbus_print(function) + + +if mode == "c": + print "/* Generated by %s. Do not edit! */" % sys.argv[0] + +if mode == "xml": + print "<!-- Generated by %s. Do not edit! -->" % sys.argv[0] + +functionregexp = re.compile(r"^(\w[^()]*)\(([^()]*)\)\s*;\s*$") + +inputiter = iter(sys.stdin) + +for line in inputiter: + words = line.split() + if len(words) == 0: # empty line + continue + if line[0] == "#": # preprocessor directive + continue + if words[0] in ["typedef", "struct", "enum", "static"]: + continue + + # accumulate lines until the parentheses are balance or an + # empty line has been encountered + myline = line.strip() + while myline.count("(") > myline.count(")"): + newline = inputiter.next().strip() + if len(newline) == 0: + break + myline += " " + newline + + # is this a function declaration? + thematch = functionregexp.match( + myline.replace("*", " " + pointer + " ")) + + if thematch is None: + continue + + function = thematch.group(1) + parameters = thematch.group(2).strip() + + if (parameters == "void") or (parameters == ""): + paramlist = [] + else: + paramlist = parameters.split(",") + + try: + processfunction(function, paramlist) + except myexception: + sys.stderr.write(myline + "\n") + except: + sys.stderr.write(myline + "\n") + raise + + + + +