<s> from . import api , model <EOL> from . commontypes import COMMON_TYPES , resolve_common_type <EOL> try : <EOL> from . import _pycparser as pycparser <EOL> except ImportError : <EOL> import pycparser <EOL> import weakref , re , sys <EOL> try : <EOL> if sys . version_info < ( <NUM_LIT:3> , ) : <EOL> import thread as _thread <EOL> else : <EOL> import _thread <EOL> lock = _thread . allocate_lock ( ) <EOL> except ImportError : <EOL> lock = None <EOL> _r_comment = re . compile ( r"<STR_LIT>" , <EOL> re . DOTALL | re . MULTILINE ) <EOL> _r_define = re . compile ( r"<STR_LIT>" <EOL> r"<STR_LIT>" , <EOL> re . DOTALL | re . MULTILINE ) <EOL> _r_partial_enum = re . compile ( r"<STR_LIT>" ) <EOL> _r_enum_dotdotdot = re . compile ( r"<STR_LIT>" ) <EOL> _r_partial_array = re . compile ( r"<STR_LIT>" ) <EOL> _r_words = re . compile ( r"<STR_LIT>" ) <EOL> _parser_cache = None <EOL> _r_int_literal = re . compile ( r"<STR_LIT>" , re . IGNORECASE ) <EOL> _r_stdcall1 = re . compile ( r"<STR_LIT>" ) <EOL> _r_stdcall2 = re . compile ( r"<STR_LIT>" ) <EOL> _r_cdecl = re . compile ( r"<STR_LIT>" ) <EOL> _r_extern_python = re . compile ( r'<STR_LIT>' ) <EOL> _r_star_const_space = re . compile ( <EOL> r"<STR_LIT>" ) <EOL> def _get_parser ( ) : <EOL> global _parser_cache <EOL> if _parser_cache is None : <EOL> _parser_cache = pycparser . CParser ( ) <EOL> return _parser_cache <EOL> def _workaround_for_old_pycparser ( csource ) : <EOL> parts = [ ] <EOL> while True : <EOL> match = _r_star_const_space . search ( csource ) <EOL> if not match : <EOL> break <EOL> parts . append ( csource [ : match . start ( ) ] ) <EOL> parts . append ( '<STR_LIT:(>' ) ; closing = '<STR_LIT:)>' <EOL> parts . append ( match . group ( ) ) <EOL> endpos = match . end ( ) <EOL> if csource . startswith ( '<STR_LIT:*>' , endpos ) : <EOL> parts . append ( '<STR_LIT:(>' ) ; closing += '<STR_LIT:)>' <EOL> level = <NUM_LIT:0> <EOL> i = endpos <EOL> while i < len ( csource ) : <EOL> c = csource [ i ] <EOL> if c == '<STR_LIT:(>' : <EOL> level += <NUM_LIT:1> <EOL> elif c == '<STR_LIT:)>' : <EOL> if level == <NUM_LIT:0> : <EOL> break <EOL> level -= <NUM_LIT:1> <EOL> elif c in '<STR_LIT>' : <EOL> if level == <NUM_LIT:0> : <EOL> break <EOL> i += <NUM_LIT:1> <EOL> csource = csource [ endpos : i ] + closing + csource [ i : ] <EOL> parts . append ( csource ) <EOL> return '<STR_LIT>' . join ( parts ) <EOL> def _preprocess_extern_python ( csource ) : <EOL> parts = [ ] <EOL> while True : <EOL> match = _r_extern_python . search ( csource ) <EOL> if not match : <EOL> break <EOL> endpos = match . end ( ) - <NUM_LIT:1> <EOL> parts . append ( csource [ : match . start ( ) ] ) <EOL> parts . append ( '<STR_LIT>' ) <EOL> if csource [ endpos ] == '<STR_LIT:{>' : <EOL> closing = csource . find ( '<STR_LIT:}>' , endpos ) <EOL> if closing < <NUM_LIT:0> : <EOL> raise api . CDefError ( "<STR_LIT>" ) <EOL> if csource . find ( '<STR_LIT:{>' , endpos + <NUM_LIT:1> , closing ) >= <NUM_LIT:0> : <EOL> raise NotImplementedError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> parts . append ( csource [ endpos + <NUM_LIT:1> : closing ] ) <EOL> csource = csource [ closing + <NUM_LIT:1> : ] <EOL> else : <EOL> semicolon = csource . find ( '<STR_LIT:;>' , endpos ) <EOL> if semicolon < <NUM_LIT:0> : <EOL> raise api . CDefError ( "<STR_LIT>" ) <EOL> parts . append ( csource [ endpos : semicolon + <NUM_LIT:1> ] ) <EOL> csource = csource [ semicolon + <NUM_LIT:1> : ] <EOL> parts . append ( '<STR_LIT>' ) <EOL> parts . append ( csource ) <EOL> return '<STR_LIT>' . join ( parts ) <EOL> def _preprocess ( csource ) : <EOL> csource = _r_comment . sub ( '<STR_LIT:U+0020>' , csource ) <EOL> macros = { } <EOL> for match in _r_define . finditer ( csource ) : <EOL> macroname , macrovalue = match . groups ( ) <EOL> macrovalue = macrovalue . replace ( '<STR_LIT>' , '<STR_LIT>' ) . strip ( ) <EOL> macros [ macroname ] = macrovalue <EOL> csource = _r_define . sub ( '<STR_LIT>' , csource ) <EOL> if pycparser . __version__ < '<STR_LIT>' : <EOL> csource = _workaround_for_old_pycparser ( csource ) <EOL> csource = _r_stdcall2 . sub ( '<STR_LIT>' , csource ) <EOL> csource = _r_stdcall1 . sub ( '<STR_LIT>' , csource ) <EOL> csource = _r_cdecl . sub ( '<STR_LIT:U+0020>' , csource ) <EOL> csource = _preprocess_extern_python ( csource ) <EOL> csource = _r_partial_array . sub ( '<STR_LIT>' , csource ) <EOL> matches = list ( _r_partial_enum . finditer ( csource ) ) <EOL> for number , match in enumerate ( reversed ( matches ) ) : <EOL> p = match . start ( ) <EOL> if csource [ p ] == '<STR_LIT:=>' : <EOL> p2 = csource . find ( '<STR_LIT>' , p , match . end ( ) ) <EOL> assert p2 > p <EOL> csource = '<STR_LIT>' % ( csource [ : p ] , number , <EOL> csource [ p2 + <NUM_LIT:3> : ] ) <EOL> else : <EOL> assert csource [ p : p + <NUM_LIT:3> ] == '<STR_LIT>' <EOL> csource = '<STR_LIT>' % ( csource [ : p ] , number , <EOL> csource [ p + <NUM_LIT:3> : ] ) <EOL> return csource . replace ( '<STR_LIT>' , '<STR_LIT>' ) , macros <EOL> def _common_type_names ( csource ) : <EOL> look_for_words = set ( COMMON_TYPES ) <EOL> look_for_words . add ( '<STR_LIT:;>' ) <EOL> look_for_words . add ( '<STR_LIT:U+002C>' ) <EOL> look_for_words . add ( '<STR_LIT:(>' ) <EOL> look_for_words . add ( '<STR_LIT:)>' ) <EOL> look_for_words . add ( '<STR_LIT>' ) <EOL> words_used = set ( ) <EOL> is_typedef = False <EOL> paren = <NUM_LIT:0> <EOL> previous_word = '<STR_LIT>' <EOL> for word in _r_words . findall ( csource ) : <EOL> if word in look_for_words : <EOL> if word == '<STR_LIT:;>' : <EOL> if is_typedef : <EOL> words_used . discard ( previous_word ) <EOL> look_for_words . discard ( previous_word ) <EOL> is_typedef = False <EOL> elif word == '<STR_LIT>' : <EOL> is_typedef = True <EOL> paren = <NUM_LIT:0> <EOL> elif word == '<STR_LIT:(>' : <EOL> paren += <NUM_LIT:1> <EOL> elif word == '<STR_LIT:)>' : <EOL> paren -= <NUM_LIT:1> <EOL> elif word == '<STR_LIT:U+002C>' : <EOL> if is_typedef and paren == <NUM_LIT:0> : <EOL> words_used . discard ( previous_word ) <EOL> look_for_words . discard ( previous_word ) <EOL> else : <EOL> words_used . add ( word ) <EOL> previous_word = word <EOL> return words_used <EOL> class Parser ( object ) : <EOL> def __init__ ( self ) : <EOL> self . _declarations = { } <EOL> self . _included_declarations = set ( ) <EOL> self . _anonymous_counter = <NUM_LIT:0> <EOL> self . _structnode2type = weakref . WeakKeyDictionary ( ) <EOL> self . _options = { } <EOL> self . _int_constants = { } <EOL> self . _recomplete = [ ] <EOL> self . _uses_new_feature = None <EOL> def _parse ( self , csource ) : <EOL> csource , macros = _preprocess ( csource ) <EOL> ctn = _common_type_names ( csource ) <EOL> typenames = [ ] <EOL> for name in sorted ( self . _declarations ) : <EOL> if name . startswith ( '<STR_LIT>' ) : <EOL> name = name [ <NUM_LIT:8> : ] <EOL> typenames . append ( name ) <EOL> ctn . discard ( name ) <EOL> typenames += sorted ( ctn ) <EOL> csourcelines = [ '<STR_LIT>' % typename for typename in typenames ] <EOL> csourcelines . append ( '<STR_LIT>' ) <EOL> csourcelines . append ( csource ) <EOL> csource = '<STR_LIT:\n>' . join ( csourcelines ) <EOL> if lock is not None : <EOL> lock . acquire ( ) <EOL> try : <EOL> ast = _get_parser ( ) . parse ( csource ) <EOL> except pycparser . c_parser . ParseError as e : <EOL> self . convert_pycparser_error ( e , csource ) <EOL> finally : <EOL> if lock is not None : <EOL> lock . release ( ) <EOL> return ast , macros , csource <EOL> def _convert_pycparser_error ( self , e , csource ) : <EOL> line = None <EOL> msg = str ( e ) <EOL> if msg . startswith ( '<STR_LIT::>' ) and '<STR_LIT::>' in msg [ <NUM_LIT:1> : ] : <EOL> linenum = msg [ <NUM_LIT:1> : msg . find ( '<STR_LIT::>' , <NUM_LIT:1> ) ] <EOL> if linenum . isdigit ( ) : <EOL> linenum = int ( linenum , <NUM_LIT:10> ) <EOL> csourcelines = csource . splitlines ( ) <EOL> if <NUM_LIT:1> <= linenum <= len ( csourcelines ) : <EOL> line = csourcelines [ linenum - <NUM_LIT:1> ] <EOL> return line <EOL> def convert_pycparser_error ( self , e , csource ) : <EOL> line = self . _convert_pycparser_error ( e , csource ) <EOL> msg = str ( e ) <EOL> if line : <EOL> msg = '<STR_LIT>' % ( line . strip ( ) , msg ) <EOL> else : <EOL> msg = '<STR_LIT>' % ( msg , ) <EOL> raise api . CDefError ( msg ) <EOL> def parse ( self , csource , override = False , packed = False , dllexport = False ) : <EOL> prev_options = self . _options <EOL> try : <EOL> self . _options = { '<STR_LIT>' : override , <EOL> '<STR_LIT>' : packed , <EOL> '<STR_LIT>' : dllexport } <EOL> self . _internal_parse ( csource ) <EOL> finally : <EOL> self . _options = prev_options <EOL> def _internal_parse ( self , csource ) : <EOL> ast , macros , csource = self . _parse ( csource ) <EOL> self . _process_macros ( macros ) <EOL> iterator = iter ( ast . ext ) <EOL> for decl in iterator : <EOL> if decl . name == '<STR_LIT>' : <EOL> break <EOL> try : <EOL> self . _inside_extern_python = False <EOL> for decl in iterator : <EOL> if isinstance ( decl , pycparser . c_ast . Decl ) : <EOL> self . _parse_decl ( decl ) <EOL> elif isinstance ( decl , pycparser . c_ast . Typedef ) : <EOL> if not decl . name : <EOL> raise api . CDefError ( "<STR_LIT>" , <EOL> decl ) <EOL> quals = <NUM_LIT:0> <EOL> if ( isinstance ( decl . type . type , pycparser . c_ast . IdentifierType ) <EOL> and decl . type . type . names [ - <NUM_LIT:1> ] == '<STR_LIT>' ) : <EOL> realtype = self . _get_unknown_type ( decl ) <EOL> elif ( isinstance ( decl . type , pycparser . c_ast . PtrDecl ) and <EOL> isinstance ( decl . type . type , pycparser . c_ast . TypeDecl ) and <EOL> isinstance ( decl . type . type . type , <EOL> pycparser . c_ast . IdentifierType ) and <EOL> decl . type . type . type . names == [ '<STR_LIT>' ] ) : <EOL> realtype = model . unknown_ptr_type ( decl . name ) <EOL> else : <EOL> realtype , quals = self . _get_type_and_quals ( <EOL> decl . type , name = decl . name ) <EOL> self . _declare ( '<STR_LIT>' + decl . name , realtype , quals = quals ) <EOL> else : <EOL> raise api . CDefError ( "<STR_LIT>" , decl ) <EOL> except api . FFIError as e : <EOL> msg = self . _convert_pycparser_error ( e , csource ) <EOL> if msg : <EOL> e . args = ( e . args [ <NUM_LIT:0> ] + "<STR_LIT>" % msg , ) <EOL> raise <EOL> def _add_constants ( self , key , val ) : <EOL> if key in self . _int_constants : <EOL> if self . _int_constants [ key ] == val : <EOL> return <EOL> raise api . FFIError ( <EOL> "<STR_LIT>" % ( key , ) ) <EOL> self . _int_constants [ key ] = val <EOL> def _add_integer_constant ( self , name , int_str ) : <EOL> int_str = int_str . lower ( ) . rstrip ( "<STR_LIT>" ) <EOL> neg = int_str . startswith ( '<STR_LIT:->' ) <EOL> if neg : <EOL> int_str = int_str [ <NUM_LIT:1> : ] <EOL> if ( int_str . startswith ( "<STR_LIT:0>" ) and int_str != '<STR_LIT:0>' <EOL> and not int_str . startswith ( "<STR_LIT>" ) ) : <EOL> int_str = "<STR_LIT>" + int_str [ <NUM_LIT:1> : ] <EOL> pyvalue = int ( int_str , <NUM_LIT:0> ) <EOL> if neg : <EOL> pyvalue = - pyvalue <EOL> self . _add_constants ( name , pyvalue ) <EOL> self . _declare ( '<STR_LIT>' + name , pyvalue ) <EOL> def _process_macros ( self , macros ) : <EOL> for key , value in macros . items ( ) : <EOL> value = value . strip ( ) <EOL> if _r_int_literal . match ( value ) : <EOL> self . _add_integer_constant ( key , value ) <EOL> elif value == '<STR_LIT>' : <EOL> self . _declare ( '<STR_LIT>' + key , value ) <EOL> else : <EOL> raise api . CDefError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> % ( key , key , key , value ) ) <EOL> def _declare_function ( self , tp , quals , decl ) : <EOL> tp = self . _get_type_pointer ( tp , quals ) <EOL> if self . _options . get ( '<STR_LIT>' ) : <EOL> tag = '<STR_LIT>' <EOL> elif self . _inside_extern_python : <EOL> tag = '<STR_LIT>' <EOL> else : <EOL> tag = '<STR_LIT>' <EOL> self . _declare ( tag + decl . name , tp ) <EOL> def _parse_decl ( self , decl ) : <EOL> node = decl . type <EOL> if isinstance ( node , pycparser . c_ast . FuncDecl ) : <EOL> tp , quals = self . _get_type_and_quals ( node , name = decl . name ) <EOL> assert isinstance ( tp , model . RawFunctionType ) <EOL> self . _declare_function ( tp , quals , decl ) <EOL> else : <EOL> if isinstance ( node , pycparser . c_ast . Struct ) : <EOL> self . _get_struct_union_enum_type ( '<STR_LIT>' , node ) <EOL> elif isinstance ( node , pycparser . c_ast . Union ) : <EOL> self . _get_struct_union_enum_type ( '<STR_LIT>' , node ) <EOL> elif isinstance ( node , pycparser . c_ast . Enum ) : <EOL> self . _get_struct_union_enum_type ( '<STR_LIT>' , node ) <EOL> elif not decl . name : <EOL> raise api . CDefError ( "<STR_LIT>" , <EOL> decl ) <EOL> if decl . name : <EOL> tp , quals = self . _get_type_and_quals ( node , <EOL> partial_length_ok = True ) <EOL> if tp . is_raw_function : <EOL> self . _declare_function ( tp , quals , decl ) <EOL> elif ( tp . is_integer_type ( ) and <EOL> hasattr ( decl , '<STR_LIT>' ) and <EOL> hasattr ( decl . init , '<STR_LIT:value>' ) and <EOL> _r_int_literal . match ( decl . init . value ) ) : <EOL> self . _add_integer_constant ( decl . name , decl . init . value ) <EOL> elif ( tp . is_integer_type ( ) and <EOL> isinstance ( decl . init , pycparser . c_ast . UnaryOp ) and <EOL> decl . init . op == '<STR_LIT:->' and <EOL> hasattr ( decl . init . expr , '<STR_LIT:value>' ) and <EOL> _r_int_literal . match ( decl . init . expr . value ) ) : <EOL> self . _add_integer_constant ( decl . name , <EOL> '<STR_LIT:->' + decl . init . expr . value ) <EOL> elif ( tp is model . void_type and <EOL> decl . name . startswith ( '<STR_LIT>' ) ) : <EOL> self . _inside_extern_python = not self . _inside_extern_python <EOL> assert self . _inside_extern_python == ( <EOL> decl . name == '<STR_LIT>' ) <EOL> else : <EOL> if self . _inside_extern_python : <EOL> raise api . CDefError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if ( quals & model . Q_CONST ) and not tp . is_array_type : <EOL> self . _declare ( '<STR_LIT>' + decl . name , tp , quals = quals ) <EOL> else : <EOL> self . _declare ( '<STR_LIT>' + decl . name , tp , quals = quals ) <EOL> def parse_type ( self , cdecl ) : <EOL> return self . parse_type_and_quals ( cdecl ) [ <NUM_LIT:0> ] <EOL> def parse_type_and_quals ( self , cdecl ) : <EOL> ast , macros = self . _parse ( '<STR_LIT>' % cdecl ) [ : <NUM_LIT:2> ] <EOL> assert not macros <EOL> exprnode = ast . ext [ - <NUM_LIT:1> ] . type . args . params [ <NUM_LIT:0> ] <EOL> if isinstance ( exprnode , pycparser . c_ast . ID ) : <EOL> raise api . CDefError ( "<STR_LIT>" % ( exprnode . name , ) ) <EOL> return self . _get_type_and_quals ( exprnode . type ) <EOL> def _declare ( self , name , obj , included = False , quals = <NUM_LIT:0> ) : <EOL> if name in self . _declarations : <EOL> prevobj , prevquals = self . _declarations [ name ] <EOL> if prevobj is obj and prevquals == quals : <EOL> return <EOL> if not self . _options . get ( '<STR_LIT>' ) : <EOL> raise api . FFIError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ( name , ) ) <EOL> assert '<STR_LIT>' not in name . split ( ) <EOL> self . _declarations [ name ] = ( obj , quals ) <EOL> if included : <EOL> self . _included_declarations . add ( obj ) <EOL> def _extract_quals ( self , type ) : <EOL> quals = <NUM_LIT:0> <EOL> if isinstance ( type , ( pycparser . c_ast . TypeDecl , <EOL> pycparser . c_ast . PtrDecl ) ) : <EOL> if '<STR_LIT>' in type . quals : <EOL> quals |= model . Q_CONST <EOL> if '<STR_LIT>' in type . quals : <EOL> quals |= model . Q_VOLATILE <EOL> if '<STR_LIT>' in type . quals : <EOL> quals |= model . Q_RESTRICT <EOL> return quals <EOL> def _get_type_pointer ( self , type , quals , declname = None ) : <EOL> if isinstance ( type , model . RawFunctionType ) : <EOL> return type . as_function_pointer ( ) <EOL> if ( isinstance ( type , model . StructOrUnionOrEnum ) and <EOL> type . name . startswith ( '<STR_LIT:$>' ) and type . name [ <NUM_LIT:1> : ] . isdigit ( ) and <EOL> type . forcename is None and declname is not None ) : <EOL> return model . NamedPointerType ( type , declname , quals ) <EOL> return model . PointerType ( type , quals ) <EOL> def _get_type_and_quals ( self , typenode , name = None , partial_length_ok = False ) : <EOL> if ( isinstance ( typenode , pycparser . c_ast . TypeDecl ) and <EOL> isinstance ( typenode . type , pycparser . c_ast . IdentifierType ) and <EOL> len ( typenode . type . names ) == <NUM_LIT:1> and <EOL> ( '<STR_LIT>' + typenode . type . names [ <NUM_LIT:0> ] ) in self . _declarations ) : <EOL> tp , quals = self . _declarations [ '<STR_LIT>' + typenode . type . names [ <NUM_LIT:0> ] ] <EOL> quals |= self . _extract_quals ( typenode ) <EOL> return tp , quals <EOL> if isinstance ( typenode , pycparser . c_ast . ArrayDecl ) : <EOL> if typenode . dim is None : <EOL> length = None <EOL> else : <EOL> length = self . _parse_constant ( <EOL> typenode . dim , partial_length_ok = partial_length_ok ) <EOL> tp , quals = self . _get_type_and_quals ( typenode . type , <EOL> partial_length_ok = partial_length_ok ) <EOL> return model . ArrayType ( tp , length ) , quals <EOL> if isinstance ( typenode , pycparser . c_ast . PtrDecl ) : <EOL> itemtype , itemquals = self . _get_type_and_quals ( typenode . type ) <EOL> tp = self . _get_type_pointer ( itemtype , itemquals , declname = name ) <EOL> quals = self . _extract_quals ( typenode ) <EOL> return tp , quals <EOL> if isinstance ( typenode , pycparser . c_ast . TypeDecl ) : <EOL> quals = self . _extract_quals ( typenode ) <EOL> type = typenode . type <EOL> if isinstance ( type , pycparser . c_ast . IdentifierType ) : <EOL> names = list ( type . names ) <EOL> if names != [ '<STR_LIT>' , '<STR_LIT>' ] : <EOL> prefixes = { } <EOL> while names : <EOL> name = names [ <NUM_LIT:0> ] <EOL> if name in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> prefixes [ name ] = prefixes . get ( name , <NUM_LIT:0> ) + <NUM_LIT:1> <EOL> del names [ <NUM_LIT:0> ] <EOL> else : <EOL> break <EOL> newnames = [ ] <EOL> for prefix in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> for i in range ( prefixes . get ( prefix , <NUM_LIT:0> ) ) : <EOL> newnames . append ( prefix ) <EOL> if not names : <EOL> names = [ '<STR_LIT:int>' ] <EOL> if names == [ '<STR_LIT:int>' ] : <EOL> if '<STR_LIT>' in prefixes or '<STR_LIT>' in prefixes : <EOL> names = [ ] <EOL> names = newnames + names <EOL> ident = '<STR_LIT:U+0020>' . join ( names ) <EOL> if ident == '<STR_LIT>' : <EOL> return model . void_type , quals <EOL> if ident == '<STR_LIT>' : <EOL> raise api . FFIError ( '<STR_LIT>' % <EOL> typenode . coord . line ) <EOL> tp0 , quals0 = resolve_common_type ( self , ident ) <EOL> return tp0 , ( quals | quals0 ) <EOL> if isinstance ( type , pycparser . c_ast . Struct ) : <EOL> tp = self . _get_struct_union_enum_type ( '<STR_LIT>' , type , name ) <EOL> return tp , quals <EOL> if isinstance ( type , pycparser . c_ast . Union ) : <EOL> tp = self . _get_struct_union_enum_type ( '<STR_LIT>' , type , name ) <EOL> return tp , quals <EOL> if isinstance ( type , pycparser . c_ast . Enum ) : <EOL> tp = self . _get_struct_union_enum_type ( '<STR_LIT>' , type , name ) <EOL> return tp , quals <EOL> if isinstance ( typenode , pycparser . c_ast . FuncDecl ) : <EOL> return self . _parse_function_type ( typenode , name ) , <NUM_LIT:0> <EOL> if isinstance ( typenode , pycparser . c_ast . Struct ) : <EOL> return self . _get_struct_union_enum_type ( '<STR_LIT>' , typenode , name , <EOL> nested = True ) , <NUM_LIT:0> <EOL> if isinstance ( typenode , pycparser . c_ast . Union ) : <EOL> return self . _get_struct_union_enum_type ( '<STR_LIT>' , typenode , name , <EOL> nested = True ) , <NUM_LIT:0> <EOL> raise api . FFIError ( "<STR_LIT>" % <EOL> typenode . coord . line ) <EOL> def _parse_function_type ( self , typenode , funcname = None ) : <EOL> params = list ( getattr ( typenode . args , '<STR_LIT>' , [ ] ) ) <EOL> for i , arg in enumerate ( params ) : <EOL> if not hasattr ( arg , '<STR_LIT:type>' ) : <EOL> raise api . CDefError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> % ( funcname or '<STR_LIT>' , i + <NUM_LIT:1> , <EOL> getattr ( arg , '<STR_LIT:name>' , '<STR_LIT:?>' ) ) ) <EOL> ellipsis = ( <EOL> len ( params ) > <NUM_LIT:0> and <EOL> isinstance ( params [ - <NUM_LIT:1> ] . type , pycparser . c_ast . TypeDecl ) and <EOL> isinstance ( params [ - <NUM_LIT:1> ] . type . type , <EOL> pycparser . c_ast . IdentifierType ) and <EOL> params [ - <NUM_LIT:1> ] . type . type . names == [ '<STR_LIT>' ] ) <EOL> if ellipsis : <EOL> params . pop ( ) <EOL> if not params : <EOL> raise api . CDefError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ( funcname or '<STR_LIT>' ) ) <EOL> args = [ self . _as_func_arg ( * self . _get_type_and_quals ( argdeclnode . type ) ) <EOL> for argdeclnode in params ] <EOL> if not ellipsis and args == [ model . void_type ] : <EOL> args = [ ] <EOL> result , quals = self . _get_type_and_quals ( typenode . type ) <EOL> abi = None <EOL> if hasattr ( typenode . type , '<STR_LIT>' ) : <EOL> if typenode . type . quals [ - <NUM_LIT:3> : ] == [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] : <EOL> abi = '<STR_LIT>' <EOL> return model . RawFunctionType ( tuple ( args ) , result , ellipsis , abi ) <EOL> def _as_func_arg ( self , type , quals ) : <EOL> if isinstance ( type , model . ArrayType ) : <EOL> return model . PointerType ( type . item , quals ) <EOL> elif isinstance ( type , model . RawFunctionType ) : <EOL> return type . as_function_pointer ( ) <EOL> else : <EOL> return type <EOL> def _get_struct_union_enum_type ( self , kind , type , name = None , nested = False ) : <EOL> try : <EOL> return self . _structnode2type [ type ] <EOL> except KeyError : <EOL> pass <EOL> force_name = name <EOL> name = type . name <EOL> if name is None : <EOL> if force_name is not None : <EOL> explicit_name = '<STR_LIT>' % force_name <EOL> else : <EOL> self . _anonymous_counter += <NUM_LIT:1> <EOL> explicit_name = '<STR_LIT>' % self . _anonymous_counter <EOL> tp = None <EOL> else : <EOL> explicit_name = name <EOL> key = '<STR_LIT>' % ( kind , name ) <EOL> tp , _ = self . _declarations . get ( key , ( None , None ) ) <EOL> if tp is None : <EOL> if kind == '<STR_LIT>' : <EOL> tp = model . StructType ( explicit_name , None , None , None ) <EOL> elif kind == '<STR_LIT>' : <EOL> tp = model . UnionType ( explicit_name , None , None , None ) <EOL> elif kind == '<STR_LIT>' : <EOL> if explicit_name == '<STR_LIT>' : <EOL> raise CDefError ( "<STR_LIT>" ) <EOL> tp = self . _build_enum_type ( explicit_name , type . values ) <EOL> else : <EOL> raise AssertionError ( "<STR_LIT>" % ( kind , ) ) <EOL> if name is not None : <EOL> self . _declare ( key , tp ) <EOL> else : <EOL> if kind == '<STR_LIT>' and type . values is not None : <EOL> raise NotImplementedError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % explicit_name ) <EOL> if not tp . forcename : <EOL> tp . force_the_name ( force_name ) <EOL> if tp . forcename and '<STR_LIT:$>' in tp . name : <EOL> self . _declare ( '<STR_LIT>' % tp . forcename , tp ) <EOL> self . _structnode2type [ type ] = tp <EOL> if kind == '<STR_LIT>' : <EOL> return tp <EOL> if type . decls is None : <EOL> return tp <EOL> if tp . fldnames is not None : <EOL> raise api . CDefError ( "<STR_LIT>" % name ) <EOL> fldnames = [ ] <EOL> fldtypes = [ ] <EOL> fldbitsize = [ ] <EOL> fldquals = [ ] <EOL> for decl in type . decls : <EOL> if ( isinstance ( decl . type , pycparser . c_ast . IdentifierType ) and <EOL> '<STR_LIT>' . join ( decl . type . names ) == '<STR_LIT>' ) : <EOL> self . _make_partial ( tp , nested ) <EOL> continue <EOL> if decl . bitsize is None : <EOL> bitsize = - <NUM_LIT:1> <EOL> else : <EOL> bitsize = self . _parse_constant ( decl . bitsize ) <EOL> self . _partial_length = False <EOL> type , fqual = self . _get_type_and_quals ( decl . type , <EOL> partial_length_ok = True ) <EOL> if self . _partial_length : <EOL> self . _make_partial ( tp , nested ) <EOL> if isinstance ( type , model . StructType ) and type . partial : <EOL> self . _make_partial ( tp , nested ) <EOL> fldnames . append ( decl . name or '<STR_LIT>' ) <EOL> fldtypes . append ( type ) <EOL> fldbitsize . append ( bitsize ) <EOL> fldquals . append ( fqual ) <EOL> tp . fldnames = tuple ( fldnames ) <EOL> tp . fldtypes = tuple ( fldtypes ) <EOL> tp . fldbitsize = tuple ( fldbitsize ) <EOL> tp . fldquals = tuple ( fldquals ) <EOL> if fldbitsize != [ - <NUM_LIT:1> ] * len ( fldbitsize ) : <EOL> if isinstance ( tp , model . StructType ) and tp . partial : <EOL> raise NotImplementedError ( "<STR_LIT>" <EOL> % ( tp , ) ) <EOL> tp . packed = self . _options . get ( '<STR_LIT>' ) <EOL> if tp . completed : <EOL> tp . completed = <NUM_LIT:0> <EOL> self . _recomplete . append ( tp ) <EOL> return tp <EOL> def _make_partial ( self , tp , nested ) : <EOL> if not isinstance ( tp , model . StructOrUnion ) : <EOL> raise api . CDefError ( "<STR_LIT>" % ( tp , ) ) <EOL> if not tp . has_c_name ( ) and not nested : <EOL> raise NotImplementedError ( "<STR_LIT>" % ( tp , ) ) <EOL> tp . partial = True <EOL> def _parse_constant ( self , exprnode , partial_length_ok = False ) : <EOL> if isinstance ( exprnode , pycparser . c_ast . Constant ) : <EOL> s = exprnode . value <EOL> if s . startswith ( '<STR_LIT:0>' ) : <EOL> if s . startswith ( '<STR_LIT>' ) or s . startswith ( '<STR_LIT>' ) : <EOL> return int ( s , <NUM_LIT:16> ) <EOL> return int ( s , <NUM_LIT:8> ) <EOL> elif '<STR_LIT:1>' <= s [ <NUM_LIT:0> ] <= '<STR_LIT>' : <EOL> return int ( s , <NUM_LIT:10> ) <EOL> elif s [ <NUM_LIT:0> ] == "<STR_LIT:'>" and s [ - <NUM_LIT:1> ] == "<STR_LIT:'>" and ( <EOL> len ( s ) == <NUM_LIT:3> or ( len ( s ) == <NUM_LIT:4> and s [ <NUM_LIT:1> ] == "<STR_LIT:\\>" ) ) : <EOL> return ord ( s [ - <NUM_LIT:2> ] ) <EOL> else : <EOL> raise api . CDefError ( "<STR_LIT>" % ( s , ) ) <EOL> if ( isinstance ( exprnode , pycparser . c_ast . UnaryOp ) and <EOL> exprnode . op == '<STR_LIT:+>' ) : <EOL> return self . _parse_constant ( exprnode . expr ) <EOL> if ( isinstance ( exprnode , pycparser . c_ast . UnaryOp ) and <EOL> exprnode . op == '<STR_LIT:->' ) : <EOL> return - self . _parse_constant ( exprnode . expr ) <EOL> if ( isinstance ( exprnode , pycparser . c_ast . ID ) and <EOL> exprnode . name in self . _int_constants ) : <EOL> return self . _int_constants [ exprnode . name ] <EOL> if partial_length_ok : <EOL> if ( isinstance ( exprnode , pycparser . c_ast . ID ) and <EOL> exprnode . name == '<STR_LIT>' ) : <EOL> self . _partial_length = True <EOL> return '<STR_LIT>' <EOL> raise api . FFIError ( "<STR_LIT>" <EOL> "<STR_LIT>" % exprnode . coord . line ) <EOL> def _build_enum_type ( self , explicit_name , decls ) : <EOL> if decls is not None : <EOL> partial = False <EOL> enumerators = [ ] <EOL> enumvalues = [ ] <EOL> nextenumvalue = <NUM_LIT:0> <EOL> for enum in decls . enumerators : <EOL> if _r_enum_dotdotdot . match ( enum . name ) : <EOL> partial = True <EOL> continue <EOL> if enum . value is not None : <EOL> nextenumvalue = self . _parse_constant ( enum . value ) <EOL> enumerators . append ( enum . name ) <EOL> enumvalues . append ( nextenumvalue ) <EOL> self . _add_constants ( enum . name , nextenumvalue ) <EOL> nextenumvalue += <NUM_LIT:1> <EOL> enumerators = tuple ( enumerators ) <EOL> enumvalues = tuple ( enumvalues ) <EOL> tp = model . EnumType ( explicit_name , enumerators , enumvalues ) <EOL> tp . partial = partial <EOL> else : <EOL> tp = model . EnumType ( explicit_name , ( ) , ( ) ) <EOL> return tp <EOL> def include ( self , other ) : <EOL> for name , ( tp , quals ) in other . _declarations . items ( ) : <EOL> if name . startswith ( '<STR_LIT>' ) : <EOL> continue <EOL> kind = name . split ( '<STR_LIT:U+0020>' , <NUM_LIT:1> ) [ <NUM_LIT:0> ] <EOL> if kind in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> self . _declare ( name , tp , included = True , quals = quals ) <EOL> for k , v in other . _int_constants . items ( ) : <EOL> self . _add_constants ( k , v ) <EOL> def _get_unknown_type ( self , decl ) : <EOL> typenames = decl . type . type . names <EOL> assert typenames [ - <NUM_LIT:1> ] == '<STR_LIT>' <EOL> if len ( typenames ) == <NUM_LIT:1> : <EOL> return model . unknown_type ( decl . name ) <EOL> if ( typenames [ : - <NUM_LIT:1> ] == [ '<STR_LIT:float>' ] or <EOL> typenames [ : - <NUM_LIT:1> ] == [ '<STR_LIT>' ] ) : <EOL> result = model . UnknownFloatType ( decl . name ) <EOL> else : <EOL> for t in typenames [ : - <NUM_LIT:1> ] : <EOL> if t not in [ '<STR_LIT:int>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' ] : <EOL> raise api . FFIError ( '<STR_LIT>' % <EOL> decl . coord . line ) <EOL> result = model . UnknownIntegerType ( decl . name ) <EOL> if self . _uses_new_feature is None : <EOL> self . _uses_new_feature = "<STR_LIT>" % ( <EOL> '<STR_LIT:U+0020>' . join ( typenames [ : - <NUM_LIT:1> ] ) , decl . name ) <EOL> return result </s>
