parameters: (self, tokens, expanded=None)
return_statement: return tokens
docstring: Given a list of tokens, this function performs macro expansion.
          The expanded argument is a dictionary that contains macros already
          expanded.  This is used to prevent infinite recursion.
docstring_summary: Given a list of tokens, this function performs macro expansion.
          The expanded argument is a dictionary that contains macros already
          expanded.  This is used to prevent infinite recursion.
docstring_tokens: Given a list of tokens this function performs macro expansion . The expanded argument is a dictionary that contains macros already expanded . This is used to prevent infinite recursion .
function: def _expand_macros(self, tokens, expanded=None):
          """Given a list of tokens, this function performs macro expansion.
          The expanded argument is a dictionary that contains macros already
          expanded.  This is used to prevent infinite recursion.
  
          """
          if expanded is None:
              expanded = {}
          i = 0
          while i < len(tokens):
              t = tokens[i]
              if t.type == self.t_ID:
                  if t.value in self.macros and t.value not in expanded:
                      # Yes, we found a macro match
                      expanded[t.value] = True
  
                      m = self.macros[t.value]
                      if not m.arglist:
                          # A simple macro
                          ex = self._expand_macros([copy.copy(_x) for _x in m.value], expanded)
                          for e in ex:
                              e.lineno = t.lineno
                          tokens[i:i+1] = ex
                          i += len(ex)
                      else:
                          # A macro with arguments
                          j = i + 1
                          while j < len(tokens) and tokens[j].type in self.t_WS:
                              j += 1
                          if tokens[j].value == '(':
                              tokcount,args,positions = self._collect_args(tokens[j:])
                              if not m.variadic and len(args) !=  len(m.arglist):
                                  self._error(t.lineno, "Macro {} requires {} arguments".format(t.value, len(m.arglist)))
                                  i = j + tokcount
                              elif m.variadic and len(args) < len(m.arglist)-1:
                                  if len(m.arglist) > 2:
                                      self._error(t.lineno, "Macro {} must have at least {} arguments".format(t.value, len(m.arglist)-1))
                                  else:
                                      self._error(t.lineno, "Macro {} must have at least {} argument".format(t.value, len(m.arglist)-1))
                                  i = j + tokcount
                              else:
                                  if m.variadic:
                                      if len(args) == len(m.arglist)-1:
                                          args.append([])
                                      else:
                                          args[len(m.arglist)-1] = tokens[j+positions[len(m.arglist)-1]:j+tokcount-1]
                                          del args[len(m.arglist):]
  
                                  # Get macro replacement text
                                  rep = self._macro_expand_args(m, args)
                                  rep = self._expand_macros(rep, expanded)
                                  for r in rep:
                                      r.lineno = t.lineno
                                  tokens[i:j+tokcount] = rep
                                  i += len(rep)
                      del expanded[t.value]
                      continue
                  elif t.value == '__LINE__':
                      t.type = self.t_INTEGER
                      t.value = self.t_INTEGER_TYPE(t.lineno)
  
              i += 1
          return tokens
function_tokens: def _expand_macros ( self , tokens , expanded = None ) : if expanded is None : expanded = { } i = 0 while i < len ( tokens ) : t = tokens [ i ] if t . type == self . t_ID : if t . value in self . macros and t . value not in expanded : # Yes, we found a macro match expanded [ t . value ] = True m = self . macros [ t . value ] if not m . arglist : # A simple macro ex = self . _expand_macros ( [ copy . copy ( _x ) for _x in m . value ] , expanded ) for e in ex : e . lineno = t . lineno tokens [ i : i + 1 ] = ex i += len ( ex ) else : # A macro with arguments j = i + 1 while j < len ( tokens ) and tokens [ j ] . type in self . t_WS : j += 1 if tokens [ j ] . value == '(' : tokcount , args , positions = self . _collect_args ( tokens [ j : ] ) if not m . variadic and len ( args ) != len ( m . arglist ) : self . _error ( t . lineno , "Macro {} requires {} arguments" . format ( t . value , len ( m . arglist ) ) ) i = j + tokcount elif m . variadic and len ( args ) < len ( m . arglist ) - 1 : if len ( m . arglist ) > 2 : self . _error ( t . lineno , "Macro {} must have at least {} arguments" . format ( t . value , len ( m . arglist ) - 1 ) ) else : self . _error ( t . lineno , "Macro {} must have at least {} argument" . format ( t . value , len ( m . arglist ) - 1 ) ) i = j + tokcount else : if m . variadic : if len ( args ) == len ( m . arglist ) - 1 : args . append ( [ ] ) else : args [ len ( m . arglist ) - 1 ] = tokens [ j + positions [ len ( m . arglist ) - 1 ] : j + tokcount - 1 ] del args [ len ( m . arglist ) : ] # Get macro replacement text rep = self . _macro_expand_args ( m , args ) rep = self . _expand_macros ( rep , expanded ) for r in rep : r . lineno = t . lineno tokens [ i : j + tokcount ] = rep i += len ( rep ) del expanded [ t . value ] continue elif t . value == '__LINE__' : t . type = self . t_INTEGER t . value = self . t_INTEGER_TYPE ( t . lineno ) i += 1 return tokens