1# 2# DEPRECATED: implementation for ffi.verify() 3# 4import sys, os 5import types 6 7from . import model 8from .error import VerificationError 9 10 11class VGenericEngine(object): 12 _class_key = 'g' 13 _gen_python_module = False 14 15 def __init__(self, verifier): 16 self.verifier = verifier 17 self.ffi = verifier.ffi 18 self.export_symbols = [] 19 self._struct_pending_verification = {} 20 21 def patch_extension_kwds(self, kwds): 22 # add 'export_symbols' to the dictionary. Note that we add the 23 # list before filling it. When we fill it, it will thus also show 24 # up in kwds['export_symbols']. 25 kwds.setdefault('export_symbols', self.export_symbols) 26 27 def find_module(self, module_name, path, so_suffixes): 28 for so_suffix in so_suffixes: 29 basename = module_name + so_suffix 30 if path is None: 31 path = sys.path 32 for dirname in path: 33 filename = os.path.join(dirname, basename) 34 if os.path.isfile(filename): 35 return filename 36 37 def collect_types(self): 38 pass # not needed in the generic engine 39 40 def _prnt(self, what=''): 41 self._f.write(what + '\n') 42 43 def write_source_to_f(self): 44 prnt = self._prnt 45 # first paste some standard set of lines that are mostly '#include' 46 prnt(cffimod_header) 47 # then paste the C source given by the user, verbatim. 48 prnt(self.verifier.preamble) 49 # 50 # call generate_gen_xxx_decl(), for every xxx found from 51 # ffi._parser._declarations. This generates all the functions. 52 self._generate('decl') 53 # 54 # on Windows, distutils insists on putting init_cffi_xyz in 55 # 'export_symbols', so instead of fighting it, just give up and 56 # give it one 57 if sys.platform == 'win32': 58 if sys.version_info >= (3,): 59 prefix = 'PyInit_' 60 else: 61 prefix = 'init' 62 modname = self.verifier.get_module_name() 63 prnt("void %s%s(void) { }\n" % (prefix, modname)) 64 65 def load_library(self, flags=0): 66 # import it with the CFFI backend 67 backend = self.ffi._backend 68 # needs to make a path that contains '/', on Posix 69 filename = os.path.join(os.curdir, self.verifier.modulefilename) 70 module = backend.load_library(filename, flags) 71 # 72 # call loading_gen_struct() to get the struct layout inferred by 73 # the C compiler 74 self._load(module, 'loading') 75 76 # build the FFILibrary class and instance, this is a module subclass 77 # because modules are expected to have usually-constant-attributes and 78 # in PyPy this means the JIT is able to treat attributes as constant, 79 # which we want. 80 class FFILibrary(types.ModuleType): 81 _cffi_generic_module = module 82 _cffi_ffi = self.ffi 83 _cffi_dir = [] 84 def __dir__(self): 85 return FFILibrary._cffi_dir 86 library = FFILibrary("") 87 # 88 # finally, call the loaded_gen_xxx() functions. This will set 89 # up the 'library' object. 90 self._load(module, 'loaded', library=library) 91 return library 92 93 def _get_declarations(self): 94 lst = [(key, tp) for (key, (tp, qual)) in 95 self.ffi._parser._declarations.items()] 96 lst.sort() 97 return lst 98 99 def _generate(self, step_name): 100 for name, tp in self._get_declarations(): 101 kind, realname = name.split(' ', 1) 102 try: 103 method = getattr(self, '_generate_gen_%s_%s' % (kind, 104 step_name)) 105 except AttributeError: 106 raise VerificationError( 107 "not implemented in verify(): %r" % name) 108 try: 109 method(tp, realname) 110 except Exception as e: 111 model.attach_exception_info(e, name) 112 raise 113 114 def _load(self, module, step_name, **kwds): 115 for name, tp in self._get_declarations(): 116 kind, realname = name.split(' ', 1) 117 method = getattr(self, '_%s_gen_%s' % (step_name, kind)) 118 try: 119 method(tp, realname, module, **kwds) 120 except Exception as e: 121 model.attach_exception_info(e, name) 122 raise 123 124 def _generate_nothing(self, tp, name): 125 pass 126 127 def _loaded_noop(self, tp, name, module, **kwds): 128 pass 129 130 # ---------- 131 # typedefs: generates no code so far 132 133 _generate_gen_typedef_decl = _generate_nothing 134 _loading_gen_typedef = _loaded_noop 135 _loaded_gen_typedef = _loaded_noop 136 137 # ---------- 138 # function declarations 139 140 def _generate_gen_function_decl(self, tp, name): 141 assert isinstance(tp, model.FunctionPtrType) 142 if tp.ellipsis: 143 # cannot support vararg functions better than this: check for its 144 # exact type (including the fixed arguments), and build it as a 145 # constant function pointer (no _cffi_f_%s wrapper) 146 self._generate_gen_const(False, name, tp) 147 return 148 prnt = self._prnt 149 numargs = len(tp.args) 150 argnames = [] 151 for i, type in enumerate(tp.args): 152 indirection = '' 153 if isinstance(type, model.StructOrUnion): 154 indirection = '*' 155 argnames.append('%sx%d' % (indirection, i)) 156 context = 'argument of %s' % name 157 arglist = [type.get_c_name(' %s' % arg, context) 158 for type, arg in zip(tp.args, argnames)] 159 tpresult = tp.result 160 if isinstance(tpresult, model.StructOrUnion): 161 arglist.insert(0, tpresult.get_c_name(' *r', context)) 162 tpresult = model.void_type 163 arglist = ', '.join(arglist) or 'void' 164 wrappername = '_cffi_f_%s' % name 165 self.export_symbols.append(wrappername) 166 if tp.abi: 167 abi = tp.abi + ' ' 168 else: 169 abi = '' 170 funcdecl = ' %s%s(%s)' % (abi, wrappername, arglist) 171 context = 'result of %s' % name 172 prnt(tpresult.get_c_name(funcdecl, context)) 173 prnt('{') 174 # 175 if isinstance(tp.result, model.StructOrUnion): 176 result_code = '*r = ' 177 elif not isinstance(tp.result, model.VoidType): 178 result_code = 'return ' 179 else: 180 result_code = '' 181 prnt(' %s%s(%s);' % (result_code, name, ', '.join(argnames))) 182 prnt('}') 183 prnt() 184 185 _loading_gen_function = _loaded_noop 186 187 def _loaded_gen_function(self, tp, name, module, library): 188 assert isinstance(tp, model.FunctionPtrType) 189 if tp.ellipsis: 190 newfunction = self._load_constant(False, tp, name, module) 191 else: 192 indirections = [] 193 base_tp = tp 194 if (any(isinstance(typ, model.StructOrUnion) for typ in tp.args) 195 or isinstance(tp.result, model.StructOrUnion)): 196 indirect_args = [] 197 for i, typ in enumerate(tp.args): 198 if isinstance(typ, model.StructOrUnion): 199 typ = model.PointerType(typ) 200 indirections.append((i, typ)) 201 indirect_args.append(typ) 202 indirect_result = tp.result 203 if isinstance(indirect_result, model.StructOrUnion): 204 if indirect_result.fldtypes is None: 205 raise TypeError("'%s' is used as result type, " 206 "but is opaque" % ( 207 indirect_result._get_c_name(),)) 208 indirect_result = model.PointerType(indirect_result) 209 indirect_args.insert(0, indirect_result) 210 indirections.insert(0, ("result", indirect_result)) 211 indirect_result = model.void_type 212 tp = model.FunctionPtrType(tuple(indirect_args), 213 indirect_result, tp.ellipsis) 214 BFunc = self.ffi._get_cached_btype(tp) 215 wrappername = '_cffi_f_%s' % name 216 newfunction = module.load_function(BFunc, wrappername) 217 for i, typ in indirections: 218 newfunction = self._make_struct_wrapper(newfunction, i, typ, 219 base_tp) 220 setattr(library, name, newfunction) 221 type(library)._cffi_dir.append(name) 222 223 def _make_struct_wrapper(self, oldfunc, i, tp, base_tp): 224 backend = self.ffi._backend 225 BType = self.ffi._get_cached_btype(tp) 226 if i == "result": 227 ffi = self.ffi 228 def newfunc(*args): 229 res = ffi.new(BType) 230 oldfunc(res, *args) 231 return res[0] 232 else: 233 def newfunc(*args): 234 args = args[:i] + (backend.newp(BType, args[i]),) + args[i+1:] 235 return oldfunc(*args) 236 newfunc._cffi_base_type = base_tp 237 return newfunc 238 239 # ---------- 240 # named structs 241 242 def _generate_gen_struct_decl(self, tp, name): 243 assert name == tp.name 244 self._generate_struct_or_union_decl(tp, 'struct', name) 245 246 def _loading_gen_struct(self, tp, name, module): 247 self._loading_struct_or_union(tp, 'struct', name, module) 248 249 def _loaded_gen_struct(self, tp, name, module, **kwds): 250 self._loaded_struct_or_union(tp) 251 252 def _generate_gen_union_decl(self, tp, name): 253 assert name == tp.name 254 self._generate_struct_or_union_decl(tp, 'union', name) 255 256 def _loading_gen_union(self, tp, name, module): 257 self._loading_struct_or_union(tp, 'union', name, module) 258 259 def _loaded_gen_union(self, tp, name, module, **kwds): 260 self._loaded_struct_or_union(tp) 261 262 def _generate_struct_or_union_decl(self, tp, prefix, name): 263 if tp.fldnames is None: 264 return # nothing to do with opaque structs 265 checkfuncname = '_cffi_check_%s_%s' % (prefix, name) 266 layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) 267 cname = ('%s %s' % (prefix, name)).strip() 268 # 269 prnt = self._prnt 270 prnt('static void %s(%s *p)' % (checkfuncname, cname)) 271 prnt('{') 272 prnt(' /* only to generate compile-time warnings or errors */') 273 prnt(' (void)p;') 274 for fname, ftype, fbitsize, fqual in tp.enumfields(): 275 if (isinstance(ftype, model.PrimitiveType) 276 and ftype.is_integer_type()) or fbitsize >= 0: 277 # accept all integers, but complain on float or double 278 prnt(' (void)((p->%s) << 1);' % fname) 279 else: 280 # only accept exactly the type declared. 281 try: 282 prnt(' { %s = &p->%s; (void)tmp; }' % ( 283 ftype.get_c_name('*tmp', 'field %r'%fname, quals=fqual), 284 fname)) 285 except VerificationError as e: 286 prnt(' /* %s */' % str(e)) # cannot verify it, ignore 287 prnt('}') 288 self.export_symbols.append(layoutfuncname) 289 prnt('intptr_t %s(intptr_t i)' % (layoutfuncname,)) 290 prnt('{') 291 prnt(' struct _cffi_aligncheck { char x; %s y; };' % cname) 292 prnt(' static intptr_t nums[] = {') 293 prnt(' sizeof(%s),' % cname) 294 prnt(' offsetof(struct _cffi_aligncheck, y),') 295 for fname, ftype, fbitsize, fqual in tp.enumfields(): 296 if fbitsize >= 0: 297 continue # xxx ignore fbitsize for now 298 prnt(' offsetof(%s, %s),' % (cname, fname)) 299 if isinstance(ftype, model.ArrayType) and ftype.length is None: 300 prnt(' 0, /* %s */' % ftype._get_c_name()) 301 else: 302 prnt(' sizeof(((%s *)0)->%s),' % (cname, fname)) 303 prnt(' -1') 304 prnt(' };') 305 prnt(' return nums[i];') 306 prnt(' /* the next line is not executed, but compiled */') 307 prnt(' %s(0);' % (checkfuncname,)) 308 prnt('}') 309 prnt() 310 311 def _loading_struct_or_union(self, tp, prefix, name, module): 312 if tp.fldnames is None: 313 return # nothing to do with opaque structs 314 layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) 315 # 316 BFunc = self.ffi._typeof_locked("intptr_t(*)(intptr_t)")[0] 317 function = module.load_function(BFunc, layoutfuncname) 318 layout = [] 319 num = 0 320 while True: 321 x = function(num) 322 if x < 0: break 323 layout.append(x) 324 num += 1 325 if isinstance(tp, model.StructOrUnion) and tp.partial: 326 # use the function()'s sizes and offsets to guide the 327 # layout of the struct 328 totalsize = layout[0] 329 totalalignment = layout[1] 330 fieldofs = layout[2::2] 331 fieldsize = layout[3::2] 332 tp.force_flatten() 333 assert len(fieldofs) == len(fieldsize) == len(tp.fldnames) 334 tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment 335 else: 336 cname = ('%s %s' % (prefix, name)).strip() 337 self._struct_pending_verification[tp] = layout, cname 338 339 def _loaded_struct_or_union(self, tp): 340 if tp.fldnames is None: 341 return # nothing to do with opaque structs 342 self.ffi._get_cached_btype(tp) # force 'fixedlayout' to be considered 343 344 if tp in self._struct_pending_verification: 345 # check that the layout sizes and offsets match the real ones 346 def check(realvalue, expectedvalue, msg): 347 if realvalue != expectedvalue: 348 raise VerificationError( 349 "%s (we have %d, but C compiler says %d)" 350 % (msg, expectedvalue, realvalue)) 351 ffi = self.ffi 352 BStruct = ffi._get_cached_btype(tp) 353 layout, cname = self._struct_pending_verification.pop(tp) 354 check(layout[0], ffi.sizeof(BStruct), "wrong total size") 355 check(layout[1], ffi.alignof(BStruct), "wrong total alignment") 356 i = 2 357 for fname, ftype, fbitsize, fqual in tp.enumfields(): 358 if fbitsize >= 0: 359 continue # xxx ignore fbitsize for now 360 check(layout[i], ffi.offsetof(BStruct, fname), 361 "wrong offset for field %r" % (fname,)) 362 if layout[i+1] != 0: 363 BField = ffi._get_cached_btype(ftype) 364 check(layout[i+1], ffi.sizeof(BField), 365 "wrong size for field %r" % (fname,)) 366 i += 2 367 assert i == len(layout) 368 369 # ---------- 370 # 'anonymous' declarations. These are produced for anonymous structs 371 # or unions; the 'name' is obtained by a typedef. 372 373 def _generate_gen_anonymous_decl(self, tp, name): 374 if isinstance(tp, model.EnumType): 375 self._generate_gen_enum_decl(tp, name, '') 376 else: 377 self._generate_struct_or_union_decl(tp, '', name) 378 379 def _loading_gen_anonymous(self, tp, name, module): 380 if isinstance(tp, model.EnumType): 381 self._loading_gen_enum(tp, name, module, '') 382 else: 383 self._loading_struct_or_union(tp, '', name, module) 384 385 def _loaded_gen_anonymous(self, tp, name, module, **kwds): 386 if isinstance(tp, model.EnumType): 387 self._loaded_gen_enum(tp, name, module, **kwds) 388 else: 389 self._loaded_struct_or_union(tp) 390 391 # ---------- 392 # constants, likely declared with '#define' 393 394 def _generate_gen_const(self, is_int, name, tp=None, category='const', 395 check_value=None): 396 prnt = self._prnt 397 funcname = '_cffi_%s_%s' % (category, name) 398 self.export_symbols.append(funcname) 399 if check_value is not None: 400 assert is_int 401 assert category == 'const' 402 prnt('int %s(char *out_error)' % funcname) 403 prnt('{') 404 self._check_int_constant_value(name, check_value) 405 prnt(' return 0;') 406 prnt('}') 407 elif is_int: 408 assert category == 'const' 409 prnt('int %s(long long *out_value)' % funcname) 410 prnt('{') 411 prnt(' *out_value = (long long)(%s);' % (name,)) 412 prnt(' return (%s) <= 0;' % (name,)) 413 prnt('}') 414 else: 415 assert tp is not None 416 assert check_value is None 417 if category == 'var': 418 ampersand = '&' 419 else: 420 ampersand = '' 421 extra = '' 422 if category == 'const' and isinstance(tp, model.StructOrUnion): 423 extra = 'const *' 424 ampersand = '&' 425 prnt(tp.get_c_name(' %s%s(void)' % (extra, funcname), name)) 426 prnt('{') 427 prnt(' return (%s%s);' % (ampersand, name)) 428 prnt('}') 429 prnt() 430 431 def _generate_gen_constant_decl(self, tp, name): 432 is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() 433 self._generate_gen_const(is_int, name, tp) 434 435 _loading_gen_constant = _loaded_noop 436 437 def _load_constant(self, is_int, tp, name, module, check_value=None): 438 funcname = '_cffi_const_%s' % name 439 if check_value is not None: 440 assert is_int 441 self._load_known_int_constant(module, funcname) 442 value = check_value 443 elif is_int: 444 BType = self.ffi._typeof_locked("long long*")[0] 445 BFunc = self.ffi._typeof_locked("int(*)(long long*)")[0] 446 function = module.load_function(BFunc, funcname) 447 p = self.ffi.new(BType) 448 negative = function(p) 449 value = int(p[0]) 450 if value < 0 and not negative: 451 BLongLong = self.ffi._typeof_locked("long long")[0] 452 value += (1 << (8*self.ffi.sizeof(BLongLong))) 453 else: 454 assert check_value is None 455 fntypeextra = '(*)(void)' 456 if isinstance(tp, model.StructOrUnion): 457 fntypeextra = '*' + fntypeextra 458 BFunc = self.ffi._typeof_locked(tp.get_c_name(fntypeextra, name))[0] 459 function = module.load_function(BFunc, funcname) 460 value = function() 461 if isinstance(tp, model.StructOrUnion): 462 value = value[0] 463 return value 464 465 def _loaded_gen_constant(self, tp, name, module, library): 466 is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() 467 value = self._load_constant(is_int, tp, name, module) 468 setattr(library, name, value) 469 type(library)._cffi_dir.append(name) 470 471 # ---------- 472 # enums 473 474 def _check_int_constant_value(self, name, value): 475 prnt = self._prnt 476 if value <= 0: 477 prnt(' if ((%s) > 0 || (long)(%s) != %dL) {' % ( 478 name, name, value)) 479 else: 480 prnt(' if ((%s) <= 0 || (unsigned long)(%s) != %dUL) {' % ( 481 name, name, value)) 482 prnt(' char buf[64];') 483 prnt(' if ((%s) <= 0)' % name) 484 prnt(' sprintf(buf, "%%ld", (long)(%s));' % name) 485 prnt(' else') 486 prnt(' sprintf(buf, "%%lu", (unsigned long)(%s));' % 487 name) 488 prnt(' sprintf(out_error, "%s has the real value %s, not %s",') 489 prnt(' "%s", buf, "%d");' % (name[:100], value)) 490 prnt(' return -1;') 491 prnt(' }') 492 493 def _load_known_int_constant(self, module, funcname): 494 BType = self.ffi._typeof_locked("char[]")[0] 495 BFunc = self.ffi._typeof_locked("int(*)(char*)")[0] 496 function = module.load_function(BFunc, funcname) 497 p = self.ffi.new(BType, 256) 498 if function(p) < 0: 499 error = self.ffi.string(p) 500 if sys.version_info >= (3,): 501 error = str(error, 'utf-8') 502 raise VerificationError(error) 503 504 def _enum_funcname(self, prefix, name): 505 # "$enum_$1" => "___D_enum____D_1" 506 name = name.replace('$', '___D_') 507 return '_cffi_e_%s_%s' % (prefix, name) 508 509 def _generate_gen_enum_decl(self, tp, name, prefix='enum'): 510 if tp.partial: 511 for enumerator in tp.enumerators: 512 self._generate_gen_const(True, enumerator) 513 return 514 # 515 funcname = self._enum_funcname(prefix, name) 516 self.export_symbols.append(funcname) 517 prnt = self._prnt 518 prnt('int %s(char *out_error)' % funcname) 519 prnt('{') 520 for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): 521 self._check_int_constant_value(enumerator, enumvalue) 522 prnt(' return 0;') 523 prnt('}') 524 prnt() 525 526 def _loading_gen_enum(self, tp, name, module, prefix='enum'): 527 if tp.partial: 528 enumvalues = [self._load_constant(True, tp, enumerator, module) 529 for enumerator in tp.enumerators] 530 tp.enumvalues = tuple(enumvalues) 531 tp.partial_resolved = True 532 else: 533 funcname = self._enum_funcname(prefix, name) 534 self._load_known_int_constant(module, funcname) 535 536 def _loaded_gen_enum(self, tp, name, module, library): 537 for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): 538 setattr(library, enumerator, enumvalue) 539 type(library)._cffi_dir.append(enumerator) 540 541 # ---------- 542 # macros: for now only for integers 543 544 def _generate_gen_macro_decl(self, tp, name): 545 if tp == '...': 546 check_value = None 547 else: 548 check_value = tp # an integer 549 self._generate_gen_const(True, name, check_value=check_value) 550 551 _loading_gen_macro = _loaded_noop 552 553 def _loaded_gen_macro(self, tp, name, module, library): 554 if tp == '...': 555 check_value = None 556 else: 557 check_value = tp # an integer 558 value = self._load_constant(True, tp, name, module, 559 check_value=check_value) 560 setattr(library, name, value) 561 type(library)._cffi_dir.append(name) 562 563 # ---------- 564 # global variables 565 566 def _generate_gen_variable_decl(self, tp, name): 567 if isinstance(tp, model.ArrayType): 568 if tp.length == '...': 569 prnt = self._prnt 570 funcname = '_cffi_sizeof_%s' % (name,) 571 self.export_symbols.append(funcname) 572 prnt("size_t %s(void)" % funcname) 573 prnt("{") 574 prnt(" return sizeof(%s);" % (name,)) 575 prnt("}") 576 tp_ptr = model.PointerType(tp.item) 577 self._generate_gen_const(False, name, tp_ptr) 578 else: 579 tp_ptr = model.PointerType(tp) 580 self._generate_gen_const(False, name, tp_ptr, category='var') 581 582 _loading_gen_variable = _loaded_noop 583 584 def _loaded_gen_variable(self, tp, name, module, library): 585 if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the 586 # sense that "a=..." is forbidden 587 if tp.length == '...': 588 funcname = '_cffi_sizeof_%s' % (name,) 589 BFunc = self.ffi._typeof_locked('size_t(*)(void)')[0] 590 function = module.load_function(BFunc, funcname) 591 size = function() 592 BItemType = self.ffi._get_cached_btype(tp.item) 593 length, rest = divmod(size, self.ffi.sizeof(BItemType)) 594 if rest != 0: 595 raise VerificationError( 596 "bad size: %r does not seem to be an array of %s" % 597 (name, tp.item)) 598 tp = tp.resolve_length(length) 599 tp_ptr = model.PointerType(tp.item) 600 value = self._load_constant(False, tp_ptr, name, module) 601 # 'value' is a <cdata 'type *'> which we have to replace with 602 # a <cdata 'type[N]'> if the N is actually known 603 if tp.length is not None: 604 BArray = self.ffi._get_cached_btype(tp) 605 value = self.ffi.cast(BArray, value) 606 setattr(library, name, value) 607 type(library)._cffi_dir.append(name) 608 return 609 # remove ptr=<cdata 'int *'> from the library instance, and replace 610 # it by a property on the class, which reads/writes into ptr[0]. 611 funcname = '_cffi_var_%s' % name 612 BFunc = self.ffi._typeof_locked(tp.get_c_name('*(*)(void)', name))[0] 613 function = module.load_function(BFunc, funcname) 614 ptr = function() 615 def getter(library): 616 return ptr[0] 617 def setter(library, value): 618 ptr[0] = value 619 setattr(type(library), name, property(getter, setter)) 620 type(library)._cffi_dir.append(name) 621 622cffimod_header = r''' 623#include <stdio.h> 624#include <stddef.h> 625#include <stdarg.h> 626#include <errno.h> 627#include <sys/types.h> /* XXX for ssize_t on some platforms */ 628 629/* this block of #ifs should be kept exactly identical between 630 c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py 631 and cffi/_cffi_include.h */ 632#if defined(_MSC_VER) 633# include <malloc.h> /* for alloca() */ 634# if _MSC_VER < 1600 /* MSVC < 2010 */ 635 typedef __int8 int8_t; 636 typedef __int16 int16_t; 637 typedef __int32 int32_t; 638 typedef __int64 int64_t; 639 typedef unsigned __int8 uint8_t; 640 typedef unsigned __int16 uint16_t; 641 typedef unsigned __int32 uint32_t; 642 typedef unsigned __int64 uint64_t; 643 typedef __int8 int_least8_t; 644 typedef __int16 int_least16_t; 645 typedef __int32 int_least32_t; 646 typedef __int64 int_least64_t; 647 typedef unsigned __int8 uint_least8_t; 648 typedef unsigned __int16 uint_least16_t; 649 typedef unsigned __int32 uint_least32_t; 650 typedef unsigned __int64 uint_least64_t; 651 typedef __int8 int_fast8_t; 652 typedef __int16 int_fast16_t; 653 typedef __int32 int_fast32_t; 654 typedef __int64 int_fast64_t; 655 typedef unsigned __int8 uint_fast8_t; 656 typedef unsigned __int16 uint_fast16_t; 657 typedef unsigned __int32 uint_fast32_t; 658 typedef unsigned __int64 uint_fast64_t; 659 typedef __int64 intmax_t; 660 typedef unsigned __int64 uintmax_t; 661# else 662# include <stdint.h> 663# endif 664# if _MSC_VER < 1800 /* MSVC < 2013 */ 665# ifndef __cplusplus 666 typedef unsigned char _Bool; 667# endif 668# endif 669#else 670# include <stdint.h> 671# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) 672# include <alloca.h> 673# endif 674#endif 675''' 676