/** * 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; }
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; }
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 ); }