1# vim: set ts=4 sws=4 sw=4: 2 3import sys # stderr 4 5_templates = {} 6 7_templates['initializer'] = \ 8'''\ 9typedef typename value_type<%s, ! std::is_pointer<%s>::value>::type 10 vector_type; 11std::vector<vector_type> %s = 12 { value_iterator<%s>(%s), value_iterator<%s>(%s) }; 13''' 14 15def _initializer(iter_type, c_name, iter_begin, iter_end): 16 return _templates['initializer'] % \ 17 ( iter_type 18 , iter_type 19 , c_name 20 , iter_type 21 , iter_begin 22 , iter_type 23 , iter_end 24 ) 25 26class ParameterList(object): 27 def __init__(self): 28 self.want_wrap = False 29 self.has_defaults = False 30 self.parameter = [] 31 self.wrap_calls = [] 32 self.wrap_protos = [] 33 self.iter_calls = [] 34 self.iter_2nd_lvl_calls = [] 35 self.iter_protos = [] 36 self.templates = [] 37 self.iterator_templates = [] 38 self.initializer = [] 39 40 def add(self, param): 41 self.has_defaults = param.default != None 42 self.parameter.append(param) 43 44 def comma(self): 45 return "" if len(self.parameter) == 0 else ", " 46 47 def is_reordered(self): 48 tmp = sorted(self.parameter, key=lambda p: p.default or '') 49 return tmp != self.parameter 50 51 def calls(self, sort, params=None): 52 ps = self.parameter if params == None else params 53 if sort: 54 tmp = sorted(ps, key=lambda p: p.default or '') 55 ps = tmp 56 calls = [p.call() for p in ps] 57 return ", ".join(calls) 58 59 def protos(self, sort, defaults, params=None): 60 if defaults: sort = True 61 ps = self.parameter if params == None else params 62 if sort: 63 tmp = sorted(ps, key=lambda p: p.default or '') 64 ps = tmp 65 protos = [p.proto(defaults) for p in ps] 66 return ", ".join(protos) 67 68 def iterator_initializers(self): 69 return self.initializer 70 71 def make_wrapped(self): 72 self.wrap_calls = [] 73 self.wrap_protos = [] 74 self.iter_calls = [] 75 self.iter_2nd_lvl_calls = [] 76 self.iter_protos = [] 77 self.initializer = [] 78 self.templates = [] 79 self.iterator_templates = [] 80 81 lenfields = {} 82 # if a parameter is removed, take reduced parameter size into account 83 adjust = 0 84 for index, param in enumerate(self.parameter): 85 prev = index - adjust - 1 86 87 if param.field.type.is_list: 88 name = param.field.type.expr.lenfield_name 89 if name in lenfields: 90 lenfields[name].append(param.c_name) 91 else: 92 lenfields[name] = [ param.c_name ] 93 94 # sys.stderr.write("list: %s %s\n\n" 95 # % ( param.field.type.expr.lenfield_type 96 # , param.field.type.expr.lenfield_name 97 # )) 98 99 # SetGamma: takes 1 size, but 3 value lists 100 # if param.field.type.is_list and prev >= 0: 101 if (param.is_const and param.is_pointer 102 and prev >= 0 103 and self.parameter[prev].c_name == param.c_name + "_len"): 104 105 adjust = adjust + 1 106 self.want_wrap = True 107 self.wrap_calls.pop(prev) 108 self.wrap_protos.pop(prev) 109 self.iter_calls.pop(prev) 110 self.iter_2nd_lvl_calls.pop(prev) 111 self.iter_protos.pop(prev) 112 113 prev_type = self.parameter[prev].c_type 114 if param.c_type == 'char': 115 116 def append_proto_string(list): 117 list.append(Parameter(None, \ 118 c_type='const std::string &', 119 c_name=param.c_name)) 120 121 def append_call_string(list): 122 list.append(Parameter(None, \ 123 c_name="static_cast<" + prev_type + ">(" \ 124 + param.c_name + '.length())')) 125 126 list.append(Parameter(None, \ 127 c_name=param.c_name + '.c_str()')) 128 129 append_proto_string(self.wrap_protos) 130 append_proto_string(self.iter_protos) 131 append_call_string(self.wrap_calls) 132 append_call_string(self.iter_calls) 133 append_call_string(self.iter_2nd_lvl_calls) 134 135 else: 136 param_type = param.c_type 137 if param_type == "void": 138 param_type = "Type_" + str(index) 139 self.templates.append(param_type) 140 141 prev_type = self.parameter[prev].c_type 142 143 ### std::vector 144 self.wrap_protos.append(Parameter(None, \ 145 c_type='const std::vector<' + param_type + '> &', 146 c_name=param.c_name)) 147 148 self.wrap_calls.append(Parameter(None, \ 149 c_name="static_cast<" + prev_type + ">(" \ 150 + param.c_name + '.size())')) 151 152 self.wrap_calls.append(Parameter(None, \ 153 c_name=param.c_name + '.data()')) 154 155 ### Iterator 156 iter_type = param.c_name.capitalize() + "_Iterator" 157 iter_begin = param.c_name + "_begin" 158 iter_end = param.c_name + "_end" 159 160 if len(self.templates) > 0: 161 self.templates[-1] += " = typename " + iter_type + "::value_type" 162 self.iterator_templates.append(iter_type) 163 164 self.iter_protos.append(Parameter(None, \ 165 c_type=iter_type, 166 c_name=iter_begin)) 167 168 self.iter_protos.append(Parameter(None, \ 169 c_type=iter_type, 170 c_name=iter_end)) 171 172 self.iter_calls.append(Parameter(None, \ 173 c_name="static_cast<" + prev_type + ">(" \ 174 + param.c_name + '.size())')) 175 176 self.iter_calls.append(Parameter(None, \ 177 c_name='const_cast<const vector_type *>(' \ 178 + param.c_name + '.data())')) 179 180 self.iter_2nd_lvl_calls.append(Parameter(None, \ 181 c_name=iter_begin)) 182 183 self.iter_2nd_lvl_calls.append(Parameter(None, \ 184 c_name=iter_end)) 185 186# vector_type = \ 187# '''\ 188# typename value_type<%s, 189# ! std::is_pointer<%s>::value 190# >::type\ 191# ''' % (iter_type, iter_type) 192 193 # self.initializer.append( \ 194 # "std::vector<%s> %s = { value_iterator<%s>(%s), \ 195 # value_iterator<%s>(%s) };" \ 196 # % (vector_type, param.c_name, 197 # iter_type, iter_begin, 198 # iter_type, iter_end)) 199 200 self.initializer.append( 201 _initializer(iter_type, param.c_name, iter_begin, iter_end)) 202 203 else: 204 self.wrap_calls.append(param) 205 self.wrap_protos.append(param) 206 self.iter_calls.append(param) 207 self.iter_2nd_lvl_calls.append(param) 208 self.iter_protos.append(param) 209 210 # end: for index, param in enumerate(self.parameter): 211 212 for k, v in list(lenfields.items()): 213 if len(v) > 1: 214 sys.stderr.write("list: %s, %s\n" % (k, v)) 215 216 217 def wrapped_calls(self, sort): 218 return self.calls(sort, params=self.wrap_calls) 219 220 def wrapped_protos(self, sort, defaults): 221 return self.protos(sort, defaults, params=self.wrap_protos) 222 223 def iterator_calls(self, sort): 224 return self.calls(sort, params=self.iter_calls) 225 226 def iterator_2nd_lvl_calls(self, sort): 227 return self.calls(sort, params=self.iter_2nd_lvl_calls) 228 229 def iterator_protos(self, sort, defaults): 230 return self.protos(sort, defaults, params=self.iter_protos) 231 232 233 234_default_parameter_values = \ 235 { "xcb_timestamp_t" : "XCB_TIME_CURRENT_TIME" } 236 237class Parameter(object): 238 def __init__(self, field, c_type="", c_name="", verbose=False): 239 self.field = field 240 if field != None: 241 self.c_type = field.c_field_type 242 self.c_name = field.c_field_name 243 self.is_const = field.c_field_const_type == "const " + field.c_field_type 244 self.is_pointer = field.c_pointer != " " 245 # self.serialize = field.type.need_serialize 246 self.default = _default_parameter_values.get(self.c_type) 247 self.with_default = True 248 if verbose: 249 sys.stderr.write("c_type: %s; c_name: %s; default: %s\n" \ 250 % (self.c_type, self.c_name, self.default)) 251 252 else: 253 self.c_type = c_type 254 self.c_name = c_name 255 self.is_const = False 256 self.is_pointer = False 257 # self.serialize = field.type.need_serialize 258 self.default = _default_parameter_values.get(self.c_type) 259 self.with_default = True 260 261 def call(self): 262 return self.c_name 263 264 def proto(self, with_default): 265 c_type = ("const " if self.is_const else "") \ 266 + self.c_type \ 267 + (" *" if self.is_pointer else "") 268 param = " = " + self.default if with_default and self.default != None else "" 269 return c_type + " " + self.c_name + param 270