From: <bi...@us...> - 2007-04-14 16:22:38
|
Revision: 280 http://svn.sourceforge.net/oorexx/?rev=280&view=rev Author: bigrixx Date: 2007-04-14 09:22:38 -0700 (Sat, 14 Apr 2007) Log Message: ----------- [ 1700617 ] Change supplier~index for multidimension arrays [ 1700532 ] StemClass.hpp needs an #include of SupplierClass [ 1698603 ] Add hasItem and Index methods to other collections. array class only. [ 1700606 ] Control stack full error from array makestring. Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp interpreter-3.x/trunk/kernel/classes/ArrayClass.hpp interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp interpreter-3.x/trunk/kernel/classes/StemClass.hpp interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp 2007-04-14 06:11:38 UTC (rev 279) +++ interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp 2007-04-14 16:22:38 UTC (rev 280) @@ -36,7 +36,7 @@ /* */ /*----------------------------------------------------------------------------*/ /******************************************************************************/ -/* REXX Kernel ArrayClass.c */ +/* REXX Kernel ArrayClass.c */ /* */ /* Primitive Array Class */ /* */ @@ -478,7 +478,7 @@ if (fMultiDim) { /* add the index location */ - indexes->put((RexxObject*) indexToStringRep(i, buffer, multiIndex), count); + indexes->put((RexxObject*) indexToArray(i), count); } else { /* add the index location */ indexes->put((RexxObject*) new_integer(i), count); @@ -496,45 +496,7 @@ return (RexxObject *)new_supplier(values, indexes); } -RexxString* RexxArray::indexToStringRep(size_t idx, char *buffer, size_t *indices) -/******************************************************************************/ -/* Function: Create human-readable representation for multi-dimensional index*/ -/******************************************************************************/ -{ - char *tmp = buffer; - size_t dims; - size_t dimension; - size_t digit; - size_t i; - /* create the string representation of the multidimensional array. as the */ - /* single indices can only be determined with the last first, they are */ - /* stored in the indices array first and then made human-readable. */ - /* this method gets the char buffer passed in so it does not have to alloc*/ - /* memory on each call. the allocation is done in RexxArray::supplier in- */ - /* stead. the same is true for the indices array. */ - idx--; - dims = this->dimensions->size(); - for (i = dims; i != 0; i--) { - dimension = ((RexxInteger *)this->dimensions->get(i))->value; - digit = idx % dimension; /* calculate current index */ - indices[dims-i] = digit+1; /* set digit in indices array */ - idx = (idx - digit) / dimension; /* remove numberspace for this index */ - } - - tmp[0] = 0x00; /* create string representation */ - for (i = dims; i > 0; i--) { - if (i == dims) { - sprintf(tmp,"%d",indices[i-1]); - } else { - sprintf(tmp,",%d",indices[i-1]); - } - tmp = tmp + strlen(tmp); - } - - return new_cstring(buffer); /* create RexxString for char buffer */ -} - void RexxArray::setExpansion(RexxObject * expansion) /******************************************************************************/ /* Function: Set a new expansion array item */ @@ -1111,7 +1073,8 @@ return newArray; } - +// Temporary bypass for BUG #1700606 +#if 0 RexxString *RexxArray::primitiveMakeString() /******************************************************************************/ /* Function: Handle a REQUEST('STRING') request for a REXX string object */ @@ -1119,9 +1082,14 @@ { return this->makeString((RexxString *)OREF_NULL); /* forward to the real makestring method */ } +#endif +RexxString *RexxArray::makeString(RexxString *format) +{ + return toString(format); +} -RexxString *RexxArray::makeString(RexxString *format) +RexxString *RexxArray::toString(RexxString *format) /******************************************************************************/ /* Function: Make a string out of an array */ /******************************************************************************/ @@ -1187,7 +1155,11 @@ { mutbuffer->append((RexxObject *) line_end_string); } - mutbuffer->append(item); + RexxObject *stringValue = item->requiredString(); + if (stringValue != TheNilObject) + { + mutbuffer->append(stringValue); + } first = false; } } @@ -1393,6 +1365,121 @@ return this; /* All done, return array */ } + +/** + * Find the index of a single item in the array. + * + * @param item The item to locate. + * + * @return The numeric index of the item. + */ +arraysize_t RexxArray::findSingleIndexItem(RexxObject *item) +{ + for (arraysize_t i = 0; i < this->arraySize; i++) + { + // if there's an object in the slot, compare it. + if (objects[i] != OREF_NULL) + { + // if the items are equal, return the index + if (item->equalValue(objects[i])) + { + return i + 1; + } + } + } + return 0; +} + + +/** + * Convert a multi-dimensional array index into an array + * of index values for the flattened dimension. + * + * @param idx The index to covert. + * + * @return An array of the individual index items. + */ +RexxObject* RexxArray::indexToArray(size_t idx) +{ + // work with an origin-origin zero version of the index, which is easier + // do work with. + idx--; + // get the number of dimensions specified. + size_t dims = this->dimensions->size(); + // get an array we fill in as we go + RexxArray *index = new_array(dims); + + for (size_t i = dims; i > 0; i--) + { + // get the next dimension size + size_t dimension = ((RexxInteger *)this->dimensions->get(i))->value; + // now get the remainder. This tells us the position within this + // dimension of the array. Make an integer object and store in the + // array. + size_t digit = idx % dimension; + // the digit is origin-zero, but the Rexx index is origin-one. + index->put(new_integer(digit + 1), i); + // now strip out that portion of the index. + idx = (idx - digit) / dimension; + } + // return the array object + discard_hold(index); + return index; +} + + +/** + * Return the index for the first occurrence of the target in + * the array. + * + * @param target The target object. + * + * @return The index for the array. For a multi-dimensional array, this + * returns an array of indices. + */ +RexxObject *RexxArray::index(RexxObject *target) +{ + // we require the index to be there. + required_arg(target, ONE); + // see if we have this item. If not, then + // we return .nil. + arraysize_t index = findSingleIndexItem(target); + + if (index == 0) + { + return TheNilObject; + } + // single dimensional arrays are easy, we return + if (this->dimensions == OREF_NULL || this->dimensions->size() == 1) + { + return new_integer(index); + } + else + { + // convert this into an array of integers + return indexToArray(index); + } +} + + +/** + * Test if an item is within the array. + * + * @param target The target test item. + * + * @return .true if this item exists in the array. .false if it does not + * exist. + */ +RexxObject *RexxArray::hasItem(RexxObject *target) +{ + // this is pretty simple. One argument, required, and just search to see + // if we have it. + required_arg(target, ONE); + return findSingleIndexItem(target) == 0 ? TheFalseObject : TheTrueObject; +} + + + void copyElements( COPYELEMENTPARM *parm, size_t newDimension) Modified: interpreter-3.x/trunk/kernel/classes/ArrayClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ArrayClass.hpp 2007-04-14 06:11:38 UTC (rev 279) +++ interpreter-3.x/trunk/kernel/classes/ArrayClass.hpp 2007-04-14 16:22:38 UTC (rev 280) @@ -93,8 +93,12 @@ RexxArray *makeArray(); RexxArray *allItems(); RexxArray *allIndexes(); + RexxString *toString(RexxString *); RexxString *makeString(RexxString *); +// Temporary bypass for BUG #1700606 +#if 0 RexxString *primitiveMakeString(); +#endif RexxObject *getRexx(RexxObject **, size_t); void put(RexxObject * eref, size_t pos); RexxObject *putRexx(RexxObject **, size_t); @@ -134,6 +138,8 @@ RexxObject *of(RexxObject **, size_t); RexxObject *empty(); RexxObject *isEmpty(); + RexxObject *index(RexxObject *); + RexxObject *hasItem(RexxObject *); inline void addLast(RexxObject *item) { this->insertItem(item, this->size() + 1); } inline void addFirst(RexxObject *item) { this->insertItem(item, 1); } @@ -143,7 +149,8 @@ inline RexxObject **data() { return this->expansionArray->objects; } inline RexxObject **data(size_t pos) { return &((this->data())[pos-1]);} inline RexxArray *getExpansion() { return this->expansionArray; } - inline RexxString *indexToStringRep(size_t, char*, size_t*); // def. 1048 + arraysize_t findSingleIndexItem(RexxObject *item); + RexxObject* indexToArray(size_t idx); size_t arraySize; /* current size of array */ size_t maximumSize; /* Maximum size array can grow */ Modified: interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-04-14 06:11:38 UTC (rev 279) +++ interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-04-14 16:22:38 UTC (rev 280) @@ -1072,6 +1072,28 @@ return string_value; /* return the converted form */ } +/** + * Handle a string request for a required string value where + * the caller wishes to handle the error itself. + * + * @return The object's string value, or OREF_NULL if this is not a + * string. + */ +RexxString *RexxObject::requiredString() +{ + // primitive object? We have a bypass for this + if (isPrimitive(this)) + { + return this->makeString(); + } + else + { + // we have to use REQUEST to get this + return (RexxString *)this->sendMessage(OREF_REQUEST, OREF_STRINGSYM); + } +} + + RexxInteger *RexxObject::requestInteger( size_t precision ) /* precision to use */ /******************************************************************************/ Modified: interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp 2007-04-14 06:11:38 UTC (rev 279) +++ interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp 2007-04-14 16:22:38 UTC (rev 280) @@ -215,6 +215,7 @@ LONG requestLong(size_t); RexxArray *requestArray(); RexxString *requiredString(LONG); + RexxString *requiredString(); RexxInteger *requiredInteger(LONG, size_t); LONG requiredLong(LONG, size_t precision = DEFAULT_DIGITS); LONG requiredPositive(LONG, size_t precision = DEFAULT_DIGITS); @@ -292,6 +293,13 @@ RexxObject *SOMObjRexx(); RexxObject *serverRexx(); BOOL callSecurityManager(RexxString *, RexxDirectory *); + // compare 2 values for equality, potentially falling back on the + // "==" method for the test. + bool inline equalValue(RexxObject *other) + { + // test first for direct equality, followed by value equality. + return (this == other) || this->isEqual(other); + } // Define operator methods here. Modified: interpreter-3.x/trunk/kernel/classes/StemClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StemClass.hpp 2007-04-14 06:11:38 UTC (rev 279) +++ interpreter-3.x/trunk/kernel/classes/StemClass.hpp 2007-04-14 16:22:38 UTC (rev 280) @@ -55,6 +55,8 @@ #define SORT_ASCENDING 0 #define SORT_DECENDING 1 +class RexxSupplier; + class RexxStem : public RexxObject { public: void *operator new (size_t); Modified: interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-04-14 06:11:38 UTC (rev 279) +++ interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-04-14 16:22:38 UTC (rev 280) @@ -350,6 +350,7 @@ CHARCONSTANT(TABLE, "TABLE"); CHARCONSTANT(TARGET, "TARGET"); CHARCONSTANT(TOKENIZE_ONLY, "//T"); +CHARCONSTANT(TOSTRING, "TOSTRING"); CHARCONSTANT(TRACEBACK, "TRACEBACK"); CHARCONSTANT(TRANSLATE, "TRANSLATE"); CHARCONSTANT(TRUE, "TRUE"); Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-04-14 06:11:38 UTC (rev 279) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-04-14 16:22:38 UTC (rev 280) @@ -161,6 +161,9 @@ CPPMA(RexxArray::allItems), CPPMA(RexxArray::empty), CPPMA(RexxArray::isEmpty), +CPPMA(RexxArray::index), +CPPMA(RexxArray::hasItem), +CPPMA(RexxArray::toString), CPPMC1(RexxArray::newRexx), CPPMA(RexxArray::makeString), @@ -860,10 +863,13 @@ defineKernelMethod(CHAR_PREVIOUS ,TheArrayBehaviour, CPPMA(RexxArray::previousRexx), 1); defineKernelMethod(CHAR_APPEND ,TheArrayBehaviour, CPPMA(RexxArray::append), 1); defineKernelMethod(CHAR_MAKESTRING ,TheArrayBehaviour, CPPMA(RexxArray::makeString), 1); + defineKernelMethod(CHAR_TOSTRING ,TheArrayBehaviour, CPPMA(RexxArray::toString), 1); defineKernelMethod(CHAR_ALLINDEXES ,TheArrayBehaviour, CPPMA(RexxArray::allIndexes), 0); defineKernelMethod(CHAR_ALLITEMS ,TheArrayBehaviour, CPPMA(RexxArray::allItems), 0); defineKernelMethod(CHAR_EMPTY ,TheArrayBehaviour, CPPMA(RexxArray::empty), 0); defineKernelMethod(CHAR_ISEMPTY ,TheArrayBehaviour, CPPMA(RexxArray::isEmpty), 0); + defineKernelMethod(CHAR_INDEX ,TheArrayBehaviour, CPPMA(RexxArray::index), 1); + defineKernelMethod(CHAR_HASITEM ,TheArrayBehaviour, CPPMA(RexxArray::hasItem), 1); /* set the scope of the methods to */ /* this classes oref */ TheArrayBehaviour->setMethodDictionaryScope(TheArrayClass); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |