code: def macro_expand_args(self, macro, args):
      # Make a copy of the macro token sequence
      rep = [copy.copy(_x) for _x in macro.value]
  
      # Make string expansion patches.  These do not alter the length of the replacement sequence
  
      str_expansion = {}
      for argnum, i in macro.str_patch:
          if argnum not in str_expansion:
              str_expansion[argnum] = (
                  '"%s"' % "".join([x.value for x in args[argnum]])
              ).replace("\\", "\\\\")
          rep[i] = copy.copy(rep[i])
          rep[i].value = str_expansion[argnum]
  
      # Make the variadic macro comma patch.  If the variadic macro argument is empty, we get rid
      comma_patch = False
      if macro.variadic and not args[-1]:
          for i in macro.var_comma_patch:
              rep[i] = None
              comma_patch = True
  
      # Make all other patches.   The order of these matters.  It is assumed that the patch list
      # has been sorted in reverse order of patch location since replacements will cause the
      # size of the replacement sequence to expand from the patch point.
  
      expanded = {}
      for ptype, argnum, i in macro.patch:
          # Concatenation.   Argument is left unexpanded
          if ptype == "c":
              rep[i : i + 1] = args[argnum]
          # Normal expansion.  Argument is macro expanded first
          elif ptype == "e":
              if argnum not in expanded:
                  expanded[argnum] = self.expand_macros(args[argnum])
              rep[i : i + 1] = expanded[argnum]
  
      # Get rid of removed comma if necessary
      if comma_patch:
          rep = [_i for _i in rep if _i]
  
      return rep
  
imports: from __future__ import generators
  import sys
  import re
  import copy
  import time
  import os.path
label_desc: Use image node_id 10 for calling the Preprocessor obj's underlying member method code with example usage: obj.macro_expand_args(macro, args) and returns: rep