File indexing completed on 2024-04-21 05:01:51
0001 #!/usr/bin/python 0002 0003 from sys import argv, stdout, stderr 0004 import xml.dom.minidom 0005 0006 from libtpcodegen import file_set_contents, u 0007 from libglibcodegen import NS_TP, get_docstring, \ 0008 get_descendant_text, get_by_path 0009 0010 class Generator(object): 0011 def __init__(self, prefix, dom, output_base): 0012 self.prefix = prefix + '_' 0013 self.spec = get_by_path(dom, "spec")[0] 0014 0015 self.output_base = output_base 0016 self.__header = [] 0017 self.__docs = [] 0018 0019 def __call__(self): 0020 self.do_header() 0021 self.do_body() 0022 self.do_footer() 0023 0024 file_set_contents(self.output_base + '.h', u('').join(self.__header).encode('utf-8')) 0025 file_set_contents(self.output_base + '-gtk-doc.h', u('').join(self.__docs).encode('utf-8')) 0026 0027 def write(self, code): 0028 self.__header.append(code) 0029 0030 def d(self, code): 0031 self.__docs.append(code) 0032 0033 # Header 0034 def do_header(self): 0035 self.write('/* Generated from ') 0036 self.write(get_descendant_text(get_by_path(self.spec, 'title'))) 0037 version = get_by_path(self.spec, "version") 0038 if version: 0039 self.write(', version ' + get_descendant_text(version)) 0040 self.write('\n\n') 0041 for copyright in get_by_path(self.spec, 'copyright'): 0042 self.write(get_descendant_text(copyright)) 0043 self.write('\n') 0044 self.write(get_descendant_text(get_by_path(self.spec, 'license'))) 0045 self.write('\n') 0046 self.write(get_descendant_text(get_by_path(self.spec, 'docstring'))) 0047 self.write(""" 0048 */ 0049 0050 #ifdef __cplusplus 0051 extern "C" { 0052 #endif 0053 \n""") 0054 0055 # Body 0056 def do_body(self): 0057 for elem in self.spec.getElementsByTagNameNS(NS_TP, '*'): 0058 if elem.localName == 'flags': 0059 self.do_flags(elem) 0060 elif elem.localName == 'enum': 0061 self.do_enum(elem) 0062 0063 def do_flags(self, flags): 0064 name = flags.getAttribute('plural') or flags.getAttribute('name') 0065 value_prefix = flags.getAttribute('singular') or \ 0066 flags.getAttribute('value-prefix') or \ 0067 flags.getAttribute('name') 0068 self.d("""\ 0069 /** 0070 * %s: 0071 """ % (self.prefix + name).replace('_', '')) 0072 for flag in get_by_path(flags, 'flag'): 0073 self.do_gtkdoc(flag, value_prefix) 0074 self.d(' *\n') 0075 docstrings = get_by_path(flags, 'docstring') 0076 if docstrings: 0077 self.d("""\ 0078 * <![CDATA[%s]]> 0079 * 0080 """ % get_descendant_text(docstrings).replace('\n', ' ')) 0081 self.d("""\ 0082 * Bitfield/set of flags generated from the Telepathy specification. 0083 */ 0084 """) 0085 0086 self.write("typedef enum /*< flags >*/ {\n") 0087 0088 for flag in get_by_path(flags, 'flag'): 0089 self.do_val(flag, value_prefix) 0090 self.write("""\ 0091 } %s; 0092 0093 """ % (self.prefix + name).replace('_', '')) 0094 0095 def do_enum(self, enum): 0096 name = enum.getAttribute('singular') or enum.getAttribute('name') 0097 value_prefix = enum.getAttribute('singular') or \ 0098 enum.getAttribute('value-prefix') or \ 0099 enum.getAttribute('name') 0100 name_plural = enum.getAttribute('plural') or \ 0101 enum.getAttribute('name') + 's' 0102 self.d("""\ 0103 /** 0104 * %s: 0105 """ % (self.prefix + name).replace('_', '')) 0106 vals = get_by_path(enum, 'enumvalue') 0107 for val in vals: 0108 self.do_gtkdoc(val, value_prefix) 0109 self.d(' *\n') 0110 docstrings = get_by_path(enum, 'docstring') 0111 if docstrings: 0112 self.d("""\ 0113 * <![CDATA[%s]]> 0114 * 0115 """ % get_descendant_text(docstrings).replace('\n', ' ')) 0116 self.d("""\ 0117 * Bitfield/set of flags generated from the Telepathy specification. 0118 */ 0119 """) 0120 0121 self.write("typedef enum {\n") 0122 0123 for val in vals: 0124 self.do_val(val, value_prefix) 0125 self.write("} %s;\n" % (self.prefix + name).replace('_', '')) 0126 0127 self.d("""\ 0128 /** 0129 * %(upper-prefix)sNUM_%(upper-plural)s: 0130 * 0131 * 1 higher than the highest valid value of #%(mixed-name)s. 0132 */ 0133 0134 /** 0135 * NUM_%(upper-prefix)s%(upper-plural)s: (skip) 0136 * 0137 * 1 higher than the highest valid value of #%(mixed-name)s. 0138 * In new code, use %(upper-prefix)sNUM_%(upper-plural)s instead. 0139 */ 0140 """ % {'mixed-name' : (self.prefix + name).replace('_', ''), 0141 'upper-prefix' : self.prefix.upper(), 0142 'upper-plural' : name_plural.upper(), 0143 'last-val' : vals[-1].getAttribute('value')}) 0144 0145 self.write("""\ 0146 #define %(upper-prefix)sNUM_%(upper-plural)s (%(last-val)s+1) 0147 #define NUM_%(upper-prefix)s%(upper-plural)s %(upper-prefix)sNUM_%(upper-plural)s 0148 0149 """ % {'mixed-name' : (self.prefix + name).replace('_', ''), 0150 'upper-prefix' : self.prefix.upper(), 0151 'upper-plural' : name_plural.upper(), 0152 'last-val' : vals[-1].getAttribute('value')}) 0153 0154 def do_val(self, val, value_prefix): 0155 name = val.getAttribute('name') 0156 suffix = val.getAttribute('suffix') 0157 use_name = (self.prefix + value_prefix + '_' + \ 0158 (suffix or name)).upper() 0159 assert not (name and suffix) or name == suffix, \ 0160 'Flag/enumvalue name %s != suffix %s' % (name, suffix) 0161 self.write(' %s = %s,\n' % (use_name, val.getAttribute('value'))) 0162 0163 def do_gtkdoc(self, node, value_prefix): 0164 self.d(' * @') 0165 self.d((self.prefix + value_prefix + '_' + 0166 node.getAttribute('suffix')).upper()) 0167 self.d(': <![CDATA[') 0168 docstring = get_by_path(node, 'docstring') 0169 self.d(get_descendant_text(docstring).replace('\n', ' ')) 0170 self.d(']]>\n') 0171 0172 # Footer 0173 def do_footer(self): 0174 self.write(""" 0175 #ifdef __cplusplus 0176 } 0177 #endif 0178 """) 0179 0180 if __name__ == '__main__': 0181 argv = argv[1:] 0182 Generator(argv[0], xml.dom.minidom.parse(argv[1]), argv[2])()