Esempio n. 1
0
 def pyname(self):
    "Returns a Pythonized name for this mapping"
    if self._pyname:
       return self._pyname
    return util.pyname(self.name)
Esempio n. 2
0
   def pycall(self, pars=(), keys=()):
      """
      Returns a string containing the Python statement or expression code for a
      call to the subroutine.

      pars is a sequence of strings, each of which is the Pythonized value of a
      parameter argument to the subroutine.  keys is a sequence of sequences,
      each of which contains two strings.  The strings are the Pythonized
      name and value of a keyword argument to the subroutine.
      """

      # Make copies of the parameter and keyword lists
      pars = tuple(pars)
      keys = tuple(keys)

      # Verify number of parameters
      npars = len(pars)
      nrequired = self.npars - self.noptional
      if npars > self.npars:
         raise Error(("subroutine '%s' takes at most %d parameters " +
	              "(called with %d)") % (self.name, self.npars, npars))
      if npars < nrequired:
         raise Error(("subroutine '%s' requires at least %d " +
	              "parameters (called with %d)") %
		     (self.name, nrequired, npars))

      #
      # Handle the parameter arguments
      #

      # Required input parameters
      input = ([ pars[i] for i in range(min(nrequired, npars))
                 if i+1 in self.inpars ])

      # Optional input parameters
      if npars > nrequired:
         for i in range(nrequired, npars):
	    if i+1 in self.inpars:
	       # Real optional input parameter
	       input.append(pars[i])
	    elif i+1 in self.outpars:
	       # Flag to indicate that an optional output parameter should be
	       # returned
	       input.append('True')

      # Output parameters
      output = [ pars[i] for i in range(npars) if i+1 in self.outpars ]

      #
      # Handle the keyword arguments
      #

      for (name, value) in keys:
	 uc_name = name.upper()

	 # Try to find a match for the keyword.  This is complicated by the
	 # fact that, in IDL, keyword names can be abbreviated as long as they
	 # can still be uniquely identified.
         matches = [ k for k in self.allkeys if k.startswith(uc_name) ]
	 if len(matches) == 0:
	    # No matches; throw an error
	    raise Error("'%s' is not a valid keyword for subroutine '%s'" %
	                (name, self.name))
	 elif len(matches) == 1:
	    # Only one match; good
	    uc_name = matches[0]
	 elif uc_name not in matches:
	    # Multiple matches; unless one of the matches is exactly what we
	    # want (i.e. the keyword is a prefix of one or more others), throw
	    # an error
	    raise Error(("identifier '%s' matches multiple keywords " +
	                 "for subroutine '%s': %s") %
			(name, self.name, matches))

	 # Pythonize the full name
         name = util.pyname(uc_name)

	 if uc_name in self.inkeys:
	    # Input keyword
	    input.append('%s=%s' % (name, value))
	 if uc_name in self.outkeys:
	    # Output keyword
	    if uc_name not in self.inkeys:
	       # If the keyword is output only, we need to flag that the value
	       # should be returned
	       input.append('%s=True' % name)
	    output.append(value)

      # Add any needed extra code
      add_extra_code(self.extracode)

      # If there's a custom callfunc, use it to generate the call code
      if self.callfunc:
         return self.callfunc(input, output)

      # Build the input and output strings
      input  = ', '.join(input)
      if output:
         output = ', '.join(output) + ' = '
      else:
         output = ''

      # Return the call code
      return '%s%s(%s)' % (output, self.pyname(), input)