/**
 * Process UNKNOWN messages for a string hash collection object,
 * forwarding them to the string value.  We need this and
 * processUnknown because the collections are documented as
 * having an UNKNKOWN method.
 *
 * @param message   The message target.
 * @param arguments The message arguments.
 *
 * @return The message result.
 */
RexxObject *StemClass::unknownRexx(RexxString *message, ArrayClass *arguments)
{
    message = stringArgument(message, ARG_ONE);
    arguments = arrayArgument(arguments, ARG_TWO);

    ProtectedObject result;
    return value->sendMessage(message, arguments, result);
}
/**
 * Create a method from an external library source.
 *
 * @param name   The method name.
 *
 * @return The resolved method object, or OREF_NULL if unable to
 *         load the routine.
 */
MethodClass *MethodClass::loadExternalMethod(RexxString *name, RexxString *descriptor)
{
    name = stringArgument(name, "name");
    descriptor = stringArgument(descriptor, "descriptor");
    // convert external into words
    ArrayClass *_words = StringUtil::words(descriptor->getStringData(), descriptor->getLength());
    ProtectedObject p(_words);
    // "LIBRARY libbar [foo]"
    if (_words->size() > 0 && ((RexxString *)(_words->get(1)))->strCompare("LIBRARY"))
    {
        RexxString *library = OREF_NULL;
        // the default entry point name is the internal name
        RexxString *entry = name;

        // full library with entry name version?
        if (_words->size() == 3)
        {
            library = (RexxString *)_words->get(2);
            entry = (RexxString *)_words->get(3);
        }
        else if (_words->size() == 2)
        {
            library = (RexxString *)_words->get(2);
        }
        else  // wrong number of tokens
        {
            reportException(Error_Translation_bad_external, descriptor);
        }
        // get the native code for this library
        NativeCode *nmethod = PackageManager::loadMethod(library, entry);
        // raise an exception if this entry point is not found.
        if (nmethod == OREF_NULL)
        {
            return (MethodClass *)TheNilObject;
        }
        // turn into a real method object
        return new MethodClass(name, nmethod);
    }
    else
    {
        // unknown external type
        reportException(Error_Translation_bad_external, descriptor);
    }
    return OREF_NULL;
}
Beispiel #3
0
RexxMethod *RexxBehaviour::methodObject(
    RexxString *messageName )          /* name of method to retrieve        */
/******************************************************************************/
/* Function:  Retrieve a method associated with the given name                */
/******************************************************************************/
{
    /* force to a string version (upper  */
    /* case required)                    */
    messageName = stringArgument(messageName, OREF_positional, ARG_ONE)->upper();
    /* now just do a method lookup       */
    return this->methodLookup(messageName);
}
/**
 * Create a method object from a file.
 *
 * @param filename The target file name.
 *
 * @return The created method object.
 */
MethodClass *MethodClass::newFileRexx(RexxString *filename)
{
    // this class is defined on the object class, but this is actually attached
    // to a class object instance.  Therefore, any use of the this pointer
    // will be touching the wrong data.  Use the classThis pointer for calling
    // any methods on this object from this method.
    RexxClass *classThis = (RexxClass *)this;
    // get the method name as a string
    filename = stringArgument(filename, ARG_ONE);

    Protected<MethodClass> newMethod = LanguageParser::createMethod(filename);

    newMethod->setScope((RexxClass *)TheNilObject);
    classThis->completeNewObject(newMethod);
    return newMethod;
}
/**
 * Set a method of executable code into a directory object.
 *
 * @param entryname The name this is set under
 * @param methodobj The associated method object.
 *
 * @return Nothing.
 */
