code: def _parse(self, csource):
      csource, macros = _preprocess(csource)
      # XXX: for more efficiency we would need to poke into the
      # internals of CParser...  the following registers the
      # typedefs, because their presence or absence influences the
      # parsing itself (but what they are typedef'ed to plays no role)
      ctn = _common_type_names(csource)
      typenames = []
      for name in sorted(self._declarations):
          if name.startswith("typedef "):
              name = name[8:]
              typenames.append(name)
              ctn.discard(name)
      typenames += sorted(ctn)
      #
      csourcelines = []
      csourcelines.append('# 1 "<cdef automatic initialization code>"')
      for typename in typenames:
          csourcelines.append("typedef int %s;" % typename)
      csourcelines.append(
          "typedef int __dotdotdotint__, __dotdotdotfloat__,"
          " __dotdotdot__;"
      )
      # this forces pycparser to consider the following in the file
      # called <cdef source string> from line 1
      csourcelines.append('# 1 "%s"' % (CDEF_SOURCE_STRING,))
      csourcelines.append(csource)
      fullcsource = "\n".join(csourcelines)
      if lock is not None:
          lock.acquire()  # pycparser is not thread-safe...
      try:
          ast = _get_parser().parse(fullcsource)
      except pycparser.c_parser.ParseError as e:
          self.convert_pycparser_error(e, csource)
      finally:
          if lock is not None:
              lock.release()
      # csource will be used to find buggy source text
      return ast, macros, csource
  
imports: from .None import model
  from .commontypes import COMMON_TYPES, resolve_common_type
  from .error import FFIError, CDefError
  import weakref, re, sys
label_desc: Use image node_id 2 for calling the Parser obj's underlying member method code with example usage: obj._parse(csource) and returns: ast,  macros,  csource