1#!/usr/bin/env python 2 3import sys 4import os 5 6sys.path.insert(0, os.path.normpath(os.path.join(__file__, '../../..'))) 7 8import struct 9from random import randint, choice, seed 10 11from Xlib.protocol import request, structs, rq, event 12from Xlib import X 13 14 15 16seed(42) 17 18MINI_DEF = (('CARD8', 'reqType'), 19 ('BYTE', 'pad'), 20 ('CARD16', 'length')) 21 22RESOURCE_DEF = (('CARD8', 'reqType'), 23 ('BYTE', 'pad'), 24 ('CARD16', 'length'), 25 ('CARD32', 'id')) 26 27def read_defs(): 28 global request_defs, reply_defs, struct_defs 29 global mini_request_defs, resource_request_defs 30 global event_defs 31 32 request_defs = {} 33 mini_request_defs = {} 34 resource_request_defs = {} 35 reply_defs = {} 36 struct_defs = {} 37 event_defs = {} 38 39 for line in sys.stdin.readlines(): 40 parts = line.strip().split() 41 42 fields = [] 43 for f in parts[2:]: 44 fields.append(f.split(':')) 45 46 if parts[0] == 'REQUEST': 47 request_defs[parts[1]] = fields 48 elif parts[0] == 'MINIREQUEST': 49 mini_request_defs[parts[1]] = MINI_DEF 50 elif parts[0] == 'RESOURCEREQUEST': 51 resource_request_defs[parts[1]] = RESOURCE_DEF 52 elif parts[0] == 'REPLY': 53 reply_defs[parts[1]] = fields 54 elif parts[0] == 'STRUCT': 55 struct_defs[parts[1]] = fields 56 elif parts[0] == 'EVENT': 57 event_defs[parts[1]] = fields 58 59 60def build(): 61 if struct.unpack('BB', struct.pack('H', 0x0100))[0]: 62 endian = 'be' 63 else: 64 endian = 'le' 65 66 read_defs() 67 68 build_request(endian) 69 build_event(endian) 70 71 72def build_request(endian): 73 fc = open('genrequest.c', 'w') 74 75 fc.write(C_HEADER) 76 77 reqlist = list(request.major_codes.items()) 78 reqlist.sort(key=lambda x: x[0]) 79 80 genfuncs = [] 81 req_args = {} 82 reply_args = {} 83 84 for code, req in reqlist: 85 name = req.__name__ 86 creqname = name 87 88 cdefs = request_defs.get(name) 89 if cdefs is None: 90 cdefs = mini_request_defs.get(name) 91 creqname = '' 92 if cdefs is None: 93 cdefs = resource_request_defs.get(name) 94 creqname = 'Resource' 95 96 creqname = 'x%sReq' % creqname 97 98 if cdefs is None: 99 sys.stderr.write('missing def for request: %s\n' % name) 100 else: 101 vardefs = request_var_defs.get(name, [()]) 102 if type(vardefs) is not list: 103 vardefs = [vardefs] 104 105 i = 0 106 for v in vardefs: 107 if i > 0: 108 uname = name + str(i) 109 else: 110 uname = name 111 112 try: 113 req_args[uname] = gen_func(fc, 114 'genrequest_' + uname, 115 creqname, 116 'REQUEST ' + uname, 117 req._request, 118 cdefs, 119 v) 120 except: 121 sys.stderr.write('Error in %s request\n' % uname) 122 raise 123 124 genfuncs.append('genrequest_' + uname) 125 i = i + 1 126 127 if issubclass(req, rq.ReplyRequest): 128 cdefs = reply_defs.get(name) 129 130 if cdefs is None: 131 sys.stderr.write('missing def for reply: %s\n' % name) 132 else: 133 vardefs = reply_var_defs.get(name, ()) 134 if type(vardefs) is not list: 135 vardefs = [vardefs] 136 137 i = 0 138 for v in vardefs: 139 if i > 0: 140 uname = name + str(i) 141 else: 142 uname = name 143 144 try: 145 reply_args[uname] = gen_func(fc, 146 'genreply_' + uname, 147 'x%sReply' % name, 148 'REPLY ' + uname, 149 req._reply, 150 cdefs, 151 v) 152 except: 153 sys.stderr.write('Error in %s reply\n' % uname) 154 raise 155 156 genfuncs.append('genreply_' + uname) 157 i = i + 1 158 159 160 fc.write(''' 161 162 int main(void) 163 { 164 ''') 165 166 for gf in genfuncs: 167 fc.write(' %s();\n' % gf) 168 169 fc.write(''' 170 return 0; 171 } 172 ''') 173 174 fc.close() 175 os.system('gcc -Wall -g genrequest.c -o genrequest') 176 177 req_bins = {} 178 reply_bins = {} 179 pc = os.popen('./genrequest', 'r') 180 for line in pc.readlines(): 181 parts = line.strip().split() 182 if parts[0] == 'REQUEST': 183 req_bins[parts[1]] = parts[2] 184 elif parts[0] == 'REPLY': 185 reply_bins[parts[1]] = parts[2] 186 187 fpy = open('../test_requests_%s.py' % endian, 'w') 188 os.chmod('../test_requests_%s.py' % endian, 0o755) 189 190 if endian == 'be': 191 e = 'BigEndian' 192 v = 1 193 else: 194 e = 'LittleEndian' 195 v = 0 196 197 fpy.write(PY_HEADER % { 'endname': e, 'endvalue': v }) 198 199 for code, req in reqlist: 200 name = req.__name__ 201 202 fpy.write('\n\nclass Test%s(EndianTest):\n' % name) 203 fpy.write(' def setUp(self):\n') 204 205 i = 0 206 reqs = -1 207 replies = -1 208 while 1: 209 if i > 0: 210 uname = name + str(i) 211 else: 212 uname = name 213 214 reqbin = req_bins.get(uname) 215 replybin = reply_bins.get(uname) 216 217 if reqbin is None and replybin is None: 218 break 219 220 if reqbin: 221 reqs = i 222 fpy.write(' self.req_args_%d = %s\n' 223 % (i, build_args(req_args[uname]))) 224 fpy.write(' self.req_bin_%d = %s\n\n' 225 % (i, build_bin(reqbin))) 226 if replybin: 227 replies = i 228 fpy.write(' self.reply_args_%d = %s\n' 229 % (i, build_args(reply_args[uname]))) 230 fpy.write(' self.reply_bin_%d = %s\n\n' 231 % (i, build_bin(replybin))) 232 233 i = i + 1 234 235 for i in range(0, reqs + 1): 236 fpy.write(''' 237 def testPackRequest%(n)d(self): 238 bin = request.%(req)s._request.to_binary(*(), **self.req_args_%(n)d) 239 self.assertBinaryEqual(bin, self.req_bin_%(n)d) 240 241 def testUnpackRequest%(n)d(self): 242 args, remain = request.%(req)s._request.parse_binary(self.req_bin_%(n)d, dummy_display, 1) 243 self.assertBinaryEmpty(remain) 244 self.assertEqual(args, self.req_args_%(n)d) 245''' % { 'req': req.__name__, 'n': i }) 246 247 for i in range(0, replies + 1): 248 fpy.write(''' 249 def testPackReply%(n)d(self): 250 bin = request.%(req)s._reply.to_binary(*(), **self.reply_args_%(n)d) 251 self.assertBinaryEqual(bin, self.reply_bin_%(n)d) 252 253 def testUnpackReply%(n)d(self): 254 args, remain = request.%(req)s._reply.parse_binary(self.reply_bin_%(n)d, dummy_display, 1) 255 self.assertBinaryEmpty(remain) 256 self.assertEqual(args, self.reply_args_%(n)d) 257''' % { 'req': req.__name__, 'n': i }) 258 259 fpy.write(''' 260 261if __name__ == "__main__": 262 unittest.main() 263''') 264 265 266def build_event(endian): 267 fc = open('genevent.c', 'w') 268 269 fc.write(C_HEADER) 270 271 evtlist = list(event.event_class.items()) 272 evtlist.sort(key=lambda x: x[0]) 273 274 genfuncs = [] 275 evt_args = {} 276 277 for code, evt in evtlist: 278 279 # skip events that does not subclass rq.Event immediately, 280 # since those are specializations of the more general ones we 281 # test. 282 283 if evt.__bases__ != (rq.Event, ): 284 continue 285 286 # special handling of KeymapNotify, since that 287 # event is so different 288 if evt == event.KeymapNotify: 289 evt_args['KeymapNotify'] = gen_func(fc, 290 'genevent_KeymapNotify', 291 'xKeymapEvent', 292 'EVENT KeymapNotify', 293 evt._fields, 294 (('BYTE', 'type'), ), 295 (31, )) 296 genfuncs.append('genevent_KeymapNotify') 297 continue 298 299 name = evt.__name__ 300 301 cdefs = event_defs.get(name) 302 if cdefs is None: 303 sys.stderr.write('missing def for event: %s\n' % name) 304 else: 305 vardefs = event_var_defs.get(name, [()]) 306 if type(vardefs) is not list: 307 vardefs = [vardefs] 308 309 i = 0 310 for v in vardefs: 311 if i > 0: 312 uname = name + str(i) 313 else: 314 uname = name 315 316 try: 317 evt_args[uname] = gen_func(fc, 318 'genevent_' + uname, 319 'xEvent', 320 'EVENT ' + uname, 321 evt._fields, 322 cdefs, 323 v) 324 except: 325 sys.stderr.write('Error in %s event\n' % uname) 326 raise 327 328 genfuncs.append('genevent_' + uname) 329 i = i + 1 330 331 fc.write(''' 332 333 int main(void) 334 { 335 ''') 336 337 for gf in genfuncs: 338 fc.write(' %s();\n' % gf) 339 340 fc.write(''' 341 return 0; 342 } 343 ''') 344 345 fc.close() 346 os.system('gcc -Wall -g genevent.c -o genevent') 347 348 evt_bins = {} 349 pc = os.popen('./genevent', 'r') 350 for line in pc.readlines(): 351 parts = line.strip().split() 352 if parts[0] == 'EVENT': 353 evt_bins[parts[1]] = parts[2] 354 355 fpy = open('../test_events_%s.py' % endian, 'w') 356 os.chmod('../test_events_%s.py' % endian, 0o755) 357 358 if endian == 'be': 359 e = 'BigEndian' 360 v = 1 361 else: 362 e = 'LittleEndian' 363 v = 0 364 365 fpy.write(PY_HEADER % { 'endname': e, 'endvalue': v }) 366 367 for code, evt in evtlist: 368 if evt.__bases__ != (rq.Event, ): 369 continue 370 371 name = evt.__name__ 372 373 fpy.write('\n\nclass Test%s(EndianTest):\n' % name) 374 fpy.write(' def setUp(self):\n') 375 376 i = 0 377 evts = -1 378 while 1: 379 if i > 0: 380 uname = name + str(i) 381 else: 382 uname = name 383 384 evtbin = evt_bins.get(uname) 385 386 if evtbin is None: 387 break 388 389 evts = i 390 fpy.write(' self.evt_args_%d = %s\n' 391 % (i, build_args(evt_args[uname]))) 392 fpy.write(' self.evt_bin_%d = %s\n\n' 393 % (i, build_bin(evtbin))) 394 i = i + 1 395 396 for i in range(0, evts + 1): 397 fpy.write(''' 398 def testPack%(n)d(self): 399 bin = event.%(evt)s._fields.to_binary(*(), **self.evt_args_%(n)d) 400 self.assertBinaryEqual(bin, self.evt_bin_%(n)d) 401 402 def testUnpack%(n)d(self): 403 args, remain = event.%(evt)s._fields.parse_binary(self.evt_bin_%(n)d, dummy_display, 1) 404 self.assertBinaryEmpty(remain) 405 self.assertEqual(args, self.evt_args_%(n)d) 406''' % { 'evt': evt.__name__, 'n': i }) 407 408 fpy.write(''' 409 410if __name__ == "__main__": 411 unittest.main() 412''') 413 414 415def gen_func(fc, funcname, structname, outputname, pydef, cdef, vardefs): 416 fc.write('''void %s(void) 417 { 418 struct { 419 %s xstruct; 420 ''' % (funcname, structname)) 421 422 args = {} 423 varfs = {} 424 extra_vars = [] 425 flags = None 426 427 # structure fields etc 428 i = 0 429 for f in pydef.var_fields: 430 # 431 # List of something 432 # 433 if isinstance(f, rq.List): 434 # 435 # List of short strings 436 # 437 if f.type is rq.Str: 438 vfstrings = vardefs[i] 439 vflen = 0 440 vfdata = '' 441 for s in vfstrings: 442 vflen = vflen + 1 + len(s) 443 vfdata = vfdata + chr(len(s)) + s 444 445 fc.write('unsigned char %s[%d];\n ' 446 % (f.name, pad4(vflen))) 447 varfs[f.name] = ('memcpy(data.%s, %s, %d);' 448 % (f.name, cstring(vfdata), vflen), 449 len(vfstrings), 0) 450 args[f.name] = vfstrings 451 452 # 453 # List of scalars 454 # 455 elif isinstance(f.type, rq.ScalarObj) \ 456 or isinstance(f.type, rq.ResourceObj): 457 458 vflen = vardefs[i] 459 460 if f.type.structcode == 'B': 461 rmin = 128 462 rmax = 255 463 deflen = pad4(vflen) 464 ctype = 'CARD8' 465 elif f.type.structcode == 'H': 466 rmin = 32768 467 rmax = 65536 468 deflen = vflen + vflen % 2 469 ctype = 'CARD16' 470 elif f.type.structcode == 'L': 471 rmin = 65536 472 rmax = 2147483646 473 deflen = vflen 474 ctype = 'CARD32' 475 else: 476 RuntimeError('oops: %s' % f.type.structcode) 477 478 def rand(x, rmin = rmin, rmax = rmax): 479 return randint(rmin, rmax) 480 481 vfdata = list(map(rand, range(0, vflen))) 482 483 # 484 # Special case for a few in-line coded lists 485 # 486 if structname in ('xGetKeyboardControlReply', 487 'xQueryKeymapReply', 488 'xKeymapEvent'): 489 extra_vars.append('%s %s_def[%d] = { %s };' 490 % (ctype, f.name, vflen, 491 ', '.join(map(str, vfdata)))) 492 varfs[f.name] = ('memcpy(data.xstruct.map, %s_def, sizeof(%s_def));' 493 % (f.name, f.name), 494 vflen, 0) 495 else: 496 fc.write('%s %s[%d];\n ' 497 % (ctype, f.name, deflen)) 498 extra_vars.append('%s %s_def[%d] = { %s };' 499 % (ctype, f.name, vflen, 500 ', '.join(map(str, vfdata)))) 501 varfs[f.name] = ('memcpy(data.%s, %s_def, sizeof(%s_def));' 502 % (f.name, f.name, f.name), 503 vflen, 0) 504 505 args[f.name] = vfdata 506 507 # 508 # Special handling of unique Host case 509 # 510 elif f.type is structs.Host: 511 pydata = [{ 'family': X.FamilyInternet, 512 'name': [ 34, 23, 178, 12 ] }, 513 { 'family': X.FamilyInternet, 514 'name': [ 130, 236, 254, 15 ] }, ] 515 516 cdata = [] 517 for p in pydata: 518 cdata.append("{ { %d, 0, 4 }, { %d, %d, %d, %d } }" 519 % ((p['family'], ) + tuple(p['name']))) 520 521 fc.write('struct { xHostEntry e; CARD8 name[4]; } %s[2];\n ' % f.name) 522 523 extra_vars.append('struct { xHostEntry e; CARD8 name[4]; } %s_def[%d] = { %s };' 524 % (f.name, len(pydata), 525 ', '.join(cdata))) 526 527 varfs[f.name] = ('memcpy(data.%s, %s_def, sizeof(%s_def));' 528 % (f.name, f.name, f.name), 529 len(pydata), 0) 530 531 args[f.name] = pydata 532 533 534 # 535 # List of structures 536 # 537 elif isinstance(f.type, rq.Struct): 538 vfname, vflen = vardefs[i] 539 vfdef = struct_defs[vfname] 540 541 pydata = [] 542 defdata = [] 543 for si in range(0, vflen): 544 d = [] 545 for t, cf in vfdef: 546 if cf[:3] != 'pad': 547 d.append(gen_value(t)) 548 549 pyd = {} 550 for sj in range(0, len(d)): 551 pyd[f.type.fields[sj].name] = d[sj] 552 553 pydata.append(pyd) 554 defdata.append('{ ' + ', '.join(map(str, d)) + ' }') 555 556 fc.write('x%s %s[%d];\n ' % (vfname, f.name, vflen)) 557 558 extra_vars.append('x%s %s_def[%d] = { %s };' 559 % (vfname, f.name, vflen, 560 ', '.join(defdata))) 561 varfs[f.name] = ('memcpy(data.%s, %s_def, sizeof(%s_def));' 562 % (f.name, f.name, f.name), 563 vflen, 0) 564 args[f.name] = pydata 565 566 # 567 # wide-char string 568 # 569 elif isinstance(f, rq.String16): 570 vfstr = vardefs[i] 571 vflen = len(vfstr) 572 573 fc.write('unsigned char %s[%d];\n ' % 574 (f.name, (vflen + vflen % 2) * 2)) 575 576 s = '' 577 for c in vfstr: 578 s = s + '\0' + c 579 580 varfs[f.name] = ('memcpy(data.%s, %s, %d);' 581 % (f.name, cstring(s), vflen * 2), 582 vflen, 0) 583 args[f.name] = tuple(map(ord, vfstr)) 584 585 # 586 # byte-char string 587 # 588 elif isinstance(f, (rq.String8, rq.Binary)): 589 vfstr = vardefs[i] 590 vflen = len(vfstr) 591 592 fc.write('unsigned char %s[%d];\n ' % 593 (f.name, (vflen + (4 - vflen % 4) % 4))) 594 varfs[f.name] = ('memcpy(data.%s, %s, %d);' 595 % (f.name, cstring(vfstr), vflen), 596 vflen, 0) 597 args[f.name] = vfstr 598 599 # 600 # List of optional values 601 # 602 elif isinstance(f, rq.ValueList): 603 vlcode = [] 604 vlargs = {} 605 flags = 0 606 for vlf, flag in f.fields: 607 ctype, rmin, rmax, clen = structcode_defs[vlf.structcode] 608 fc.write('%s %s_%s;\n ' 609 % (ctype, f.name, vlf.name)) 610 if clen < 4: 611 fc.write('unsigned char %s_%s_pad[%d];\n ' 612 % (f.name, vlf.name, 4 - clen)) 613 614 if isinstance(vlf, rq.Set): 615 val = choice(vlf.values) 616 elif isinstance(vlf, rq.Bool): 617 val = choice((0, 1)) 618 else: 619 val = randint(rmin, rmax) 620 vlargs[vlf.name] = val 621 vlcode.append('data.%s_%s = %d;' % (f.name, vlf.name, val)) 622 flags = flags | flag 623 624 # vlcode.append('data.%s_flags = %d;' % (f.name, flags)) 625 626 varfs[f.name] = (' '.join(vlcode), 0, 0) 627 args[f.name] = vlargs 628 629 # 630 # Text/font list, hardwire since they are so rare 631 # 632 elif isinstance(f, rq.TextElements8): 633 if isinstance(f, rq.TextElements16): 634 vfstr = b'\x02\x02\x10\x23\x00\x12\xff\x01\x02\x03\x04' 635 ret = [{'delta': 2, 'string': (0x1023, 0x0012)}, 636 0x01020304] 637 else: 638 vfstr = b'\x03\x02zoo\xff\x01\x02\x03\x04\x02\x00ie' 639 ret = [{'delta': 2, 'string': 'zoo'}, 640 0x01020304, 641 { 'delta': 0, 'string': 'ie'}] 642 643 fc.write('unsigned char %s[%d];\n ' 644 % (f.name, len(vfstr))) 645 varfs[f.name] = ('memcpy(data.%s, %s, %d);' 646 % (f.name, cstring(vfstr), len(vfstr)), 647 0, 0) 648 args[f.name] = ret 649 650 # 651 # Keyboard/modifier mappings 652 # 653 elif isinstance(f, rq.KeyboardMapping) \ 654 or isinstance(f, rq.ModifierMapping): 655 656 if isinstance(f, rq.KeyboardMapping): 657 rmin = 0 658 rmax = 2147483646 659 length = 20 660 format = 3 661 ctype = 'CARD32' 662 else: 663 rmin = 0 664 rmax = 255 665 length = 8 666 format = 2 667 ctype = 'CARD8' 668 669 pydata = [] 670 cdata = [] 671 for i in range(0, length): 672 x = [] 673 for j in range(0, format): 674 v = randint(rmin, rmax) 675 x.append(v) 676 cdata.append(str(v)) 677 pydata.append(x) 678 679 fc.write('%s %s[%d];\n ' % (ctype, f.name, len(cdata))) 680 extra_vars.append('%s %s_def[%d] = { %s };' 681 % (ctype, f.name, len(cdata), 682 ', '.join(cdata))) 683 varfs[f.name] = ('memcpy(data.%s, %s_def, sizeof(%s_def));' 684 % (f.name, f.name, f.name), 685 length, format) 686 args[f.name] = pydata 687 688 # 689 # property data 690 # 691 elif isinstance(f, rq.PropertyData): 692 format, data = vardefs[i] 693 length = len(data) 694 695 if format == 8: 696 ctype = 'CARD8' 697 clen = pad4(length) 698 cdata = cstring(data) 699 elif format == 16: 700 ctype = 'CARD16' 701 clen = length + length % 2 702 cdata = ', '.join(map(str, data)) 703 elif format == 32: 704 ctype = 'CARD32' 705 clen = length 706 cdata = ', '.join(map(str, data)) 707 708 if not isinstance(f, rq.FixedPropertyData): 709 fc.write('%s %s[%d];\n ' % 710 (ctype, f.name, clen)) 711 712 extra_vars.append('%s %s_def[%d] = { %s };' 713 % (ctype, f.name, length, cdata)) 714 715 if not isinstance(f, rq.FixedPropertyData): 716 varfs[f.name] = ('memcpy(data.%s, %s_def, sizeof(%s_def));' 717 % (f.name, f.name, f.name), 718 length, format) 719 else: 720 varfs[f.name] = ('assert(sizeof(%s_def) == 20); memcpy(data.xstruct.u.clientMessage.u.b.bytes, %s_def, sizeof(%s_def));' 721 % (f.name, f.name, f.name), 722 length, format) 723 724 args[f.name] = (format, data) 725 726 # 727 # Event 728 # 729 elif isinstance(f, rq.EventField): 730 ev = event.Expose(window = gen_value('CARD32'), 731 x = gen_value('CARD16'), 732 y = gen_value('CARD16'), 733 width = gen_value('CARD16'), 734 height = gen_value('CARD16'), 735 count = gen_value('CARD16')) 736 cdata = cstring(ev._binary) 737 738 # fc.write('unsigned char %s[32];\n ' % f.name) 739 extra_vars.append('unsigned char %s_def[32] = %s;' 740 % (f.name, cdata)) 741 varfs[f.name] = ('memcpy(&data.xstruct.event, %s_def, sizeof(%s_def));' 742 % (f.name, f.name), 743 0, 0) 744 745 args[f.name] = ev 746 747 else: 748 raise RuntimeError('oops: %s.%s' % (funcname, f.name)) 749 750 i = i + 1 751 752 753 fc.write('\n } data;\n') 754 755 756 for v in extra_vars: 757 fc.write(' %s\n' % v) 758 759 fc.write(''' 760 memset(&data, 0, sizeof(data)); 761 762 ''') 763 764 pyi = 0 765 ci = 0 766 767 while ci < len(cdef): 768 try: 769 pyf = pydef.fields[pyi] 770 except IndexError: 771 pyf = None 772 773 cf = cdef[ci] 774 t, f = cf 775 776 pyi = pyi + 1 777 ci = ci + 1 778 779 if f[:3] == 'pad' or f[:6] == 'walign': 780 if not isinstance(pyf, rq.Pad): 781 pyi = pyi - 1 782 783 # special case for value list mask 784 elif (f == 'mask' or f == 'valueMask') and flags is not None: 785 fc.write(' data.xstruct.%s = %d;\n' % (f, flags)) 786 787 elif isinstance(pyf, rq.ConstantField): 788 fc.write(' data.xstruct.%s = %d;\n' % (f, pyf.value)) 789 790 elif isinstance(pyf, rq.RequestLength): 791 assert f == 'length' 792 793 fc.write(' assert(sizeof(data) % 4 == 0);\n') 794 fc.write(' data.xstruct.length = sizeof(data) / 4;\n') 795 796 elif isinstance(pyf, rq.ReplyLength): 797 assert f == 'length' 798 799 fc.write(' assert(sizeof(data) % 4 == 0);\n') 800 fc.write(' assert(sizeof(data) >= 32);\n') 801 fc.write(' data.xstruct.length = (sizeof(data) - 32) / 4;\n') 802 803 elif isinstance(pyf, rq.LengthOf): 804 fc.write(' data.xstruct.%s = %d;\n' % (f, varfs[pyf.name][1])) 805 806 elif isinstance(pyf, rq.OddLength): 807 fc.write(' data.xstruct.%s = %d;\n' % (f, varfs[pyf.name][1] % 2)) 808 809 elif isinstance(pyf, rq.Format): 810 fc.write(' data.xstruct.%s = %d;\n' % (f, varfs[pyf.name][2])) 811 812 elif isinstance(pyf, rq.Set): 813 val = choice(pyf.values) 814 fc.write(' data.xstruct.%s = %d;\n' % (f, val)) 815 args[pyf.name] = val 816 817 elif t == 'xCharInfo': 818 d = [] 819 for ct, cf in struct_defs['CharInfo']: 820 if cf[:3] != 'pad': 821 d.append(gen_value(ct)) 822 823 pyd = {} 824 for sj in range(0, len(d)): 825 pyd[pyf.type.fields[sj].name] = d[sj] 826 827 fc.write('{ %s def = { %s };\n ' 828 % (t, ', '.join(map(str, d)))) 829 fc.write('memcpy(&data.xstruct.%s, &def, sizeof(def)); }\n ' % f) 830 args[pyf.name] = pyd 831 832 else: 833 val = gen_value(t) 834 fc.write(' data.xstruct.%s = %d;\n' % (f, val)) 835 args[pyf.name] = val 836 837 for code, length, format in varfs.values(): 838 fc.write(' %s\n' % code); 839 840 fc.write(''' 841 output("%s", &data, sizeof(data)); 842 } 843 844 ''' % outputname) 845 846 return args 847 848 849def gen_value(t): 850 if t == 'INT8': 851 val = randint(-128, -1) 852 elif t == 'INT16': 853 val = randint(-32768, -256) 854 elif t == 'INT32': 855 val = randint(-2147483647, -65536) 856 elif t == 'CARD8' or t == 'BYTE': 857 val = randint(128, 255) 858 elif t == 'CARD16': 859 val = randint(256, 65535) 860 elif t == 'CARD32': 861 val = randint(65536, 2147483646) 862 elif t == 'BOOL': 863 val = randint(0, 1) 864 else: 865 raise RuntimeError('unknown type: %s' % t) 866 return val 867 868 869def pad4(l): 870 return l + (4 - l % 4) % 4 871 872def cstring(s): 873 if not isinstance(s, bytes): 874 s = s.encode('ascii') 875 return '"' + ''.join('\\x%x' % c for c in s) + '"' 876 877 878def build_args(args): 879 kwlist = [] 880 for kw, val in sorted(args.items(), key=lambda i: i[0]): 881 if isinstance(val, rq.Event): 882 members = list(val._data.keys()) 883 members.remove('send_event') 884 kwlist.append(" '%s': event.%s(%s),\n" % ( 885 kw, val.__class__.__name__, 886 ', '.join('%s=%s' % (m, val._data[m]) 887 for m in sorted(members)), 888 )) 889 else: 890 kwlist.append(" '%s': %s,\n" % (kw, repr(val))) 891 892 return '{\n' + ''.join(kwlist) + ' }' 893 894def build_bin(bin): 895 bins = [] 896 for i in range(0, len(bin), 16): 897 bins.append(bin[i:i+16]) 898 899 bins2 = [] 900 for i in range(0, len(bins), 2): 901 try: 902 bins2.append("b'%s' b'%s'" % (bins[i], bins[i + 1])) 903 except IndexError: 904 bins2.append("b'%s'" % bins[i]) 905 906 return ' \\\n '.join(bins2) 907 908 909request_var_defs = { 910 'InternAtom': ('fuzzy_prop', ), 911 'ChangeProperty': [((8, b''), ), 912 ((8, b'foo'), ), 913 ((8, b'zoom'), ), 914 ((16, []), ), 915 ((16, [1, 2, 3]), ), 916 ((16, [1, 2, 3, 4]), ), 917 ((32, []), ), 918 ((32, [1, 2, 3]), ) ], 919 'OpenFont': ('foofont', ), 920 'QueryTextExtents': ('foo', ), 921 'ListFonts': ('bhazr', ), 922 'ListFontsWithInfo': ('bhazr2', ), 923 'SetFontPath': [(['foo', 'bar', 'gazonk'], ), 924 ([], ) ], 925 'SetDashes': (9, ), 926 'SetClipRectangles': [(('Rectangle', 2), ), 927 (('Rectangle', 0), ) ], 928 'PolyPoint': (('Point', 3), ), 929 'PolyLine': (('Point', 5), ), 930 'PolySegment': (('Segment', 1), ), 931 'PolyRectangle': (('Rectangle', 3), ), 932 'PolyArc': (('Arc', 3), ), 933 'FillPoly': (('Point', 3), ), 934 'PolyFillRectangle': (('Rectangle', 2), ), 935 'PolyFillArc': (('Arc', 1), ), 936 'PutImage': (b'\xe9\x10\xf2o\x7f{\xae-\xe6\x18\xce\x83', ), 937 'ImageText8': ('showme', ), 938 'ImageText16': ('showmore', ), 939 'AllocNamedColor': ('octarin', ), 940 'FreeColors': (17, ), 941 'StoreColors': (('ColorItem', 4), ), 942 'StoreNamedColor': ('blue', ), 943 'QueryColors': [(8, ), (0, ) ], 944 'LookupColor': ('octarin', ), 945 'QueryExtension': ('XTRA', ), 946 'ChangeHosts': (4, ), 947 'RotateProperties': (12, ), 948 'SetPointerMapping': (5, ), 949 } 950 951reply_var_defs = { 952 'QueryTree': (7, ), 953 'GetAtomName': ('WM_CLASS', ), 954 'GetProperty': [((8, b''), ), 955 ((8, b'foo'), ), 956 ((8, b'zoom'), ), 957 ((16, []), ), 958 ((16, [1, 2, 3]), ), 959 ((16, [1, 2, 3, 4]), ), 960 ((32, []), ), 961 ((32, [1, 2, 3]), ) ], 962 'ListProperties': (23, ), 963 'GetMotionEvents': (('Timecoord', 5), ), 964 'QueryKeymap': (32, ), 965 'QueryFont': (('FontProp', 1), ('CharInfo', 3)), 966 'ListFonts': (['fie', 'fuzzy', 'foozooom'], ), 967 'ListFontsWithInfo': (('FontProp', 1), 'fontfont'), 968 'GetFontPath': [(['path1', 'path2232'], ), 969 ([], ) ], 970 'GetImage': (b'\xeb?:\xa7\xc6\x8b\xc2\x96o-S\xe6\xd6z6\x94\xd7v\xd2R.\xa2\xeaw\t\x13\x95\x85',), 971 'ListInstalledColormaps': (2, ), 972 'AllocColorCells': [(17, 3), 973 (0, 0) ], 974 'AllocColorPlanes': (4, ), 975 'QueryColors': (('rgb', 5), ), 976 'ListExtensions': (['XTRA', 'XTRA-II'], ), 977 'GetKeyboardControl': (32, ), 978 'GetPointerMapping': (5, ), 979# '': (, ), 980 } 981 982event_var_defs = { 983 'ClientMessage': [((8, b'01234567890123456789'), ), 984 ((16, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), ), 985 ((32, [1, 2, 3, 4, 5]), ) ], 986 } 987 988structcode_defs = { 989 'b': ('INT8', -128, -1, 1), 990 'B': ('CARD8', 128, 255, 1), 991 'h': ('INT16', -32768, -1, 2), 992 'H': ('CARD16', 32768, 65536, 2), 993 'l': ('INT32', -2147483647, -1, 4), 994 'L': ('CARD32', 65536, 2147483646, 4), 995 } 996 997C_HEADER = r''' 998#include <stdio.h> 999#include <assert.h> 1000#include <ctype.h> 1001#include <string.h> 1002#include <X11/Xproto.h> 1003 1004void output(char *name, void *data, int length) 1005{ 1006 unsigned char *d = (unsigned char *) data; 1007 1008 printf("%s ", name); 1009 1010 while (length-- > 0) { 1011 if (0 && isgraph(*d)) 1012 putchar(*d); 1013 else 1014 printf("\\x%02x", *d); 1015 d++; 1016 } 1017 1018 putchar('\n'); 1019} 1020 1021''' 1022 1023PY_HEADER = r'''#!/usr/bin/env python2 1024 1025import sys, os 1026sys.path.insert(0, os.path.normpath(os.path.join(__file__, '../..'))) 1027 1028import unittest 1029from Xlib.protocol import request, event 1030from . import %(endname)sTest as EndianTest 1031from . import DummyDisplay 1032 1033dummy_display = DummyDisplay() 1034''' 1035 1036if __name__ == '__main__': 1037 build() 1038