#!/usr/bin/python # Raph, 2010, address@hidden # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . from lxml import objectify DIR='/tmp/' NS='org.freedesktop.UDisks' DEVICES=[ 'Device' , 'Adapter', 'Expander', 'Port' ]; xml_type_to_c_type = { 't' : 'guint64 ', #time 'x' : 'guint64 ', 's' : 'gchar *', 'b' : 'gboolean ', 'd' : 'double ', 'u' : 'uid_t ', 'as' : 'char **', 'i' : 'int ', # udisks specific: ao, as char ** ? 'ao' : 'char **', 'ay' : 'char **', 'o' : 'char *' } xml_type_to_glib_func = { 't' : 'g_value_get_uint64', 'x' : 'g_value_get_uint64', 's' : 'g_value_get_string', 'b' : 'g_value_get_boolean', 'd' : 'g_value_get_double', 'u' : 'g_value_get_uint', 'as' : 'g_value_get_boxed', 'i' : 'g_value_get_int ', 'ao' : 'g_value_get_boxed', 'ay' : 'g_value_get_boxed', 'o' : 'g_value_get_boxed' } # header struct which define the Object #TODO: udisks is hardcoded #TODO: name is hardcoded to DeviceProperties (wouldn't Object Attribute be better) header_prop_pre = '#include "udisks-daemon-glue.h"\ntypedef struct {' header_prop_post = """} DeviceProperties;\n static DeviceProperties * device_properties_get (DBusGConnection *bus, const char *object_path); static void device_properties_free (DeviceProperties *props); gboolean collect_props (char *key, GValue *value, DeviceProperties *props);""" # print the string to comparate 2 properties values, according to their type prop_comparator_pre = 'gboolean prop_equal_common(DeviceProperties *a, DeviceProperties *b) {' prop_comparator_post = '\treturn TRUE;\n}' # print the function which set the Attribute value for an Object according to the Attribute name collect_props_pre = """static void collect_props (const char *key, const GValue *value, DeviceProperties *props) {\t \tgboolean handled = TRUE;\n""" collect_props_post = """\n\telse\n\thandled = FALSE; \tif (!handled) \t\tg_warning ("unhandled property '%s'", key);\n}""" # print the function which free an Object free_props_pre = 'static void device_properties_free (DeviceProperties *props) {' free_props_post = '\tg_free (props);\n}' # helper used by collect_props for the 'string' and 'array of strings' cases def collect_prop_type_to_func(atype, middle_str): a = xml_type_to_glib_func[atype] str = '' if a == 'g_value_get_boxed': str = 'g_strdupv (' + a + ' ' + middle_str + ') )' elif a == 'g_value_get_string': str = 'g_strdup (' + a + ' ' + middle_str + ') )' else: str = a + ' ' + middle_str + ')' return str # convert a XMLName to a c_name def XML_name_to_C(aname): alphabet = "abcdefghijklmnopqrstuvwxyz".upper() str = aname[0].lower() i = 1; while i < len(aname): if aname[i] in alphabet: if aname[i-1] not in alphabet: str += '_' str += aname[i].lower() else: str += aname[i] i += 1 return str def do_property_header(node): atype=xml_type_to_c_type[node.get('type')] aname=XML_name_to_C(node.get('name')) print "\t%s%s;" % (atype, aname) def do_collect_props(node): atype=xml_type_to_c_type[node.get('type')] aname=XML_name_to_C(node.get('name')) print '\t', if node.get('type') in [ 'as', 'ao' ]: print """else if (strcmp (key, \"%s\") == 0) { \t\tguint n; \t\tGPtrArray *object_paths;\n \t\tobject_paths = g_value_get_boxed (value);\n \t\tprops->%s = g_new0 (char *, object_paths->len + 1); \t\tfor (n = 0; n < object_paths->len; n++) \t\t\tprops->%s[n] = g_strdup (object_paths->pdata[n]); \t\tprops->%s[n] = NULL; \t}""" % (node.get('name'), aname, aname, aname) elif node.get('type') == 'ay': print 'TODO: blob array to collect' else: print 'else if (strcmp (key, "%s") == 0)' % (node.get('name')) print '\t\tprops->%s = %s;\n' % ( aname, collect_prop_type_to_func(node.get('type'), '(value)') ) def do_free_props(node): aname=XML_name_to_C(node.get('name')) func = 'g_free' if node.get('type') == 't': func = 'g_strfreev' print '\t%s (props->%s);' % (func , aname) def do_prop_comparator(node): aname=XML_name_to_C(node.get('name')) print "\t", if node.get('type') == 'b': print "if ( a->%s && !b->%s )\n\t\treturn FALSE;" % ( aname, aname ) elif node.get('type') in [ 's', 'o' ]: print "if ( a->%s && b->%s && strcmp(a->%s, b->%s) != 0 )\n\t\treturn FALSE;" % (aname, aname, aname, aname) elif node.get('type') in [ 'as', 'ay', 'ao' ]: print 'TODO: compare 2 arrays' else: print "if ( a->%s != 0 && b->%s != 0 && a->%s == b->%s )\n\t\treturn FALSE;" % (aname, aname, aname, aname) tree = objectify.parse(DIR + NS + '.xml') root = tree.getroot().interface for node1 in root.iterchildren(tag='signal'): print node1.tag, "." , node1.get('name'), " : ", node1.arg.get('name') #print "static void device_handler_" , node1.get('name') , " (DBusGProxy *proxy, const char *object_path, gpointer user_data)" > .h #print 'dbus_g_proxy_connect_signal (disks_proxy, "', node1.get('name') , '", G_CALLBACK (device_changed_signal_handler), NULL, NULL);' > .c #print 'dbus_g_proxy_add_signal (disks_proxy, "', node1.get('name'), '", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);' for devit in DEVICES: dev = DIR + NS + '.' + devit + '.xml' treedev = objectify.parse(dev) rootdev = treedev.getroot().interface print header_prop_pre for node in rootdev.iterchildren(tag='property'): do_property_header(node) print header_prop_post print collect_props_pre print '\tTODO: remove 1st "else"' for node in rootdev.iterchildren(tag='property'): do_collect_props(node) print collect_props_post print free_props_pre for node in rootdev.iterchildren(tag='property'): do_free_props(node) print free_props_post print prop_comparator_pre for node in rootdev.iterchildren(tag='property'): do_prop_comparator(node) print prop_comparator_post