RexxInternalObject *DirectoryClass::setMethodRexx(RexxString *entryname, MethodClass *methodobj)
{
    entryname = stringArgument(entryname, "index")->upper();
    if (methodobj != OREF_NULL)
    {
        // make sure we have a method object for this.  The scope is .nil to indicate object scope.
        methodobj = MethodClass::newMethodObject(entryname, methodobj, (RexxClass *)TheNilObject, "method");

        // the unknown method?  We keep that in a special place
        if (entryname->strCompare(GlobalNames::UNKNOWN))
        {
            setField(unknownMethod, methodobj);
        }
        else
        {
            // create the table if this is the first addition
            if (methodTable == OREF_NULL)
            {
                setField(methodTable, new_string_table());
            }
            // and add the method to the table
            methodTable->put(methodobj, entryname);
        }
    }
    // no method object given, this is a removal
    else
    {
        // if unknown, remove this from the special place.
        if (entryname->strCompare(GlobalNames::UNKNOWN))
        {
            clearField(unknownMethod);
        }
        else
        {
            // remove from the method table if we have one
            if (methodTable != OREF_NULL)
            {
                methodTable->remove(entryname);
            }
        }
    }

    // since setting a method will also override any contents, we need to
    // ensure the contents don't have this either.
    contents->remove(entryname);
    return OREF_NULL;
}
/**
 * unset a method of executable code into a directory object.
 *
 * @param entryname The name this is set under
 *
 * @return Nothing.
 */
RexxInternalObject *DirectoryClass::unsetMethodRexx(RexxString *entryname)
{
    // the entry name is always upper case
    entryname = stringArgument(entryname, "index")->upper();

    // if unknown, remove this from the special place.
    if (entryname->strCompare(GlobalNames::UNKNOWN))
    {
        clearField(unknownMethod);
    }
    else
    {
        // remove from the method table if we have one
        if (methodTable != OREF_NULL)
        {
            methodTable->remove(entryname);
        }
    }

    return OREF_NULL;
}
/**
 * Forward all request requests to the target value.  We
 * handle some of these directly, the rest are passed on
 * to the default value.
 *
 * @param makeclass The name of the class for the request.
 *
 * @return The appropriate result for the request.
 */
RexxObject *StemClass::request(RexxString *makeclass)
{
    ProtectedObject result;
    makeclass = stringArgument(makeclass, ARG_ONE)->upper();
    // take care of any ARRAY requests, the rest go to the default value
    if (makeclass->strCompare("ARRAY"))
    {
        // if we have a real stem object (not a subclass), handle directly,
        // otherwise send to the subclass.
        if (isStem(this))
        {
            return makeArray();
        }
        else
        {
            sendMessage(GlobalNames::MAKEARRAY, result);
            return result;
        }
    }
    // let the default value handle everything else
    value->sendMessage(GlobalNames::REQUEST, makeclass, result);
    return result;
}
Beispiel #8
0
bool SystemInterpreter::valueFunction(
    RexxString *Name,                  /* variable name                     */
    RexxObject *NewValue,              /* new assigned value                */
    RexxString *Selector,              /* variable selector                 */
    RexxObject *&result)
{
  const char * OldValue;               /* old environment value             */

  Selector = Selector->upper();        /* upper case the selector           */
                                       /* Linux environment variables can   */
                                       /* be lowercased                     */
                                       /* and the name too                  */
  if (!Selector->strCompare(SELECTOR)) /* correct selector?                 */
  {
      return false;                    // we can't handle this one
  }
                                       /* scan for the variable             */
  OldValue = getenv(Name->getStringData());
  if (OldValue != NULL)                /* have a value already?   */
    result = new_string(OldValue);    /* Yes -  convert to Rexx string     */
  else
    result = OREF_NULLSTRING;          /* otherwise, return null            */

  if (NewValue != OREF_NULL)           /* if there's a new value, set it    */
  {
    if(NewValue == (RexxString *) TheNilObject)
    {
      SetEnvironmentVariable(Name, (RexxString *) TheNilObject);
    }
    else
    {
    SetEnvironmentVariable(Name, stringArgument(NewValue, ARG_TWO));
    }
  }
  return true;
}
 void stringArgument( const QString & string, bool multiline, const QString & fixme ) { FOREACH stringArgument( string, multiline, fixme ); }